net: dsa: mv88e6xxx: factorize PHY access with PPU
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Mon, 9 May 2016 17:22:39 +0000 (13:22 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 May 2016 18:26:08 +0000 (14:26 -0400)
Add a MV88E6XXX_FLAG_PPU flag to describe switch models with a PHY
Polling Unit. This allows to merge PPU specific PHY access code in the
share code.

Make the mv88e6xxx_ppu_disable and mv88e6xxx_phy_{read,write}_ppu
functions use unlocked register accesses in order to call them in
mv88e6xxx_phy_{read,write} in a locked context.

Since the PPU code is shared, also remove NET_DSA_MV88E6XXX_NEED_PPU.

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

index 90ba003d8fdf307784a35ee76dc61fda55dc8cf6..4aaadced6b81f1659db1f1578690a79518adde83 100644 (file)
@@ -13,15 +13,10 @@ config NET_DSA_MV88E6060
          This enables support for the Marvell 88E6060 ethernet switch
          chip.
 
-config NET_DSA_MV88E6XXX_NEED_PPU
-       bool
-       default n
-
 config NET_DSA_MV88E6131
        tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
        depends on NET_DSA
        select NET_DSA_MV88E6XXX
-       select NET_DSA_MV88E6XXX_NEED_PPU
        select NET_DSA_TAG_DSA
        ---help---
          This enables support for the Marvell 88E6085/6095/6095F/6131
index d4773204935bfe7a9b6689bfe48a79644df66123..9d21d69de08a1c025ade0700dd71f30ab2b4c3b9 100644 (file)
@@ -132,8 +132,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
        if (ret < 0)
                return ret;
 
-       mv88e6xxx_ppu_state_init(ps);
-
        ret = mv88e6xxx_switch_reset(ps, false);
        if (ret < 0)
                return ret;
@@ -145,46 +143,13 @@ static int mv88e6131_setup(struct dsa_switch *ds)
        return mv88e6xxx_setup_ports(ds);
 }
 
-static int mv88e6131_port_to_phy_addr(struct dsa_switch *ds, int port)
-{
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
-       if (port >= 0 && port < ps->info->num_ports)
-               return port;
-
-       return -EINVAL;
-}
-
-static int
-mv88e6131_phy_read(struct dsa_switch *ds, int port, int regnum)
-{
-       int addr = mv88e6131_port_to_phy_addr(ds, port);
-
-       if (addr < 0)
-               return addr;
-
-       return mv88e6xxx_phy_read_ppu(ds, addr, regnum);
-}
-
-static int
-mv88e6131_phy_write(struct dsa_switch *ds,
-                             int port, int regnum, u16 val)
-{
-       int addr = mv88e6131_port_to_phy_addr(ds, port);
-
-       if (addr < 0)
-               return addr;
-
-       return mv88e6xxx_phy_write_ppu(ds, addr, regnum, val);
-}
-
 struct dsa_switch_driver mv88e6131_switch_driver = {
        .tag_protocol           = DSA_TAG_PROTO_DSA,
        .probe                  = mv88e6131_drv_probe,
        .setup                  = mv88e6131_setup,
        .set_addr               = mv88e6xxx_set_addr_direct,
-       .phy_read               = mv88e6131_phy_read,
-       .phy_write              = mv88e6131_phy_write,
+       .phy_read               = mv88e6xxx_phy_read,
+       .phy_write              = mv88e6xxx_phy_write,
        .get_strings            = mv88e6xxx_get_strings,
        .get_ethtool_stats      = mv88e6xxx_get_ethtool_stats,
        .get_sset_count         = mv88e6xxx_get_sset_count,
index 470cfc783baaf1e5006ffaf14f4e1f17dd9b2052..a28b46c33e130eb590e106d80813a9c27e2e25cc 100644 (file)
@@ -241,24 +241,23 @@ static int _mv88e6xxx_phy_write(struct mv88e6xxx_priv_state *ps, int addr,
        return 0;
 }
 
-#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
 static int mv88e6xxx_ppu_disable(struct mv88e6xxx_priv_state *ps)
 {
        int ret;
        unsigned long timeout;
 
-       ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL);
+       ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL);
        if (ret < 0)
                return ret;
 
-       ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
-                                 ret & ~GLOBAL_CONTROL_PPU_ENABLE);
+       ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
+                                  ret & ~GLOBAL_CONTROL_PPU_ENABLE);
        if (ret)
                return ret;
 
        timeout = jiffies + 1 * HZ;
        while (time_before(jiffies, timeout)) {
-               ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS);
+               ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS);
                if (ret < 0)
                        return ret;
 
