The port_set_speed method for the Topaz family must not be the same
as for Peridot family, since on Topaz port 5 is the SERDES port and it
can be set to 2500mbps speed mode.

This patch adds a new method for the Topaz family, allowing the alt_bit
mode only for port 0 and the 2500 mbps mode for port 5.

Signed-off-by: Marek Behún <marek.be...@nic.cz>
---
 drivers/net/dsa/mv88e6xxx/chip.c |  4 ++--
 drivers/net/dsa/mv88e6xxx/port.c | 25 +++++++++++++++++++++++--
 drivers/net/dsa/mv88e6xxx/port.h |  1 +
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 78ce820b5257..e05d4eddc935 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2907,7 +2907,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,
@@ -3528,7 +3528,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,
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 92945841c8e8..cd7db60a508b 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -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)
 {
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index f32f56af8e35..36904c9bf955 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -269,6 +269,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);
-- 
2.16.4

Reply via email to