aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2016-05-09 13:22:40 -0400
committerDavid S. Miller <davem@davemloft.net>2016-05-09 14:26:08 -0400
commit6d5834a1adefd6199bbd7c8b2ba3a131f38e161e (patch)
treed87fa957c37396b8a28d589ba0cc9e3c0814e439 /drivers/net/dsa
parent8c9983a2249269f9b0f22bf070bf856ec1ff58d7 (diff)
net: dsa: mv88e6xxx: factorize PHY indirect access
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>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/mv88e6171.c4
-rw-r--r--drivers/net/dsa/mv88e6352.c4
-rw-r--r--drivers/net/dsa/mv88e6xxx.c37
-rw-r--r--drivers/net/dsa/mv88e6xxx.h22
4 files changed, 21 insertions, 46 deletions
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index e64cbeed2cdf..b190647d2a15 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -124,8 +124,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
124 .probe = mv88e6171_drv_probe, 124 .probe = mv88e6171_drv_probe,
125 .setup = mv88e6171_setup, 125 .setup = mv88e6171_setup,
126 .set_addr = mv88e6xxx_set_addr_indirect, 126 .set_addr = mv88e6xxx_set_addr_indirect,
127 .phy_read = mv88e6xxx_phy_read_indirect, 127 .phy_read = mv88e6xxx_phy_read,
128 .phy_write = mv88e6xxx_phy_write_indirect, 128 .phy_write = mv88e6xxx_phy_write,
129 .get_strings = mv88e6xxx_get_strings, 129 .get_strings = mv88e6xxx_get_strings,
130 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, 130 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
131 .get_sset_count = mv88e6xxx_get_sset_count, 131 .get_sset_count = mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index c61f0f4da6f4..6fa7c02f9027 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -344,8 +344,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
344 .probe = mv88e6352_drv_probe, 344 .probe = mv88e6352_drv_probe,
345 .setup = mv88e6352_setup, 345 .setup = mv88e6352_setup,
346 .set_addr = mv88e6xxx_set_addr_indirect, 346 .set_addr = mv88e6xxx_set_addr_indirect,
347 .phy_read = mv88e6xxx_phy_read_indirect, 347 .phy_read = mv88e6xxx_phy_read,
348 .phy_write = mv88e6xxx_phy_write_indirect, 348 .phy_write = mv88e6xxx_phy_write,
349 .get_strings = mv88e6xxx_get_strings, 349 .get_strings = mv88e6xxx_get_strings,
350 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, 350 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
351 .get_sset_count = mv88e6xxx_get_sset_count, 351 .get_sset_count = mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index a28b46c33e13..2c8c5e1d16bc 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2887,6 +2887,8 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
2887 2887
2888 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) 2888 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
2889 ret = mv88e6xxx_phy_read_ppu(ps, addr, regnum); 2889 ret = mv88e6xxx_phy_read_ppu(ps, addr, regnum);
2890 else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
2891 ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum);
2890 else 2892 else
2891 ret = _mv88e6xxx_phy_read(ps, addr, regnum); 2893 ret = _mv88e6xxx_phy_read(ps, addr, regnum);
2892 2894
@@ -2908,6 +2910,8 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
2908 2910
2909 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) 2911 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
2910 ret = mv88e6xxx_phy_write_ppu(ps, addr, regnum, val); 2912 ret = mv88e6xxx_phy_write_ppu(ps, addr, regnum, val);
2913 else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
2914 ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val);
2911 else 2915 else
2912 ret = _mv88e6xxx_phy_write(ps, addr, regnum, val); 2916 ret = _mv88e6xxx_phy_write(ps, addr, regnum, val);
2913 2917
@@ -2915,39 +2919,6 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
2915 return ret; 2919 return ret;
2916} 2920}
2917 2921
2918int
2919mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
2920{
2921 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2922 int addr = mv88e6xxx_port_to_phy_addr(ps, port);
2923 int ret;
2924
2925 if (addr < 0)
2926 return 0xffff;
2927
2928 mutex_lock(&ps->smi_mutex);
2929 ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum);
2930 mutex_unlock(&ps->smi_mutex);
2931 return ret;
2932}
2933
2934int
2935mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
2936 u16 val)
2937{
2938 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2939 int addr = mv88e6xxx_port_to_phy_addr(ps, port);
2940 int ret;
2941
2942 if (addr < 0)
2943 return addr;
2944
2945 mutex_lock(&ps->smi_mutex);
2946 ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val);
2947 mutex_unlock(&ps->smi_mutex);
2948 return ret;
2949}
2950
2951#ifdef CONFIG_NET_DSA_HWMON 2922#ifdef CONFIG_NET_DSA_HWMON
2952 2923
2953static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp) 2924static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 52ca24efec64..597257123ca7 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -355,10 +355,17 @@ enum mv88e6xxx_cap {
355 * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING. 355 * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
356 */ 356 */
357 MV88E6XXX_CAP_PPU, 357 MV88E6XXX_CAP_PPU,
358
359 /* SMI PHY Command and Data registers.
360 * This requires an indirect access to PHY registers through
361 * GLOBAL2_SMI_OP, otherwise direct access to PHY registers is done.
362 */
363 MV88E6XXX_CAP_SMI_PHY,
358}; 364};
359 365
360/* Bitmask of capabilities */ 366/* Bitmask of capabilities */
361#define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) 367#define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU)
368#define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY)
362 369
363#define MV88E6XXX_FLAGS_FAMILY_6095 \ 370#define MV88E6XXX_FLAGS_FAMILY_6095 \
364 MV88E6XXX_FLAG_PPU 371 MV88E6XXX_FLAG_PPU
@@ -371,11 +378,14 @@ enum mv88e6xxx_cap {
371#define MV88E6XXX_FLAGS_FAMILY_6185 \ 378#define MV88E6XXX_FLAGS_FAMILY_6185 \
372 MV88E6XXX_FLAG_PPU 379 MV88E6XXX_FLAG_PPU
373 380
374#define MV88E6XXX_FLAGS_FAMILY_6320 0 381#define MV88E6XXX_FLAGS_FAMILY_6320 \
382 MV88E6XXX_FLAG_SMI_PHY
375 383
376#define MV88E6XXX_FLAGS_FAMILY_6351 0 384#define MV88E6XXX_FLAGS_FAMILY_6351 \
385 MV88E6XXX_FLAG_SMI_PHY
377 386
378#define MV88E6XXX_FLAGS_FAMILY_6352 0 387#define MV88E6XXX_FLAGS_FAMILY_6352 \
388 MV88E6XXX_FLAG_SMI_PHY
379 389
380struct mv88e6xxx_info { 390struct mv88e6xxx_info {
381 enum mv88e6xxx_family family; 391 enum mv88e6xxx_family family;
@@ -497,9 +507,6 @@ int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
497int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr); 507int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
498int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum); 508int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
499int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val); 509int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
500int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum);
501int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
502 u16 val);
503void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data); 510void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
504void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port, 511void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
505 uint64_t *data); 512 uint64_t *data);
@@ -516,9 +523,6 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp);
516int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm); 523int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm);
517int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds); 524int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds);
518int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds); 525int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds);
519int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum);
520int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
521 u16 val);
522int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); 526int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
523int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, 527int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
524 struct phy_device *phydev, struct ethtool_eee *e); 528 struct phy_device *phydev, struct ethtool_eee *e);