net: dsa: mv88e6xxx: factorize PHY indirect access
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Mon, 9 May 2016 17:22:40 +0000 (13:22 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 May 2016 18:26:08 +0000 (14:26 -0400)
Some switch has dedicated SMI PHY Command and Data registers, used to
indirectly access the PHYs, instead of direct access.

Identify these switch models and make mv88e6xxx_phy_{read,write} generic
enough to support every models.

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

index e64cbeed2cdf5449334d8ef698a1ba6d67d83639..b190647d2a15d7682e25c5b52f9ba3b765749361 100644 (file)
@@ -124,8 +124,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
        .probe                  = mv88e6171_drv_probe,
        .setup                  = mv88e6171_setup,
        .set_addr               = mv88e6xxx_set_addr_indirect,
-       .phy_read               = mv88e6xxx_phy_read_indirect,
-       .phy_write              = mv88e6xxx_phy_write_indirect,
+       .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 c61f0f4da6f4444fd4d188038ff416730dbd749a..6fa7c02f9027cc74c120b20e9c06492a17a86873 100644 (file)
@@ -344,8 +344,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
        .probe                  = mv88e6352_drv_probe,
        .setup                  = mv88e6352_setup,
        .set_addr               = mv88e6xxx_set_addr_indirect,
-       .phy_read               = mv88e6xxx_phy_read_indirect,
-       .phy_write              = mv88e6xxx_phy_write_indirect,
+       .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 a28b46c33e130eb590e106d80813a9c27e2e25cc..2c8c5e1d16bce59029bad334ab004115f953e125 100644 (file)
@@ -2887,6 +2887,8 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
 
        if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
                ret = mv88e6xxx_phy_read_ppu(ps, addr, regnum);
+       else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
+               ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum);
        else
                ret = _mv88e6xxx_phy_read(ps, addr, regnum);
 
@@ -2908,6 +2910,8 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
 
        if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
                ret = mv88e6xxx_phy_write_ppu(ps, addr, regnum, val);
+       else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
+               ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val);
        else
                ret = _mv88e6xxx_phy_write(ps, addr, regnum, val);
 
@@ -2915,39 +2919,6 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
        return ret;
 }
 
-int
-mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
-{
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-       int addr = mv88e6xxx_port_to_phy_addr(ps, port);
-       int ret;
-
-       if (addr < 0)
-               return 0xffff;
-
-       mutex_lock(&ps->smi_mutex);
-       ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum);
-       mutex_unlock(&ps->smi_mutex);
-       return ret;
-}
-
-int
-mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
-                            u16 val)
-{
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-       int addr = mv88e6xxx_port_to_phy_addr(ps, port);
-       int ret;
-
-       if (addr < 0)
-               return addr;
-
-       mutex_lock(&ps->smi_mutex);
-       ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val);
-       mutex_unlock(&ps->smi_mutex);
-       return ret;
-}
-
 #ifdef CONFIG_NET_DSA_HWMON
 
 static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
index 52ca24efec64b235aa40ba23019b6319c9ad2df7..597257123ca77e816b90b1aaaf154f121aefa5e6 100644 (file)
@@ -355,10 +355,17 @@ enum mv88e6xxx_cap {
         * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
         */
        MV88E6XXX_CAP_PPU,
+
+       /* SMI PHY Command and Data registers.
+        * This requires an indirect access to PHY registers through
+        * GLOBAL2_SMI_OP, otherwise direct access to PHY registers is done.
+        */
+       MV88E6XXX_CAP_SMI_PHY,
 };
 
 /* Bitmask of capabilities */
 #define MV88E6XXX_FLAG_PPU             BIT(MV88E6XXX_CAP_PPU)
+#define MV88E6XXX_FLAG_SMI_PHY         BIT(MV88E6XXX_CAP_SMI_PHY)
 
 #define MV88E6XXX_FLAGS_FAMILY_6095    \
        MV88E6XXX_FLAG_PPU
@@ -371,11 +378,14 @@ enum mv88e6xxx_cap {
 #define MV88E6XXX_FLAGS_FAMILY_6185    \
        MV88E6XXX_FLAG_PPU
 
-#define MV88E6XXX_FLAGS_FAMILY_6320    0
+#define MV88E6XXX_FLAGS_FAMILY_6320    \
+       MV88E6XXX_FLAG_SMI_PHY
 
-#define MV88E6XXX_FLAGS_FAMILY_6351    0
+#define MV88E6XXX_FLAGS_FAMILY_6351    \
+       MV88E6XXX_FLAG_SMI_PHY
 
-#define MV88E6XXX_FLAGS_FAMILY_6352    0
+#define MV88E6XXX_FLAGS_FAMILY_6352    \
+       MV88E6XXX_FLAG_SMI_PHY
 
 struct mv88e6xxx_info {
        enum mv88e6xxx_family family;
@@ -497,9 +507,6 @@ int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
 int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
 int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
 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_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);
@@ -516,9 +523,6 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp);
 int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm);
 int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds);
 int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds);
-int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum);
-int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
-                                u16 val);
 int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
 int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
                      struct phy_device *phydev, struct ethtool_eee *e);