]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: dsa: mv88e6xxx: Fix 88E6141/6341 2500mbps SERDES speed
authorMarek Behún <marek.behun@nic.cz>
Sat, 13 Oct 2018 12:40:31 +0000 (14:40 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 Dec 2019 08:16:33 +0000 (09:16 +0100)
[ Upstream commit 26422340da467538cd65eaa9c65538039ee99c8c ]

This is a fix for the port_set_speed method for the Topaz family.
Currently the same method is used as for the Peridot family, but
this is wrong for the SERDES port.

On Topaz, the SERDES port is port 5, not 9 and 10 as in Peridot.
Moreover setting alt_bit on Topaz only makes sense for port 0 (for
(differentiating 100mbps vs 200mbps). The SERDES port does not
support more than 2500mbps, so alt_bit does not make any difference.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/port.c
drivers/net/dsa/mv88e6xxx/port.h

index d075f0f7a3de84666c1d69476a84af9a1d47e7a5..411ae9961bf4fc3d094173303d39ae237434fd42 100644 (file)
@@ -3028,7 +3028,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
        .port_set_link = mv88e6xxx_port_set_link,
        .port_set_duplex = mv88e6xxx_port_set_duplex,
        .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
-       .port_set_speed = mv88e6390_port_set_speed,
+       .port_set_speed = mv88e6341_port_set_speed,
        .port_tag_remap = mv88e6095_port_tag_remap,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -3649,7 +3649,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
        .port_set_link = mv88e6xxx_port_set_link,
        .port_set_duplex = mv88e6xxx_port_set_duplex,
        .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
-       .port_set_speed = mv88e6390_port_set_speed,
+       .port_set_speed = mv88e6341_port_set_speed,
        .port_tag_remap = mv88e6095_port_tag_remap,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
index fdeddbfa829da009ef00807236561ce9f5f73df6..2f16a310c110eb3682edd2e8a2410b1facea77a6 100644 (file)
@@ -228,8 +228,11 @@ static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
                ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
                break;
        case 2500:
-               ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
-                       MV88E6390_PORT_MAC_CTL_ALTSPEED;
+               if (alt_bit)
+                       ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
+                               MV88E6390_PORT_MAC_CTL_ALTSPEED;
+               else
+                       ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
                break;
        case 10000:
                /* all bits set, fall through... */
@@ -291,6 +294,24 @@ int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
        return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
 }
 
+/* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
+int mv88e6341_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
+{
+       if (speed == SPEED_MAX)
+               speed = port < 5 ? 1000 : 2500;
+
+       if (speed > 2500)
+               return -EOPNOTSUPP;
+
+       if (speed == 200 && port != 0)
+               return -EOPNOTSUPP;
+
+       if (speed == 2500 && port < 5)
+               return -EOPNOTSUPP;
+
+       return mv88e6xxx_port_set_speed(chip, port, speed, !port, true);
+}
+
 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
 {
index 95b59f5eb39310aa6742ee8db5afd4c75857d2ea..cbb64a7683e287d724203cda74a186297e85d6b3 100644 (file)
@@ -280,6 +280,7 @@ int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup);
 
 int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
 int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
+int mv88e6341_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);