@@ -361,35 +360,33 @@ void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps)
        ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
 }
 
-int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
+static int mv88e6xxx_phy_read_ppu(struct mv88e6xxx_priv_state *ps, int addr,
+                                 int regnum)
 {
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
        int ret;
 
        ret = mv88e6xxx_ppu_access_get(ps);
        if (ret >= 0) {
-               ret = mv88e6xxx_reg_read(ps, addr, regnum);
+               ret = _mv88e6xxx_reg_read(ps, addr, regnum);
                mv88e6xxx_ppu_access_put(ps);
        }
 
        return ret;
 }
 
-int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
-                           int regnum, u16 val)
+static int mv88e6xxx_phy_write_ppu(struct mv88e6xxx_priv_state *ps, int addr,
+                                  int regnum, u16 val)
 {
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
        int ret;
 
        ret = mv88e6xxx_ppu_access_get(ps);
        if (ret >= 0) {
-               ret = mv88e6xxx_reg_write(ps, addr, regnum, val);
+               ret = _mv88e6xxx_reg_write(ps, addr, regnum, val);
                mv88e6xxx_ppu_access_put(ps);
        }
 
        return ret;
 }
-#endif
 
 static bool mv88e6xxx_6065_family(struct mv88e6xxx_priv_state *ps)
 {
@@ -2599,6 +2596,9 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
 
        INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
 
+       if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
+               mv88e6xxx_ppu_state_init(ps);
+
        return 0;
 }
 
@@ -2884,7 +2884,12 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
                return 0xffff;
 
        mutex_lock(&ps->smi_mutex);
-       ret = _mv88e6xxx_phy_read(ps, addr, regnum);
+
+       if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
+               ret = mv88e6xxx_phy_read_ppu(ps, addr, regnum);
+       else
+               ret = _mv88e6xxx_phy_read(ps, addr, regnum);
+
        mutex_unlock(&ps->smi_mutex);
        return ret;
 }
@@ -2900,7 +2905,12 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
                return 0xffff;
 
        mutex_lock(&ps->smi_mutex);
-       ret = _mv88e6xxx_phy_write(ps, addr, regnum, val);
+
+       if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
+               ret = mv88e6xxx_phy_write_ppu(ps, addr, regnum, val);
+       else
+               ret = _mv88e6xxx_phy_write(ps, addr, regnum, val);
+
        mutex_unlock(&ps->smi_mutex);
        return ret;
 }
index c67b72af9af1456d816e16edf1b602032586e8cf..52ca24efec64b235aa40ba23019b6319c9ad2df7 100644 (file)
@@ -350,13 +350,26 @@ enum mv88e6xxx_family {
        MV88E6XXX_FAMILY_6352,  /* 6172 6176 6240 6352 */
 };
 
-#define MV88E6XXX_FLAGS_FAMILY_6095    0
+enum mv88e6xxx_cap {
+       /* PHY Polling Unit.
+        * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
+        */
+       MV88E6XXX_CAP_PPU,
+};
+
+/* Bitmask of capabilities */
+#define MV88E6XXX_FLAG_PPU             BIT(MV88E6XXX_CAP_PPU)
 
-#define MV88E6XXX_FLAGS_FAMILY_6097    0
+#define MV88E6XXX_FLAGS_FAMILY_6095    \
+       MV88E6XXX_FLAG_PPU
+
+#define MV88E6XXX_FLAGS_FAMILY_6097    \
+       MV88E6XXX_FLAG_PPU
 
 #define MV88E6XXX_FLAGS_FAMILY_6165    0
 
-#define MV88E6XXX_FLAGS_FAMILY_6185    0
+#define MV88E6XXX_FLAGS_FAMILY_6185    \
+       MV88E6XXX_FLAG_PPU
 
 #define MV88E6XXX_FLAGS_FAMILY_6320    0
 
@@ -418,7 +431,6 @@ struct mv88e6xxx_priv_state {
        struct mii_bus *bus;
        int sw_addr;
 
-#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
        /* Handles automatic disabling and re-enabling of the PHY
         * polling unit.
         */
@@ -426,7 +438,6 @@ struct mv88e6xxx_priv_state {
        int                     ppu_disabled;
        struct work_struct      ppu_work;
        struct timer_list       ppu_timer;
-#endif
 
        /* This mutex serialises access to the statistics unit.
         * Hold this mutex over snapshot + dump sequences.
@@ -489,10 +500,6 @@ int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
 int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum);
 int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
                                 u16 val);
-void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps);
-int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum);
-int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
-                           int regnum, u16 val);
 void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
 void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
                                 uint64_t *data);