OSDN Git Service

net: dsa: mv88e6xxx: use 4-bit port for PVT data
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Thu, 30 Mar 2017 21:37:08 +0000 (17:37 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sat, 1 Apr 2017 19:22:57 +0000 (12:22 -0700)
The Cross-chip Port Based VLAN Table (PVT) supports two indexing modes,
one using 5-bit for device and 4-bit for port, the other using 4-bit for
device and 5-bit for port, configured via the Global 2 Misc register.

Only 4 bits for the source port are needed when interconnecting 88E6xxx
switch devices since they all support less than 16 physical ports. The
full 5 bits are needed when interconnecting a device with 98DXxxx switch
devices since they support more than 16 physical ports.

Add a mv88e6xxx_pvt_setup helper to set the 4-bit port PVT mode, which
will be extended later to also initialize the PVT content.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/global2.c
drivers/net/dsa/mv88e6xxx/global2.h
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h

index 8f1f881..2a32bb4 100644 (file)
@@ -1198,6 +1198,17 @@ static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip)
        return mv88e6xxx_g1_atu_set_age_time(chip, 300000);
 }
 
+static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip)
+{
+       if (!mv88e6xxx_has_pvt(chip))
+               return 0;
+
+       /* Clear 5 Bit Port for usage with Marvell Link Street devices:
+        * use 4 bits for the Src_Port/Src_Trunk and 5 bits for the Src_Dev.
+        */
+       return mv88e6xxx_g2_misc_4_bit_port(chip);
+}
+
 static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
 {
        struct mv88e6xxx_chip *chip = ds->priv;
@@ -2594,6 +2605,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
                        goto unlock;
        }
 
+       err = mv88e6xxx_pvt_setup(chip);
+       if (err)
+               goto unlock;
+
        err = mv88e6xxx_atu_setup(chip);
        if (err)
                goto unlock;
index 6228aab..d64f4c1 100644 (file)
@@ -784,6 +784,31 @@ static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
        return err;
 }
 
+/* Offset 0x1D: Misc Register */
+
+static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
+                                       bool port_5_bit)
+{
+       u16 val;
+       int err;
+
+       err = mv88e6xxx_g2_read(chip, GLOBAL2_MISC, &val);
+       if (err)
+               return err;
+
+       if (port_5_bit)
+               val |= GLOBAL2_MISC_5_BIT_PORT;
+       else
+               val &= ~GLOBAL2_MISC_5_BIT_PORT;
+
+       return mv88e6xxx_g2_write(chip, GLOBAL2_MISC, val);
+}
+
+int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
+{
+       return mv88e6xxx_g2_misc_5_bit_port(chip, false);
+}
+
 static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
 {
        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
index f8b6dd9..71fb2ff 100644 (file)
@@ -42,6 +42,8 @@ int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
 int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
                              struct ethtool_eeprom *eeprom, u8 *data);
 
+int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip);
+
 int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip);
 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip);
 void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip);
@@ -110,6 +112,11 @@ static inline int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
        return -EOPNOTSUPP;
 }
 
+int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
 {
        return -EOPNOTSUPP;
index 97dd3e2..bcaa55b 100644 (file)
 #define GLOBAL2_WDOG_FORCE_IRQ                 BIT(0)
 #define GLOBAL2_QOS_WEIGHT     0x1c
 #define GLOBAL2_MISC           0x1d
+#define GLOBAL2_MISC_5_BIT_PORT        BIT(14)
 
 #define MV88E6XXX_N_FID                4096