From f7a48b68abd9b20ce1ac6298aaaa3c4d158271dd Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 19 Dec 2019 11:48:22 +0200 Subject: net: dsa: mv88e6xxx: force cmode write on 6141/6341 mv88e6xxx_port_set_cmode() relies on cmode stored in struct mv88e6xxx_port to skip cmode update when the requested value matches the cached value. It turns out that mv88e6xxx_port_hidden_write() might change the port cmode setting as a side effect, so we can't rely on the cached value to determine that cmode update in not necessary. Force cmode update in mv88e6341_port_set_cmode(), to make serdes configuration work again. Other mv88e6xxx_port_set_cmode() callers keep the current behaviour. This fixes serdes configuration of the 6141 switch on SolidRun Clearfog GT-8K. Fixes: 7a3007d22e8 ("net: dsa: mv88e6xxx: fully support SERDES on Topaz family") Reported-by: Denis Odintsov Signed-off-by: Baruch Siach Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/port.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net/dsa') diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index 7fe256c5739d..0b43c650e100 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -393,7 +393,7 @@ phy_interface_t mv88e6390x_port_max_speed_mode(int port) } static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, - phy_interface_t mode) + phy_interface_t mode, bool force) { u8 lane; u16 cmode; @@ -427,8 +427,8 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, cmode = 0; } - /* cmode doesn't change, nothing to do for us */ - if (cmode == chip->ports[port].cmode) + /* cmode doesn't change, nothing to do for us unless forced */ + if (cmode == chip->ports[port].cmode && !force) return 0; lane = mv88e6xxx_serdes_get_lane(chip, port); @@ -484,7 +484,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, if (port != 9 && port != 10) return -EOPNOTSUPP; - return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, false); } int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, @@ -504,7 +504,7 @@ int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, break; } - return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, false); } static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip, @@ -555,7 +555,7 @@ int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port, if (err) return err; - return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, true); } int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) -- cgit v1.2.3 From d8dc2c9676e614ef62f54a155b50076888c8a29a Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 4 Jan 2020 23:14:51 +0100 Subject: net: dsa: mv88e6xxx: Preserve priority when setting CPU port. The 6390 family uses an extended register to set the port connected to the CPU. The lower 5 bits indicate the port, the upper three bits are the priority of the frames as they pass through the switch, what egress queue they should use, etc. Since frames being set to the CPU are typically management frames, BPDU, IGMP, ARP, etc set the priority to 7, the reset default, and the highest. Fixes: 33641994a676 ("net: dsa: mv88e6xxx: Monitor and Management tables") Signed-off-by: Andrew Lunn Tested-by: Chris Healy Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/global1.c | 5 +++++ drivers/net/dsa/mv88e6xxx/global1.h | 1 + 2 files changed, 6 insertions(+) (limited to 'drivers/net/dsa') diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c index 120a65d3e3ef..b016cc205f81 100644 --- a/drivers/net/dsa/mv88e6xxx/global1.c +++ b/drivers/net/dsa/mv88e6xxx/global1.c @@ -360,6 +360,11 @@ int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port) { u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST; + /* Use the default high priority for management frames sent to + * the CPU. + */ + port |= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI; + return mv88e6390_g1_monitor_write(chip, ptr, port); } diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h index bc5a6b2bb1e4..5324c6f4ae90 100644 --- a/drivers/net/dsa/mv88e6xxx/global1.h +++ b/drivers/net/dsa/mv88e6xxx/global1.h @@ -211,6 +211,7 @@ #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST 0x2000 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST 0x2100 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST 0x3000 +#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI 0x00e0 #define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK 0x00ff /* Offset 0x1C: Global Control 2 */ -- cgit v1.2.3