OSDN Git Service

net: dsa: mv88e6xxx: add a cascade port op
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Wed, 9 May 2018 15:38:49 +0000 (11:38 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 10 May 2018 20:12:31 +0000 (16:12 -0400)
Only the 88E6185 family has bits 15:12 Cascade Port bits in the Global
Control 2 register. Hence inconsistent values are actually written in
this register for other families.

Add a .set_cascade_port operation to isolate the 88E6185 case, and call
it from the device mapping setup function.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/chip.h
drivers/net/dsa/mv88e6xxx/global1.c
drivers/net/dsa/mv88e6xxx/global1.h

index e7e079b..9b61d5b 100644 (file)
@@ -1046,6 +1046,13 @@ static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
                        return err;
        }
 
+       if (chip->info->ops->set_cascade_port) {
+               port = MV88E6XXX_CASCADE_PORT_MULTIPLE;
+               err = chip->info->ops->set_cascade_port(chip, port);
+               if (err)
+                       return err;
+       }
+
        return 0;
 }
 
@@ -2158,7 +2165,6 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
 
        /* Disable remote management, and set the switch's DSA device number. */
        err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2,
-                                MV88E6XXX_G1_CTL2_MULTIPLE_CASCADE |
                                 (ds->index & 0x1f));
        if (err)
                return err;
@@ -2643,6 +2649,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
        .watchdog_ops = &mv88e6097_watchdog_ops,
        .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
        .ppu_enable = mv88e6185_g1_ppu_enable,
+       .set_cascade_port = mv88e6185_g1_set_cascade_port,
        .ppu_disable = mv88e6185_g1_ppu_disable,
        .reset = mv88e6185_g1_reset,
        .vtu_getnext = mv88e6185_g1_vtu_getnext,
@@ -2911,6 +2918,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
        .set_egress_port = mv88e6095_g1_set_egress_port,
        .watchdog_ops = &mv88e6097_watchdog_ops,
        .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
+       .set_cascade_port = mv88e6185_g1_set_cascade_port,
        .ppu_enable = mv88e6185_g1_ppu_enable,
        .ppu_disable = mv88e6185_g1_ppu_disable,
        .reset = mv88e6185_g1_reset,
index 4163c80..62234c2 100644 (file)
@@ -401,6 +401,12 @@ struct mv88e6xxx_ops {
                               uint64_t *data);
        int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
        int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
+
+#define MV88E6XXX_CASCADE_PORT_NONE            0xe
+#define MV88E6XXX_CASCADE_PORT_MULTIPLE                0xf
+
+       int (*set_cascade_port)(struct mv88e6xxx_chip *chip, int port);
+
        const struct mv88e6xxx_irq_ops *watchdog_ops;
 
        int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
index b43bd64..6eb4eca 100644 (file)
@@ -350,6 +350,29 @@ int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
 
 /* Offset 0x1c: Global Control 2 */
 
+static int mv88e6xxx_g1_ctl2_mask(struct mv88e6xxx_chip *chip, u16 mask,
+                                 u16 val)
+{
+       u16 reg;
+       int err;
+
+       err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL2, &reg);
+       if (err)
+               return err;
+
+       reg &= ~mask;
+       reg |= val & mask;
+
+       return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2, reg);
+}
+
+int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port)
+{
+       const u16 mask = MV88E6185_G1_CTL2_CASCADE_PORT_MASK;
+
+       return mv88e6xxx_g1_ctl2_mask(chip, mask, port << __bf_shf(mask));
+}
+
 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
 {
        u16 val;
index 6aee731..bcbb804 100644 (file)
 
 /* Offset 0x1C: Global Control 2 */
 #define MV88E6XXX_G1_CTL2                      0x1c
-#define MV88E6XXX_G1_CTL2_NO_CASCADE           0xe000
-#define MV88E6XXX_G1_CTL2_MULTIPLE_CASCADE     0xf000
 #define MV88E6XXX_G1_CTL2_HIST_RX              0x0040
 #define MV88E6XXX_G1_CTL2_HIST_TX              0x0080
 #define MV88E6XXX_G1_CTL2_HIST_RX_TX           0x00c0
+#define MV88E6185_G1_CTL2_CASCADE_PORT_MASK    0xf000
+#define MV88E6185_G1_CTL2_CASCADE_PORT_NONE    0xe000
+#define MV88E6185_G1_CTL2_CASCADE_PORT_MULTI   0xf000
 
 /* Offset 0x1D: Stats Operation Register */
 #define MV88E6XXX_G1_STATS_OP                  0x1d
@@ -253,6 +254,8 @@ int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
 int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
 int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
 
+int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port);
+
 int mv88e6xxx_g1_atu_set_learn2all(struct mv88e6xxx_chip *chip, bool learn2all);
 int mv88e6xxx_g1_atu_set_age_time(struct mv88e6xxx_chip *chip,
                                  unsigned int msecs);