From b5058d7a308035233db18032edc17135cb17ae27 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:38 -0400 Subject: net: dsa: mv88e6xxx: add flags to info Add a flags bitmap to the info structure in order to identify features supported or not by the different switch models. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 3 +++ drivers/net/dsa/mv88e6131.c | 4 ++++ drivers/net/dsa/mv88e6171.c | 4 ++++ drivers/net/dsa/mv88e6352.c | 6 ++++++ drivers/net/dsa/mv88e6xxx.h | 21 +++++++++++++++++++++ 5 files changed, 38 insertions(+) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 5535a42a6113..ab5885b68a07 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -24,18 +24,21 @@ static const struct mv88e6xxx_info mv88e6123_table[] = { .name = "Marvell 88E6123", .num_databases = 4096, .num_ports = 3, + .flags = MV88E6XXX_FLAGS_FAMILY_6165, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6161, .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6161", .num_databases = 4096, .num_ports = 6, + .flags = MV88E6XXX_FLAGS_FAMILY_6165, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6165, .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6165", .num_databases = 4096, .num_ports = 6, + .flags = MV88E6XXX_FLAGS_FAMILY_6165, } }; diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 357ab794d720..d4773204935b 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -24,24 +24,28 @@ static const struct mv88e6xxx_info mv88e6131_table[] = { .name = "Marvell 88E6095/88E6095F", .num_databases = 256, .num_ports = 11, + .flags = MV88E6XXX_FLAGS_FAMILY_6095, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6085, .family = MV88E6XXX_FAMILY_6097, .name = "Marvell 88E6085", .num_databases = 4096, .num_ports = 10, + .flags = MV88E6XXX_FLAGS_FAMILY_6097, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6131, .family = MV88E6XXX_FAMILY_6185, .name = "Marvell 88E6131", .num_databases = 256, .num_ports = 8, + .flags = MV88E6XXX_FLAGS_FAMILY_6185, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6185, .family = MV88E6XXX_FAMILY_6185, .name = "Marvell 88E6185", .num_databases = 256, .num_ports = 10, + .flags = MV88E6XXX_FLAGS_FAMILY_6185, } }; diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index f75164dc3bd6..e64cbeed2cdf 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -24,24 +24,28 @@ static const struct mv88e6xxx_info mv88e6171_table[] = { .name = "Marvell 88E6171", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6351, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6175, .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6175", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6351, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6350, .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6350", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6351, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6351, .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6351", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6351, } }; diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index c622a1d58480..c61f0f4da6f4 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -29,36 +29,42 @@ static const struct mv88e6xxx_info mv88e6352_table[] = { .name = "Marvell 88E6320", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6320, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6321, .family = MV88E6XXX_FAMILY_6320, .name = "Marvell 88E6321", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6320, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6172, .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6172", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6352, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6176, .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6176", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6352, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6240, .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6240", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6352, }, { .prod_num = PORT_SWITCH_ID_PROD_NUM_6352, .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6352", .num_databases = 4096, .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6352, } }; diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 4f455d219859..c67b72af9af1 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -350,12 +350,27 @@ enum mv88e6xxx_family { MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */ }; +#define MV88E6XXX_FLAGS_FAMILY_6095 0 + +#define MV88E6XXX_FLAGS_FAMILY_6097 0 + +#define MV88E6XXX_FLAGS_FAMILY_6165 0 + +#define MV88E6XXX_FLAGS_FAMILY_6185 0 + +#define MV88E6XXX_FLAGS_FAMILY_6320 0 + +#define MV88E6XXX_FLAGS_FAMILY_6351 0 + +#define MV88E6XXX_FLAGS_FAMILY_6352 0 + struct mv88e6xxx_info { enum mv88e6xxx_family family; u16 prod_num; const char *name; unsigned int num_databases; unsigned int num_ports; + unsigned long flags; }; struct mv88e6xxx_atu_entry { @@ -449,6 +464,12 @@ struct mv88e6xxx_hw_stat { enum stat_type type; }; +static inline bool mv88e6xxx_has(struct mv88e6xxx_priv_state *ps, + unsigned long flags) +{ + return (ps->info->flags & flags) == flags; +} + int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active); const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, int sw_addr, void **priv, -- cgit v1.2.3 From 8c9983a2249269f9b0f22bf070bf856ec1ff58d7 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:39 -0400 Subject: net: dsa: mv88e6xxx: factorize PHY access with PPU 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 Signed-off-by: David S. Miller --- drivers/net/dsa/Kconfig | 5 ----- drivers/net/dsa/mv88e6131.c | 39 ++------------------------------------- drivers/net/dsa/mv88e6xxx.c | 40 +++++++++++++++++++++++++--------------- drivers/net/dsa/mv88e6xxx.h | 25 ++++++++++++++++--------- 4 files changed, 43 insertions(+), 66 deletions(-) diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 90ba003d8fdf..4aaadced6b81 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -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 diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index d4773204935b..9d21d69de08a 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -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, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 470cfc783baa..a28b46c33e13 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -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; } diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index c67b72af9af1..52ca24efec64 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -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); -- cgit v1.2.3 From 6d5834a1adefd6199bbd7c8b2ba3a131f38e161e Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:40 -0400 Subject: 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 Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6171.c | 4 ++-- drivers/net/dsa/mv88e6352.c | 4 ++-- drivers/net/dsa/mv88e6xxx.c | 37 ++++--------------------------------- drivers/net/dsa/mv88e6xxx.h | 22 +++++++++++++--------- 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 = { .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, 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 = { .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, 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) 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) 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 { * 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); -- cgit v1.2.3 From d24645bebce2b13b3c5c49ff392cfb7f3efe0d76 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:41 -0400 Subject: net: dsa: mv88e6xxx: factorize EEPROM access Add a MV88E6XXX_FLAG_EEPROM flag to describe switch models featuring an EEPROM and distribute the EEPROM access routines to all models. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 2 + drivers/net/dsa/mv88e6131.c | 2 + drivers/net/dsa/mv88e6171.c | 2 + drivers/net/dsa/mv88e6352.c | 207 +----------------------------------------- drivers/net/dsa/mv88e6xxx.c | 216 +++++++++++++++++++++++++++++++++++++++++++- drivers/net/dsa/mv88e6xxx.h | 18 +++- 6 files changed, 236 insertions(+), 211 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index ab5885b68a07..8330a8e34bff 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -124,6 +124,8 @@ struct dsa_switch_driver mv88e6123_switch_driver = { #ifdef CONFIG_NET_DSA_HWMON .get_temp = mv88e6xxx_get_temp, #endif + .get_eeprom = mv88e6xxx_get_eeprom, + .set_eeprom = mv88e6xxx_set_eeprom, .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, }; diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 9d21d69de08a..ab8c507b8f8c 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -153,6 +153,8 @@ struct dsa_switch_driver mv88e6131_switch_driver = { .get_strings = mv88e6xxx_get_strings, .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, .get_sset_count = mv88e6xxx_get_sset_count, + .get_eeprom = mv88e6xxx_get_eeprom, + .set_eeprom = mv88e6xxx_set_eeprom, .adjust_link = mv88e6xxx_adjust_link, .port_bridge_join = mv88e6xxx_port_bridge_join, .port_bridge_leave = mv88e6xxx_port_bridge_leave, diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index b190647d2a15..a7afbaa87618 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -133,6 +133,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = { #ifdef CONFIG_NET_DSA_HWMON .get_temp = mv88e6xxx_get_temp, #endif + .get_eeprom = mv88e6xxx_get_eeprom, + .set_eeprom = mv88e6xxx_set_eeprom, .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, .port_bridge_join = mv88e6xxx_port_bridge_join, diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 6fa7c02f9027..3bb271e16035 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -125,8 +125,6 @@ static int mv88e6352_setup(struct dsa_switch *ds) if (ret < 0) return ret; - mutex_init(&ps->eeprom_mutex); - ret = mv88e6xxx_switch_reset(ps, true); if (ret < 0) return ret; @@ -138,207 +136,6 @@ static int mv88e6352_setup(struct dsa_switch *ds) return mv88e6xxx_setup_ports(ds); } -static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - mutex_lock(&ps->eeprom_mutex); - - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, - GLOBAL2_EEPROM_OP_READ | - (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); - if (ret < 0) - goto error; - - ret = mv88e6xxx_eeprom_busy_wait(ds); - if (ret < 0) - goto error; - - ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA); -error: - mutex_unlock(&ps->eeprom_mutex); - return ret; -} - -static int mv88e6352_get_eeprom(struct dsa_switch *ds, - struct ethtool_eeprom *eeprom, u8 *data) -{ - int offset; - int len; - int ret; - - offset = eeprom->offset; - len = eeprom->len; - eeprom->len = 0; - - eeprom->magic = 0xc3ec4951; - - ret = mv88e6xxx_eeprom_load_wait(ds); - if (ret < 0) - return ret; - - if (offset & 1) { - int word; - - word = mv88e6352_read_eeprom_word(ds, offset >> 1); - if (word < 0) - return word; - - *data++ = (word >> 8) & 0xff; - - offset++; - len--; - eeprom->len++; - } - - while (len >= 2) { - int word; - - word = mv88e6352_read_eeprom_word(ds, offset >> 1); - if (word < 0) - return word; - - *data++ = word & 0xff; - *data++ = (word >> 8) & 0xff; - - offset += 2; - len -= 2; - eeprom->len += 2; - } - - if (len) { - int word; - - word = mv88e6352_read_eeprom_word(ds, offset >> 1); - if (word < 0) - return word; - - *data++ = word & 0xff; - - offset++; - len--; - eeprom->len++; - } - - return 0; -} - -static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP); - if (ret < 0) - return ret; - - if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN)) - return -EROFS; - - return 0; -} - -static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr, - u16 data) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - mutex_lock(&ps->eeprom_mutex); - - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data); - if (ret < 0) - goto error; - - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, - GLOBAL2_EEPROM_OP_WRITE | - (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); - if (ret < 0) - goto error; - - ret = mv88e6xxx_eeprom_busy_wait(ds); -error: - mutex_unlock(&ps->eeprom_mutex); - return ret; -} - -static int mv88e6352_set_eeprom(struct dsa_switch *ds, - struct ethtool_eeprom *eeprom, u8 *data) -{ - int offset; - int ret; - int len; - - if (eeprom->magic != 0xc3ec4951) - return -EINVAL; - - ret = mv88e6352_eeprom_is_readonly(ds); - if (ret) - return ret; - - offset = eeprom->offset; - len = eeprom->len; - eeprom->len = 0; - - ret = mv88e6xxx_eeprom_load_wait(ds); - if (ret < 0) - return ret; - - if (offset & 1) { - int word; - - word = mv88e6352_read_eeprom_word(ds, offset >> 1); - if (word < 0) - return word; - - word = (*data++ << 8) | (word & 0xff); - - ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); - if (ret < 0) - return ret; - - offset++; - len--; - eeprom->len++; - } - - while (len >= 2) { - int word; - - word = *data++; - word |= *data++ << 8; - - ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); - if (ret < 0) - return ret; - - offset += 2; - len -= 2; - eeprom->len += 2; - } - - if (len) { - int word; - - word = mv88e6352_read_eeprom_word(ds, offset >> 1); - if (word < 0) - return word; - - word = (word & 0xff00) | *data++; - - ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); - if (ret < 0) - return ret; - - offset++; - len--; - eeprom->len++; - } - - return 0; -} - struct dsa_switch_driver mv88e6352_switch_driver = { .tag_protocol = DSA_TAG_PROTO_EDSA, .probe = mv88e6352_drv_probe, @@ -358,8 +155,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .set_temp_limit = mv88e6xxx_set_temp_limit, .get_temp_alarm = mv88e6xxx_get_temp_alarm, #endif - .get_eeprom = mv88e6352_get_eeprom, - .set_eeprom = mv88e6352_set_eeprom, + .get_eeprom = mv88e6xxx_get_eeprom, + .set_eeprom = mv88e6xxx_set_eeprom, .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, .port_bridge_join = mv88e6xxx_port_bridge_join, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 2c8c5e1d16bc..d277350069d0 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -823,7 +823,7 @@ static int _mv88e6xxx_phy_wait(struct mv88e6xxx_priv_state *ps) GLOBAL2_SMI_OP_BUSY); } -int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds) +static int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -831,7 +831,7 @@ int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds) GLOBAL2_EEPROM_OP_LOAD); } -int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds) +static int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -839,6 +839,215 @@ int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds) GLOBAL2_EEPROM_OP_BUSY); } +static int mv88e6xxx_read_eeprom_word(struct dsa_switch *ds, int addr) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + + mutex_lock(&ps->eeprom_mutex); + + ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, + GLOBAL2_EEPROM_OP_READ | + (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); + if (ret < 0) + goto error; + + ret = mv88e6xxx_eeprom_busy_wait(ds); + if (ret < 0) + goto error; + + ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA); +error: + mutex_unlock(&ps->eeprom_mutex); + return ret; +} + +int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, + u8 *data) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int offset; + int len; + int ret; + + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) + return -EOPNOTSUPP; + + offset = eeprom->offset; + len = eeprom->len; + eeprom->len = 0; + + eeprom->magic = 0xc3ec4951; + + ret = mv88e6xxx_eeprom_load_wait(ds); + if (ret < 0) + return ret; + + if (offset & 1) { + int word; + + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + *data++ = (word >> 8) & 0xff; + + offset++; + len--; + eeprom->len++; + } + + while (len >= 2) { + int word; + + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + *data++ = word & 0xff; + *data++ = (word >> 8) & 0xff; + + offset += 2; + len -= 2; + eeprom->len += 2; + } + + if (len) { + int word; + + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + *data++ = word & 0xff; + + offset++; + len--; + eeprom->len++; + } + + return 0; +} + +static int mv88e6xxx_eeprom_is_readonly(struct dsa_switch *ds) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + + ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP); + if (ret < 0) + return ret; + + if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN)) + return -EROFS; + + return 0; +} + +static int mv88e6xxx_write_eeprom_word(struct dsa_switch *ds, int addr, + u16 data) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + + mutex_lock(&ps->eeprom_mutex); + + ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data); + if (ret < 0) + goto error; + + ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, + GLOBAL2_EEPROM_OP_WRITE | + (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); + if (ret < 0) + goto error; + + ret = mv88e6xxx_eeprom_busy_wait(ds); +error: + mutex_unlock(&ps->eeprom_mutex); + return ret; +} + +int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, + u8 *data) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int offset; + int ret; + int len; + + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) + return -EOPNOTSUPP; + + if (eeprom->magic != 0xc3ec4951) + return -EINVAL; + + ret = mv88e6xxx_eeprom_is_readonly(ds); + if (ret) + return ret; + + offset = eeprom->offset; + len = eeprom->len; + eeprom->len = 0; + + ret = mv88e6xxx_eeprom_load_wait(ds); + if (ret < 0) + return ret; + + if (offset & 1) { + int word; + + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + word = (*data++ << 8) | (word & 0xff); + + ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word); + if (ret < 0) + return ret; + + offset++; + len--; + eeprom->len++; + } + + while (len >= 2) { + int word; + + word = *data++; + word |= *data++ << 8; + + ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word); + if (ret < 0) + return ret; + + offset += 2; + len -= 2; + eeprom->len += 2; + } + + if (len) { + int word; + + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + word = (word & 0xff00) | *data++; + + ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word); + if (ret < 0) + return ret; + + offset++; + len--; + eeprom->len++; + } + + return 0; +} + static int _mv88e6xxx_atu_wait(struct mv88e6xxx_priv_state *ps) { return _mv88e6xxx_wait(ps, REG_GLOBAL, GLOBAL_ATU_OP, @@ -2596,6 +2805,9 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) + mutex_init(&ps->eeprom_mutex); + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) mv88e6xxx_ppu_state_init(ps); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 597257123ca7..0181f6775bfc 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -351,6 +351,11 @@ enum mv88e6xxx_family { }; enum mv88e6xxx_cap { + /* EEPROM Command and Data registers. + * See GLOBAL2_EEPROM_OP and GLOBAL2_EEPROM_DATA. + */ + MV88E6XXX_CAP_EEPROM, + /* PHY Polling Unit. * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING. */ @@ -364,6 +369,7 @@ enum mv88e6xxx_cap { }; /* Bitmask of capabilities */ +#define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) #define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) #define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY) @@ -379,13 +385,15 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_PPU #define MV88E6XXX_FLAGS_FAMILY_6320 \ - MV88E6XXX_FLAG_SMI_PHY + (MV88E6XXX_FLAG_EEPROM | \ + MV88E6XXX_FLAG_SMI_PHY) #define MV88E6XXX_FLAGS_FAMILY_6351 \ MV88E6XXX_FLAG_SMI_PHY #define MV88E6XXX_FLAGS_FAMILY_6352 \ - MV88E6XXX_FLAG_SMI_PHY + (MV88E6XXX_FLAG_EEPROM | \ + MV88E6XXX_FLAG_SMI_PHY) struct mv88e6xxx_info { enum mv88e6xxx_family family; @@ -521,8 +529,10 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp); int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp); 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_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, + u8 *data); +int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, + u8 *data); 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); -- cgit v1.2.3 From 6594f615792a52ccb66c07000ade917e8c8f62fd Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:42 -0400 Subject: net: dsa: mv88e6xxx: factorize temperature access Add MV88E6XXX_FLAG_TEMP and MV88E6XXX_FLAG_TEMP_LIMIT flags to describe switch models featuring a temperature access. Use them to centralize the access to the temperature feature. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 3 +++ drivers/net/dsa/mv88e6131.c | 6 ++++++ drivers/net/dsa/mv88e6171.c | 3 +++ drivers/net/dsa/mv88e6xxx.c | 9 ++++++--- drivers/net/dsa/mv88e6xxx.h | 22 ++++++++++++++++++---- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 8330a8e34bff..e234bdbd9b42 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -123,6 +123,9 @@ struct dsa_switch_driver mv88e6123_switch_driver = { .adjust_link = mv88e6xxx_adjust_link, #ifdef CONFIG_NET_DSA_HWMON .get_temp = mv88e6xxx_get_temp, + .get_temp_limit = mv88e6xxx_get_temp_limit, + .set_temp_limit = mv88e6xxx_set_temp_limit, + .get_temp_alarm = mv88e6xxx_get_temp_alarm, #endif .get_eeprom = mv88e6xxx_get_eeprom, .set_eeprom = mv88e6xxx_set_eeprom, diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index ab8c507b8f8c..089f9c05ea38 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -155,6 +155,12 @@ struct dsa_switch_driver mv88e6131_switch_driver = { .get_sset_count = mv88e6xxx_get_sset_count, .get_eeprom = mv88e6xxx_get_eeprom, .set_eeprom = mv88e6xxx_set_eeprom, +#ifdef CONFIG_NET_DSA_HWMON + .get_temp = mv88e6xxx_get_temp, + .get_temp_limit = mv88e6xxx_get_temp_limit, + .set_temp_limit = mv88e6xxx_set_temp_limit, + .get_temp_alarm = mv88e6xxx_get_temp_alarm, +#endif .adjust_link = mv88e6xxx_adjust_link, .port_bridge_join = mv88e6xxx_port_bridge_join, .port_bridge_leave = mv88e6xxx_port_bridge_leave, diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index a7afbaa87618..588b48625af7 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -132,6 +132,9 @@ struct dsa_switch_driver mv88e6171_switch_driver = { .adjust_link = mv88e6xxx_adjust_link, #ifdef CONFIG_NET_DSA_HWMON .get_temp = mv88e6xxx_get_temp, + .get_temp_limit = mv88e6xxx_get_temp_limit, + .set_temp_limit = mv88e6xxx_set_temp_limit, + .get_temp_alarm = mv88e6xxx_get_temp_alarm, #endif .get_eeprom = mv88e6xxx_get_eeprom, .set_eeprom = mv88e6xxx_set_eeprom, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index d277350069d0..24aea900af35 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -3199,6 +3199,9 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP)) + return -EOPNOTSUPP; + if (mv88e6xxx_6320_family(ps) || mv88e6xxx_6352_family(ps)) return mv88e63xx_get_temp(ds, temp); @@ -3211,7 +3214,7 @@ int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; int ret; - if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT)) return -EOPNOTSUPP; *temp = 0; @@ -3231,7 +3234,7 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; int ret; - if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT)) return -EOPNOTSUPP; ret = mv88e6xxx_phy_page_read(ds, phy, 6, 26); @@ -3248,7 +3251,7 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm) int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; int ret; - if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT)) return -EOPNOTSUPP; *alarm = false; diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 0181f6775bfc..9ddb6d04389e 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -366,12 +366,20 @@ enum mv88e6xxx_cap { * GLOBAL2_SMI_OP, otherwise direct access to PHY registers is done. */ MV88E6XXX_CAP_SMI_PHY, + + /* Internal temperature sensor. + * Available from any enabled port's PHY register 26, page 6. + */ + MV88E6XXX_CAP_TEMP, + MV88E6XXX_CAP_TEMP_LIMIT, }; /* Bitmask of capabilities */ #define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) #define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) #define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY) +#define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP) +#define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT) #define MV88E6XXX_FLAGS_FAMILY_6095 \ MV88E6XXX_FLAG_PPU @@ -379,21 +387,27 @@ enum mv88e6xxx_cap { #define MV88E6XXX_FLAGS_FAMILY_6097 \ MV88E6XXX_FLAG_PPU -#define MV88E6XXX_FLAGS_FAMILY_6165 0 +#define MV88E6XXX_FLAGS_FAMILY_6165 \ + MV88E6XXX_FLAG_TEMP #define MV88E6XXX_FLAGS_FAMILY_6185 \ MV88E6XXX_FLAG_PPU #define MV88E6XXX_FLAGS_FAMILY_6320 \ (MV88E6XXX_FLAG_EEPROM | \ - MV88E6XXX_FLAG_SMI_PHY) + MV88E6XXX_FLAG_SMI_PHY | \ + MV88E6XXX_FLAG_TEMP | \ + MV88E6XXX_FLAG_TEMP_LIMIT) #define MV88E6XXX_FLAGS_FAMILY_6351 \ - MV88E6XXX_FLAG_SMI_PHY + (MV88E6XXX_FLAG_SMI_PHY | \ + MV88E6XXX_FLAG_TEMP) #define MV88E6XXX_FLAGS_FAMILY_6352 \ (MV88E6XXX_FLAG_EEPROM | \ - MV88E6XXX_FLAG_SMI_PHY) + MV88E6XXX_FLAG_SMI_PHY | \ + MV88E6XXX_FLAG_TEMP | \ + MV88E6XXX_FLAG_TEMP_LIMIT) struct mv88e6xxx_info { enum mv88e6xxx_family family; -- cgit v1.2.3 From 1d13a06e00bdcde27d4d88e011841ff0924b3dde Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:43 -0400 Subject: net: dsa: mv88e6xxx: factorize MAC address setting Some switch models have a dedicated register for Switch MAC/WoF/WoL. This register, when present, is used to indirectly set the switch MAC address, instead of a direct write to 3 global registers. Identify this feature and share a common mv88e6xxx_set_addr function. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 2 +- drivers/net/dsa/mv88e6131.c | 2 +- drivers/net/dsa/mv88e6171.c | 2 +- drivers/net/dsa/mv88e6352.c | 2 +- drivers/net/dsa/mv88e6xxx.c | 14 ++++++++++++-- drivers/net/dsa/mv88e6xxx.h | 17 ++++++++++++++--- 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index e234bdbd9b42..c349fb7ec3f2 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -114,7 +114,7 @@ struct dsa_switch_driver mv88e6123_switch_driver = { .tag_protocol = DSA_TAG_PROTO_EDSA, .probe = mv88e6123_drv_probe, .setup = mv88e6123_setup, - .set_addr = mv88e6xxx_set_addr_indirect, + .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, .get_strings = mv88e6xxx_get_strings, diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 089f9c05ea38..1e040c6d663a 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -147,7 +147,7 @@ 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, + .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, .get_strings = mv88e6xxx_get_strings, diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 588b48625af7..f9b20e05b895 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -123,7 +123,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = { .tag_protocol = DSA_TAG_PROTO_EDSA, .probe = mv88e6171_drv_probe, .setup = mv88e6171_setup, - .set_addr = mv88e6xxx_set_addr_indirect, + .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, .get_strings = mv88e6xxx_get_strings, diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 3bb271e16035..d03c14a7ad1f 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -140,7 +140,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .tag_protocol = DSA_TAG_PROTO_EDSA, .probe = mv88e6352_drv_probe, .setup = mv88e6352_setup, - .set_addr = mv88e6xxx_set_addr_indirect, + .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, .get_strings = mv88e6xxx_get_strings, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 24aea900af35..4f0e047538d2 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -173,7 +173,7 @@ int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, return ret; } -int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) +static int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int err; @@ -192,7 +192,7 @@ int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) (addr[4] << 8) | addr[5]); } -int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) +static int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int ret; @@ -225,6 +225,16 @@ int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) return 0; } +int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SWITCH_MAC)) + return mv88e6xxx_set_addr_indirect(ds, addr); + else + return mv88e6xxx_set_addr_direct(ds, addr); +} + static int _mv88e6xxx_phy_read(struct mv88e6xxx_priv_state *ps, int addr, int regnum) { diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 9ddb6d04389e..517e95fbd10e 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -367,6 +367,13 @@ enum mv88e6xxx_cap { */ MV88E6XXX_CAP_SMI_PHY, + /* Switch MAC/WoL/WoF register. + * This requires an indirect access to set the switch MAC address + * through GLOBAL2_SWITCH_MAC, otherwise GLOBAL_MAC_01, GLOBAL_MAC_23, + * and GLOBAL_MAC_45 are used with a direct access. + */ + MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF, + /* Internal temperature sensor. * Available from any enabled port's PHY register 26, page 6. */ @@ -378,6 +385,7 @@ enum mv88e6xxx_cap { #define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) #define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) #define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY) +#define MV88E6XXX_FLAG_SWITCH_MAC BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF) #define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP) #define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT) @@ -388,7 +396,8 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_PPU #define MV88E6XXX_FLAGS_FAMILY_6165 \ - MV88E6XXX_FLAG_TEMP + (MV88E6XXX_FLAG_SWITCH_MAC | \ + MV88E6XXX_FLAG_TEMP) #define MV88E6XXX_FLAGS_FAMILY_6185 \ MV88E6XXX_FLAG_PPU @@ -396,16 +405,19 @@ enum mv88e6xxx_cap { #define MV88E6XXX_FLAGS_FAMILY_6320 \ (MV88E6XXX_FLAG_EEPROM | \ MV88E6XXX_FLAG_SMI_PHY | \ + MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ MV88E6XXX_FLAG_TEMP_LIMIT) #define MV88E6XXX_FLAGS_FAMILY_6351 \ (MV88E6XXX_FLAG_SMI_PHY | \ + MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP) #define MV88E6XXX_FLAGS_FAMILY_6352 \ (MV88E6XXX_FLAG_EEPROM | \ MV88E6XXX_FLAG_SMI_PHY | \ + MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ MV88E6XXX_FLAG_TEMP_LIMIT) @@ -525,8 +537,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds); int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg); int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, int reg, u16 val); -int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr); -int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr); +int mv88e6xxx_set_addr(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); void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data); -- cgit v1.2.3 From aadbdb8a0da6c38e8370fb7cd860f38b266c6037 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:44 -0400 Subject: net: dsa: mv88e6xxx: factorize EEE access Add a MV88E6XXX_FLAG_EEE flag to describe switch models featuring Energy Efficient Ethernet. Use it to conditionally support such access in the common code. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 2 ++ drivers/net/dsa/mv88e6131.c | 2 ++ drivers/net/dsa/mv88e6171.c | 2 ++ drivers/net/dsa/mv88e6xxx.c | 6 ++++++ drivers/net/dsa/mv88e6xxx.h | 11 +++++++++-- 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index c349fb7ec3f2..1ad7bcd1d421 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -117,6 +117,8 @@ struct dsa_switch_driver mv88e6123_switch_driver = { .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, + .set_eee = mv88e6xxx_set_eee, + .get_eee = mv88e6xxx_get_eee, .get_strings = mv88e6xxx_get_strings, .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, .get_sset_count = mv88e6xxx_get_sset_count, diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 1e040c6d663a..432d3c487691 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -150,6 +150,8 @@ struct dsa_switch_driver mv88e6131_switch_driver = { .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, + .set_eee = mv88e6xxx_set_eee, + .get_eee = mv88e6xxx_get_eee, .get_strings = mv88e6xxx_get_strings, .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, .get_sset_count = mv88e6xxx_get_sset_count, diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index f9b20e05b895..a98e7d3c0c64 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -126,6 +126,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = { .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, + .set_eee = mv88e6xxx_set_eee, + .get_eee = mv88e6xxx_get_eee, .get_strings = mv88e6xxx_get_strings, .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, .get_sset_count = mv88e6xxx_get_sset_count, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 4f0e047538d2..6aac58b8b78b 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1105,6 +1105,9 @@ int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int reg; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEE)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); reg = _mv88e6xxx_phy_read_indirect(ps, port, 16); @@ -1133,6 +1136,9 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, int reg; int ret; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEE)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); ret = _mv88e6xxx_phy_read_indirect(ps, port, 16); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 517e95fbd10e..b99e0905992a 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -351,6 +351,10 @@ enum mv88e6xxx_family { }; enum mv88e6xxx_cap { + /* Energy Efficient Ethernet. + */ + MV88E6XXX_CAP_EEE, + /* EEPROM Command and Data registers. * See GLOBAL2_EEPROM_OP and GLOBAL2_EEPROM_DATA. */ @@ -382,6 +386,7 @@ enum mv88e6xxx_cap { }; /* Bitmask of capabilities */ +#define MV88E6XXX_FLAG_EEE BIT(MV88E6XXX_CAP_EEE) #define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) #define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) #define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY) @@ -403,7 +408,8 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_PPU #define MV88E6XXX_FLAGS_FAMILY_6320 \ - (MV88E6XXX_FLAG_EEPROM | \ + (MV88E6XXX_FLAG_EEE | \ + MV88E6XXX_FLAG_EEPROM | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ @@ -415,7 +421,8 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_TEMP) #define MV88E6XXX_FLAGS_FAMILY_6352 \ - (MV88E6XXX_FLAG_EEPROM | \ + (MV88E6XXX_FLAG_EEE | \ + MV88E6XXX_FLAG_EEPROM | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ -- cgit v1.2.3 From 2306251341bda39f1c3260bb96479db4dff2fe95 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:45 -0400 Subject: net: dsa: mv88e6131: add registers access Only 6131 was not supporting the port registers access yet. Assume such support and use the unlock access routines in the meantime. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6131.c | 2 ++ drivers/net/dsa/mv88e6xxx.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 432d3c487691..3fb06af74db3 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -157,6 +157,8 @@ struct dsa_switch_driver mv88e6131_switch_driver = { .get_sset_count = mv88e6xxx_get_sset_count, .get_eeprom = mv88e6xxx_get_eeprom, .set_eeprom = mv88e6xxx_set_eeprom, + .get_regs_len = mv88e6xxx_get_regs_len, + .get_regs = mv88e6xxx_get_regs, #ifdef CONFIG_NET_DSA_HWMON .get_temp = mv88e6xxx_get_temp, .get_temp_limit = mv88e6xxx_get_temp_limit, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 6aac58b8b78b..c28ad83ee74d 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -787,13 +787,17 @@ void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, memset(p, 0xff, 32 * sizeof(u16)); + mutex_lock(&ps->smi_mutex); + for (i = 0; i < 32; i++) { int ret; - ret = mv88e6xxx_reg_read(ps, REG_PORT(port), i); + ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), i); if (ret >= 0) p[i] = ret; } + + mutex_unlock(&ps->smi_mutex); } static int _mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, int offset, -- cgit v1.2.3 From 936f234a9624dbce9f723cbb24f135c60f76c148 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:46 -0400 Subject: net: dsa: mv88e6xxx: factorize bridge support Add MV88E6XXX_FLAG_PORTSTATE and MV88E6XXX_FLAG_VLANTABLE flags to identify switch models with required 802.1D operations. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 3 +++ drivers/net/dsa/mv88e6131.c | 1 + drivers/net/dsa/mv88e6xxx.c | 9 +++++++++ drivers/net/dsa/mv88e6xxx.h | 38 ++++++++++++++++++++++++++++++-------- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 1ad7bcd1d421..81cd4a906038 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -133,6 +133,9 @@ struct dsa_switch_driver mv88e6123_switch_driver = { .set_eeprom = mv88e6xxx_set_eeprom, .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, + .port_bridge_join = mv88e6xxx_port_bridge_join, + .port_bridge_leave = mv88e6xxx_port_bridge_leave, + .port_stp_state_set = mv88e6xxx_port_stp_state_set, }; MODULE_ALIAS("platform:mv88e6123"); diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 3fb06af74db3..5d252445e543 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -168,6 +168,7 @@ struct dsa_switch_driver mv88e6131_switch_driver = { .adjust_link = mv88e6xxx_adjust_link, .port_bridge_join = mv88e6xxx_port_bridge_join, .port_bridge_leave = mv88e6xxx_port_bridge_leave, + .port_stp_state_set = mv88e6xxx_port_stp_state_set, .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, .port_vlan_add = mv88e6xxx_port_vlan_add, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index c28ad83ee74d..f02738eaf541 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1369,6 +1369,9 @@ void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int stp_state; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_PORTSTATE)) + return; + switch (state) { case BR_STATE_DISABLED: stp_state = PORT_CONTROL_STATE_DISABLED; @@ -2430,6 +2433,9 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int i, err = 0; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); /* Assign the bridge and remap each port's VLANTable */ @@ -2454,6 +2460,9 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) struct net_device *bridge = ps->ports[port].bridge_dev; int i; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE)) + return; + mutex_lock(&ps->smi_mutex); /* Unassign the bridge and remap each port's VLANTable */ diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index b99e0905992a..d15e0b3dffd3 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -360,6 +360,11 @@ enum mv88e6xxx_cap { */ MV88E6XXX_CAP_EEPROM, + /* Port State Filtering for 802.1D Spanning Tree. + * See PORT_CONTROL_STATE_* values in the PORT_CONTROL register. + */ + MV88E6XXX_CAP_PORTSTATE, + /* PHY Polling Unit. * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING. */ @@ -383,50 +388,67 @@ enum mv88e6xxx_cap { */ MV88E6XXX_CAP_TEMP, MV88E6XXX_CAP_TEMP_LIMIT, + + /* In-chip Port Based VLANs. + * Each port VLANTable register (see PORT_BASE_VLAN) is used to restrict + * the output (or egress) ports to which it is allowed to send frames. + */ + MV88E6XXX_CAP_VLANTABLE, }; /* Bitmask of capabilities */ #define MV88E6XXX_FLAG_EEE BIT(MV88E6XXX_CAP_EEE) #define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) +#define MV88E6XXX_FLAG_PORTSTATE BIT(MV88E6XXX_CAP_PORTSTATE) #define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) #define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY) #define MV88E6XXX_FLAG_SWITCH_MAC BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF) #define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP) #define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT) +#define MV88E6XXX_FLAG_VLANTABLE BIT(MV88E6XXX_CAP_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6095 \ - MV88E6XXX_FLAG_PPU + (MV88E6XXX_FLAG_PPU | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6097 \ - MV88E6XXX_FLAG_PPU + (MV88E6XXX_FLAG_PPU | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6165 \ (MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP) #define MV88E6XXX_FLAGS_FAMILY_6185 \ - MV88E6XXX_FLAG_PPU + (MV88E6XXX_FLAG_PPU | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6320 \ (MV88E6XXX_FLAG_EEE | \ MV88E6XXX_FLAG_EEPROM | \ + MV88E6XXX_FLAG_PORTSTATE | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ - MV88E6XXX_FLAG_TEMP_LIMIT) + MV88E6XXX_FLAG_TEMP_LIMIT | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6351 \ - (MV88E6XXX_FLAG_SMI_PHY | \ + (MV88E6XXX_FLAG_PORTSTATE | \ + MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ - MV88E6XXX_FLAG_TEMP) + MV88E6XXX_FLAG_TEMP | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6352 \ (MV88E6XXX_FLAG_EEE | \ MV88E6XXX_FLAG_EEPROM | \ - MV88E6XXX_FLAG_SMI_PHY | \ + MV88E6XXX_FLAG_PORTSTATE | \ + MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ - MV88E6XXX_FLAG_TEMP_LIMIT) + MV88E6XXX_FLAG_TEMP_LIMIT | \ + MV88E6XXX_FLAG_VLANTABLE) struct mv88e6xxx_info { enum mv88e6xxx_family family; -- cgit v1.2.3 From 54d77b5b6ac92c76ee7dd360d8b7b0dfabf9f5f0 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:47 -0400 Subject: net: dsa: mv88e6xxx: factorize VTU access Add a MV88E6XXX_FLAG_VTU flag to indentify switch models with a VLAN Table Unit. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 5 +++++ drivers/net/dsa/mv88e6xxx.c | 16 ++++++++++++++++ drivers/net/dsa/mv88e6xxx.h | 24 ++++++++++++++++++------ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 81cd4a906038..da5aa9c0a471 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -136,6 +136,11 @@ struct dsa_switch_driver mv88e6123_switch_driver = { .port_bridge_join = mv88e6xxx_port_bridge_join, .port_bridge_leave = mv88e6xxx_port_bridge_leave, .port_stp_state_set = mv88e6xxx_port_stp_state_set, + .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, + .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, + .port_vlan_add = mv88e6xxx_port_vlan_add, + .port_vlan_del = mv88e6xxx_port_vlan_del, + .port_vlan_dump = mv88e6xxx_port_vlan_dump, }; MODULE_ALIAS("platform:mv88e6123"); diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index f02738eaf541..6c472cfa1df9 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1596,6 +1596,9 @@ int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, u16 pvid; int err; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); err = _mv88e6xxx_port_pvid_get(ps, port, &pvid); @@ -2019,6 +2022,9 @@ int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, PORT_CONTROL_2_8021Q_DISABLED; int ret; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_CONTROL_2); @@ -2052,8 +2058,12 @@ int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan, struct switchdev_trans *trans) { + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int err; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) + return -EOPNOTSUPP; + /* If the requested port doesn't belong to the same bridge as the VLAN * members, do not support it (yet) and fallback to software VLAN. */ @@ -2094,6 +2104,9 @@ void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; u16 vid; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) + return; + mutex_lock(&ps->smi_mutex); for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) @@ -2151,6 +2164,9 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 pvid, vid; int err = 0; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); err = _mv88e6xxx_port_pvid_get(ps, port, &pvid); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index d15e0b3dffd3..4f21206ac4de 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -394,6 +394,11 @@ enum mv88e6xxx_cap { * the output (or egress) ports to which it is allowed to send frames. */ MV88E6XXX_CAP_VLANTABLE, + + /* VLAN Table Unit. + * The VTU is used to program 802.1Q VLANs. See GLOBAL_VTU_OP. + */ + MV88E6XXX_CAP_VTU, }; /* Bitmask of capabilities */ @@ -406,14 +411,17 @@ enum mv88e6xxx_cap { #define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP) #define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT) #define MV88E6XXX_FLAG_VLANTABLE BIT(MV88E6XXX_CAP_VLANTABLE) +#define MV88E6XXX_FLAG_VTU BIT(MV88E6XXX_CAP_VTU) #define MV88E6XXX_FLAGS_FAMILY_6095 \ (MV88E6XXX_FLAG_PPU | \ - MV88E6XXX_FLAG_VLANTABLE) + MV88E6XXX_FLAG_VLANTABLE | \ + MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6097 \ (MV88E6XXX_FLAG_PPU | \ - MV88E6XXX_FLAG_VLANTABLE) + MV88E6XXX_FLAG_VLANTABLE | \ + MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6165 \ (MV88E6XXX_FLAG_SWITCH_MAC | \ @@ -421,7 +429,8 @@ enum mv88e6xxx_cap { #define MV88E6XXX_FLAGS_FAMILY_6185 \ (MV88E6XXX_FLAG_PPU | \ - MV88E6XXX_FLAG_VLANTABLE) + MV88E6XXX_FLAG_VLANTABLE | \ + MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6320 \ (MV88E6XXX_FLAG_EEE | \ @@ -431,14 +440,16 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ MV88E6XXX_FLAG_TEMP_LIMIT | \ - MV88E6XXX_FLAG_VLANTABLE) + MV88E6XXX_FLAG_VLANTABLE | \ + MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6351 \ (MV88E6XXX_FLAG_PORTSTATE | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ - MV88E6XXX_FLAG_VLANTABLE) + MV88E6XXX_FLAG_VLANTABLE | \ + MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6352 \ (MV88E6XXX_FLAG_EEE | \ @@ -448,7 +459,8 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ MV88E6XXX_FLAG_TEMP_LIMIT | \ - MV88E6XXX_FLAG_VLANTABLE) + MV88E6XXX_FLAG_VLANTABLE | \ + MV88E6XXX_FLAG_VTU) struct mv88e6xxx_info { enum mv88e6xxx_family family; -- cgit v1.2.3 From 2672f82548de2be29adcf5ef3c99fdaa1e5ace32 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:48 -0400 Subject: net: dsa: mv88e6xxx: factorize ATU access Add a MV88E6XXX_FLAG_ATU flag to identify switch models with an Address Translation Unit. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 4 ++++ drivers/net/dsa/mv88e6xxx.c | 14 ++++++++++++++ drivers/net/dsa/mv88e6xxx.h | 24 ++++++++++++++++++------ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index da5aa9c0a471..45cce4fa5f37 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -141,6 +141,10 @@ struct dsa_switch_driver mv88e6123_switch_driver = { .port_vlan_add = mv88e6xxx_port_vlan_add, .port_vlan_del = mv88e6xxx_port_vlan_del, .port_vlan_dump = mv88e6xxx_port_vlan_dump, + .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, + .port_fdb_add = mv88e6xxx_port_fdb_add, + .port_fdb_del = mv88e6xxx_port_fdb_del, + .port_fdb_dump = mv88e6xxx_port_fdb_dump, }; MODULE_ALIAS("platform:mv88e6123"); diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 6c472cfa1df9..037244b95e79 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2275,6 +2275,11 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, const struct switchdev_obj_port_fdb *fdb, struct switchdev_trans *trans) { + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU)) + return -EOPNOTSUPP; + /* We don't need any dynamic resource from the kernel (yet), * so skip the prepare phase. */ @@ -2290,6 +2295,9 @@ void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, GLOBAL_ATU_DATA_STATE_UC_STATIC; struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU)) + return; + mutex_lock(&ps->smi_mutex); if (_mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, state)) netdev_err(ds->ports[port], "failed to load MAC address\n"); @@ -2302,6 +2310,9 @@ int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int ret; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); ret = _mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, GLOBAL_ATU_DATA_STATE_UNUSED); @@ -2407,6 +2418,9 @@ int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, u16 fid; int err; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); /* Dump port's default Filtering Information Database (VLAN ID 0) */ diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 4f21206ac4de..192292f21c8a 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -351,6 +351,11 @@ enum mv88e6xxx_family { }; enum mv88e6xxx_cap { + /* Address Translation Unit. + * The ATU is used to lookup and learn MAC addresses. See GLOBAL_ATU_OP. + */ + MV88E6XXX_CAP_ATU, + /* Energy Efficient Ethernet. */ MV88E6XXX_CAP_EEE, @@ -402,6 +407,7 @@ enum mv88e6xxx_cap { }; /* Bitmask of capabilities */ +#define MV88E6XXX_FLAG_ATU BIT(MV88E6XXX_CAP_ATU) #define MV88E6XXX_FLAG_EEE BIT(MV88E6XXX_CAP_EEE) #define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) #define MV88E6XXX_FLAG_PORTSTATE BIT(MV88E6XXX_CAP_PORTSTATE) @@ -414,12 +420,14 @@ enum mv88e6xxx_cap { #define MV88E6XXX_FLAG_VTU BIT(MV88E6XXX_CAP_VTU) #define MV88E6XXX_FLAGS_FAMILY_6095 \ - (MV88E6XXX_FLAG_PPU | \ + (MV88E6XXX_FLAG_ATU | \ + MV88E6XXX_FLAG_PPU | \ MV88E6XXX_FLAG_VLANTABLE | \ MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6097 \ - (MV88E6XXX_FLAG_PPU | \ + (MV88E6XXX_FLAG_ATU | \ + MV88E6XXX_FLAG_PPU | \ MV88E6XXX_FLAG_VLANTABLE | \ MV88E6XXX_FLAG_VTU) @@ -428,12 +436,14 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_TEMP) #define MV88E6XXX_FLAGS_FAMILY_6185 \ - (MV88E6XXX_FLAG_PPU | \ + (MV88E6XXX_FLAG_ATU | \ + MV88E6XXX_FLAG_PPU | \ MV88E6XXX_FLAG_VLANTABLE | \ MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6320 \ - (MV88E6XXX_FLAG_EEE | \ + (MV88E6XXX_FLAG_ATU | \ + MV88E6XXX_FLAG_EEE | \ MV88E6XXX_FLAG_EEPROM | \ MV88E6XXX_FLAG_PORTSTATE | \ MV88E6XXX_FLAG_SMI_PHY | \ @@ -444,7 +454,8 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6351 \ - (MV88E6XXX_FLAG_PORTSTATE | \ + (MV88E6XXX_FLAG_ATU | \ + MV88E6XXX_FLAG_PORTSTATE | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ @@ -452,7 +463,8 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_VTU) #define MV88E6XXX_FLAGS_FAMILY_6352 \ - (MV88E6XXX_FLAG_EEE | \ + (MV88E6XXX_FLAG_ATU | \ + MV88E6XXX_FLAG_EEE | \ MV88E6XXX_FLAG_EEPROM | \ MV88E6XXX_FLAG_PORTSTATE | \ MV88E6XXX_FLAG_SMI_PHY | \ -- cgit v1.2.3 From 552238b59487eaac1477bdb7b0c4c652f29cbc86 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:49 -0400 Subject: net: dsa: mv88e6xxx: factorize switch reset Add a MV88E6XXX_FLAG_PPU_ACTIVE flag to describe how to reset the switch, and merge the reset call to the common setup code. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 4 -- drivers/net/dsa/mv88e6131.c | 4 -- drivers/net/dsa/mv88e6171.c | 4 -- drivers/net/dsa/mv88e6352.c | 4 -- drivers/net/dsa/mv88e6xxx.c | 137 +++++++++++++++++++++++--------------------- drivers/net/dsa/mv88e6xxx.h | 6 +- 6 files changed, 76 insertions(+), 83 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 45cce4fa5f37..fadec7a0e6b5 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -99,10 +99,6 @@ static int mv88e6123_setup(struct dsa_switch *ds) if (ret < 0) return ret; - ret = mv88e6xxx_switch_reset(ps, false); - if (ret < 0) - return ret; - ret = mv88e6123_setup_global(ds); if (ret < 0) return ret; diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 5d252445e543..25ed82372df5 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -132,10 +132,6 @@ static int mv88e6131_setup(struct dsa_switch *ds) if (ret < 0) return ret; - ret = mv88e6xxx_switch_reset(ps, false); - if (ret < 0) - return ret; - ret = mv88e6131_setup_global(ds); if (ret < 0) return ret; diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index a98e7d3c0c64..caaa4b66abc1 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -108,10 +108,6 @@ static int mv88e6171_setup(struct dsa_switch *ds) if (ret < 0) return ret; - ret = mv88e6xxx_switch_reset(ps, true); - if (ret < 0) - return ret; - ret = mv88e6171_setup_global(ds); if (ret < 0) return ret; diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index d03c14a7ad1f..470789a3f8ec 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -125,10 +125,6 @@ static int mv88e6352_setup(struct dsa_switch *ds) if (ret < 0) return ret; - ret = mv88e6xxx_switch_reset(ps, true); - if (ret < 0) - return ret; - ret = mv88e6352_setup_global(ds); if (ret < 0) return ret; diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 037244b95e79..b631a5d07ba0 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2559,6 +2559,68 @@ restore_page_0: return ret; } +static int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps) +{ + bool ppu_active = mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE); + u16 is_reset = (ppu_active ? 0x8800 : 0xc800); + struct gpio_desc *gpiod = ps->ds->pd->reset; + unsigned long timeout; + int ret; + int i; + + /* Set all ports to the disabled state. */ + for (i = 0; i < ps->info->num_ports; i++) { + ret = _mv88e6xxx_reg_read(ps, REG_PORT(i), PORT_CONTROL); + if (ret < 0) + return ret; + + ret = _mv88e6xxx_reg_write(ps, REG_PORT(i), PORT_CONTROL, + ret & 0xfffc); + if (ret) + return ret; + } + + /* Wait for transmit queues to drain. */ + usleep_range(2000, 4000); + + /* If there is a gpio connected to the reset pin, toggle it */ + if (gpiod) { + gpiod_set_value_cansleep(gpiod, 1); + usleep_range(10000, 20000); + gpiod_set_value_cansleep(gpiod, 0); + usleep_range(10000, 20000); + } + + /* Reset the switch. Keep the PPU active if requested. The PPU + * needs to be active to support indirect phy register access + * through global registers 0x18 and 0x19. + */ + if (ppu_active) + ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc000); + else + ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc400); + if (ret) + return ret; + + /* Wait up to one second for reset to complete. */ + timeout = jiffies + 1 * HZ; + while (time_before(jiffies, timeout)) { + ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, 0x00); + if (ret < 0) + return ret; + + if ((ret & is_reset) == is_reset) + break; + usleep_range(1000, 2000); + } + if (time_after(jiffies, timeout)) + ret = -ETIMEDOUT; + else + ret = 0; + + return ret; +} + static int mv88e6xxx_power_on_serdes(struct mv88e6xxx_priv_state *ps) { int ret; @@ -2860,6 +2922,8 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) { + int err; + mutex_init(&ps->smi_mutex); INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); @@ -2870,7 +2934,13 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) mv88e6xxx_ppu_state_init(ps); - return 0; + mutex_lock(&ps->smi_mutex); + + err = mv88e6xxx_switch_reset(ps); + + mutex_unlock(&ps->smi_mutex); + + return err; } int mv88e6xxx_setup_global(struct dsa_switch *ds) @@ -3046,71 +3116,6 @@ unlock: return err; } -int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active) -{ - u16 is_reset = (ppu_active ? 0x8800 : 0xc800); - struct gpio_desc *gpiod = ps->ds->pd->reset; - unsigned long timeout; - int ret; - int i; - - mutex_lock(&ps->smi_mutex); - - /* Set all ports to the disabled state. */ - for (i = 0; i < ps->info->num_ports; i++) { - ret = _mv88e6xxx_reg_read(ps, REG_PORT(i), PORT_CONTROL); - if (ret < 0) - goto unlock; - - ret = _mv88e6xxx_reg_write(ps, REG_PORT(i), PORT_CONTROL, - ret & 0xfffc); - if (ret) - goto unlock; - } - - /* Wait for transmit queues to drain. */ - usleep_range(2000, 4000); - - /* If there is a gpio connected to the reset pin, toggle it */ - if (gpiod) { - gpiod_set_value_cansleep(gpiod, 1); - usleep_range(10000, 20000); - gpiod_set_value_cansleep(gpiod, 0); - usleep_range(10000, 20000); - } - - /* Reset the switch. Keep the PPU active if requested. The PPU - * needs to be active to support indirect phy register access - * through global registers 0x18 and 0x19. - */ - if (ppu_active) - ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc000); - else - ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc400); - if (ret) - goto unlock; - - /* Wait up to one second for reset to complete. */ - timeout = jiffies + 1 * HZ; - while (time_before(jiffies, timeout)) { - ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, 0x00); - if (ret < 0) - goto unlock; - - if ((ret & is_reset) == is_reset) - break; - usleep_range(1000, 2000); - } - if (time_after(jiffies, timeout)) - ret = -ETIMEDOUT; - else - ret = 0; -unlock: - mutex_unlock(&ps->smi_mutex); - - return ret; -} - int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 192292f21c8a..efd6ebde8eb4 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -374,6 +374,7 @@ enum mv88e6xxx_cap { * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING. */ MV88E6XXX_CAP_PPU, + MV88E6XXX_CAP_PPU_ACTIVE, /* SMI PHY Command and Data registers. * This requires an indirect access to PHY registers through @@ -412,6 +413,7 @@ enum mv88e6xxx_cap { #define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) #define MV88E6XXX_FLAG_PORTSTATE BIT(MV88E6XXX_CAP_PORTSTATE) #define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) +#define MV88E6XXX_FLAG_PPU_ACTIVE BIT(MV88E6XXX_CAP_PPU_ACTIVE) #define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY) #define MV88E6XXX_FLAG_SWITCH_MAC BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF) #define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP) @@ -446,6 +448,7 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_EEE | \ MV88E6XXX_FLAG_EEPROM | \ MV88E6XXX_FLAG_PORTSTATE | \ + MV88E6XXX_FLAG_PPU_ACTIVE | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ @@ -456,6 +459,7 @@ enum mv88e6xxx_cap { #define MV88E6XXX_FLAGS_FAMILY_6351 \ (MV88E6XXX_FLAG_ATU | \ MV88E6XXX_FLAG_PORTSTATE | \ + MV88E6XXX_FLAG_PPU_ACTIVE | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ @@ -467,6 +471,7 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAG_EEE | \ MV88E6XXX_FLAG_EEPROM | \ MV88E6XXX_FLAG_PORTSTATE | \ + MV88E6XXX_FLAG_PPU_ACTIVE | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ @@ -578,7 +583,6 @@ static inline bool mv88e6xxx_has(struct mv88e6xxx_priv_state *ps, return (ps->info->flags & flags) == flags; } -int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active); const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, int sw_addr, void **priv, const struct mv88e6xxx_info *table, -- cgit v1.2.3 From 08a012619a0349b8e02797bdfe57051fe7df3d3b Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:50 -0400 Subject: net: dsa: mv88e6xxx: factorize global setup Every driver is calling mv88e6xxx_setup_global after mv88e6xxx_setup_common. Call the former in the latter. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 4 -- drivers/net/dsa/mv88e6131.c | 4 -- drivers/net/dsa/mv88e6171.c | 4 -- drivers/net/dsa/mv88e6352.c | 4 -- drivers/net/dsa/mv88e6xxx.c | 109 +++++++++++++++++++++++--------------------- drivers/net/dsa/mv88e6xxx.h | 1 - 6 files changed, 56 insertions(+), 70 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index fadec7a0e6b5..d74695ac0be6 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -58,10 +58,6 @@ static int mv88e6123_setup_global(struct dsa_switch *ds) int ret; u32 reg; - ret = mv88e6xxx_setup_global(ds); - if (ret) - return ret; - /* Disable the PHY polling unit (since there won't be any * external PHYs to poll), don't discard packets with * excessive collisions, and mask all interrupt sources. diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 25ed82372df5..e22ca7b7fa51 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -65,10 +65,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) int ret; u32 reg; - ret = mv88e6xxx_setup_global(ds); - if (ret) - return ret; - /* Enable the PHY polling unit, don't discard packets with * excessive collisions, use a weighted fair queueing scheme * to arbitrate between packet queues, set the maximum frame diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index caaa4b66abc1..4bbf2e1a90aa 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -65,10 +65,6 @@ static int mv88e6171_setup_global(struct dsa_switch *ds) int ret; u32 reg; - ret = mv88e6xxx_setup_global(ds); - if (ret) - return ret; - /* Discard packets with excessive collisions, mask all * interrupt sources, enable PPU. */ diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 470789a3f8ec..3e0be872df95 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -84,10 +84,6 @@ static int mv88e6352_setup_global(struct dsa_switch *ds) int ret; u32 reg; - ret = mv88e6xxx_setup_global(ds); - if (ret) - return ret; - /* Discard packets with excessive collisions, * mask all interrupt sources, enable PPU (bit 14, undocumented). */ diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index b631a5d07ba0..32b36a8fb446 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2920,36 +2920,11 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) return 0; } -int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) +static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) { int err; - - mutex_init(&ps->smi_mutex); - - INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); - - if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) - mutex_init(&ps->eeprom_mutex); - - if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) - mv88e6xxx_ppu_state_init(ps); - - mutex_lock(&ps->smi_mutex); - - err = mv88e6xxx_switch_reset(ps); - - mutex_unlock(&ps->smi_mutex); - - return err; -} - -int mv88e6xxx_setup_global(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int err; int i; - mutex_lock(&ps->smi_mutex); /* Set the default address aging time to 5 minutes, and * enable address learn messages to be sent to all message * ports. @@ -2957,45 +2932,45 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL, 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL); if (err) - goto unlock; + return err; /* Configure the IP ToS mapping registers. */ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); if (err) - goto unlock; + return err; err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); if (err) - goto unlock; + return err; err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); if (err) - goto unlock; + return err; err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); if (err) - goto unlock; + return err; err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); if (err) - goto unlock; + return err; err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); if (err) - goto unlock; + return err; err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); if (err) - goto unlock; + return err; err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); if (err) - goto unlock; + return err; /* Configure the IEEE 802.1p priority mapping register. */ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); if (err) - goto unlock; + return err; /* Send all frames with destination addresses matching * 01:80:c2:00:00:0x to the CPU port. */ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff); if (err) - goto unlock; + return err; /* Ignore removed tag data on doubly tagged packets, disable * flow control messages, force flow control priority to the @@ -3006,15 +2981,15 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 | GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI); if (err) - goto unlock; + return err; /* Program the DSA routing table. */ for (i = 0; i < 32; i++) { int nexthop = 0x1f; - if (ds->pd->rtable && - i != ds->index && i < ds->dst->pd->nr_chips) - nexthop = ds->pd->rtable[i] & 0x1f; + if (ps->ds->pd->rtable && + i != ps->ds->index && i < ps->ds->dst->pd->nr_chips) + nexthop = ps->ds->pd->rtable[i] & 0x1f; err = _mv88e6xxx_reg_write( ps, REG_GLOBAL2, @@ -3022,7 +2997,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) GLOBAL2_DEVICE_MAPPING_UPDATE | (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop); if (err) - goto unlock; + return err; } /* Clear all trunk masks. */ @@ -3032,7 +3007,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) | ((1 << ps->info->num_ports) - 1)); if (err) - goto unlock; + return err; } /* Clear all trunk mappings. */ @@ -3043,7 +3018,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) GLOBAL2_TRUNK_MAPPING_UPDATE | (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); if (err) - goto unlock; + return err; } if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || @@ -3055,7 +3030,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_MGMT_EN_2X, 0xffff); if (err) - goto unlock; + return err; /* Initialise cross-chip port VLAN table to reset * defaults. @@ -3063,7 +3038,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_PVT_ADDR, 0x9000); if (err) - goto unlock; + return err; /* Clear the priority override table. */ for (i = 0; i < 16; i++) { @@ -3071,7 +3046,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) GLOBAL2_PRIO_OVERRIDE, 0x8000 | (i << 8)); if (err) - goto unlock; + return err; } } @@ -3088,7 +3063,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) GLOBAL2_INGRESS_OP, 0x9000 | (i << 8)); if (err) - goto unlock; + return err; } } @@ -3096,20 +3071,48 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP, GLOBAL_STATS_OP_FLUSH_ALL); if (err) - goto unlock; + return err; /* Wait for the flush to complete. */ err = _mv88e6xxx_stats_wait(ps); - if (err < 0) - goto unlock; + if (err) + return err; /* Clear all ATU entries */ err = _mv88e6xxx_atu_flush(ps, 0, true); - if (err < 0) - goto unlock; + if (err) + return err; /* Clear all the VTU and STU entries */ err = _mv88e6xxx_vtu_stu_flush(ps); + if (err < 0) + return err; + + return err; +} + +int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) +{ + int err; + + mutex_init(&ps->smi_mutex); + + INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); + + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) + mutex_init(&ps->eeprom_mutex); + + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) + mv88e6xxx_ppu_state_init(ps); + + mutex_lock(&ps->smi_mutex); + + err = mv88e6xxx_switch_reset(ps); + if (err) + goto unlock; + + err = mv88e6xxx_setup_global(ps); + unlock: mutex_unlock(&ps->smi_mutex); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index efd6ebde8eb4..62f6fc9510aa 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -590,7 +590,6 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, int mv88e6xxx_setup_ports(struct dsa_switch *ds); int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps); -int mv88e6xxx_setup_global(struct dsa_switch *ds); int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg); int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, int reg, u16 val); -- cgit v1.2.3 From 119477bd987cbaf29af10b9cb1b731547906787e Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:51 -0400 Subject: net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup All switch models configure the GLOBAL_CONTROL register with slightly differences. Discarding packets with excessive collisions (GLOBAL_CONTROL_DISCARD_EXCESS) is specific to 6352 and similar switches, and setting a maximum frame size (GLOBAL_CONTROL_MAX_FRAME_1632) is specific to 6185 and similar switches. As we are centralizing the chips setup, skip these settings and don't discard any frames yet, until we found out that such discarding by the hardware is necessary. Assume a common setup to enable the PHY Polling Unit if present, don't discard any packets, and mask all interrupt sources. Tested on 88E6352 and 88E6185. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 8 -------- drivers/net/dsa/mv88e6131.c | 11 ----------- drivers/net/dsa/mv88e6171.c | 9 --------- drivers/net/dsa/mv88e6352.c | 9 --------- drivers/net/dsa/mv88e6xxx.c | 13 +++++++++++++ 5 files changed, 13 insertions(+), 37 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index d74695ac0be6..1cd30ac19c1a 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -58,14 +58,6 @@ static int mv88e6123_setup_global(struct dsa_switch *ds) int ret; u32 reg; - /* Disable the PHY polling unit (since there won't be any - * external PHYs to poll), don't discard packets with - * excessive collisions, and mask all interrupt sources. - */ - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 0x0000); - if (ret) - return ret; - /* Configure the upstream port, and configure the upstream * port as the port to which ingress and egress monitor frames * are to be sent. diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index e22ca7b7fa51..d05fc7980e0c 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -65,17 +65,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) int ret; u32 reg; - /* Enable the PHY polling unit, don't discard packets with - * excessive collisions, use a weighted fair queueing scheme - * to arbitrate between packet queues, set the maximum frame - * size to 1632, and mask all interrupt sources. - */ - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, - GLOBAL_CONTROL_PPU_ENABLE | - GLOBAL_CONTROL_MAX_FRAME_1632); - if (ret) - return ret; - /* Set the VLAN ethertype to 0x8100. */ ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100); if (ret) diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 4bbf2e1a90aa..6c8554ce24e6 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -65,15 +65,6 @@ static int mv88e6171_setup_global(struct dsa_switch *ds) int ret; u32 reg; - /* Discard packets with excessive collisions, mask all - * interrupt sources, enable PPU. - */ - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, - GLOBAL_CONTROL_PPU_ENABLE | - GLOBAL_CONTROL_DISCARD_EXCESS); - if (ret) - return ret; - /* Configure the upstream port, and configure the upstream * port as the port to which ingress and egress monitor frames * are to be sent. diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 3e0be872df95..a27616c00ad6 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -84,15 +84,6 @@ static int mv88e6352_setup_global(struct dsa_switch *ds) int ret; u32 reg; - /* Discard packets with excessive collisions, - * mask all interrupt sources, enable PPU (bit 14, undocumented). - */ - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, - GLOBAL_CONTROL_PPU_ENABLE | - GLOBAL_CONTROL_DISCARD_EXCESS); - if (ret) - return ret; - /* Configure the upstream port, and configure the upstream * port as the port to which ingress and egress monitor frames * are to be sent. diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 32b36a8fb446..f1cd66073bf7 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2922,9 +2922,22 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) { + u16 reg; int err; int i; + /* Enable the PHY Polling Unit if present, don't discard any packets, + * and mask all interrupt sources. + */ + reg = 0; + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU) || + mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE)) + reg |= GLOBAL_CONTROL_PPU_ENABLE; + + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, reg); + if (err) + return err; + /* Set the default address aging time to 5 minutes, and * enable address learn messages to be sent to all message * ports. -- cgit v1.2.3 From 709643aa626ec8f0bd678be79187beefffae32c7 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:52 -0400 Subject: net: dsa: mv88e6131: drop VLAN Ethertype setup The 6131 switch models have a Core Tag Type register. Their setup code is setting it to 0x8100, which is the reset default. Drop this specific part which is correctly configured on reset anyway. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6131.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index d05fc7980e0c..1c3b245cd110 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -65,11 +65,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) int ret; u32 reg; - /* Set the VLAN ethertype to 0x8100. */ - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100); - if (ret) - return ret; - /* Disable ARP mirroring, and configure the upstream port as * the port to which ingress and egress monitor frames are to * be sent. -- cgit v1.2.3 From b0745e87943b40734e6c341dcf47a6ec80ee4346 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:53 -0400 Subject: net: dsa: mv88e6xxx: factorize GLOBAL_MONITOR_CONTROL setup All switch drivers configure the GLOBAL_MONITOR_CONTROL register with slightly changes. Assume the setup of the upstream port, and configure it as the port to which ingress and egress and ARP monitor frames are to be sent. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 14 -------------- drivers/net/dsa/mv88e6131.c | 13 ------------- drivers/net/dsa/mv88e6171.c | 15 --------------- drivers/net/dsa/mv88e6352.c | 14 -------------- drivers/net/dsa/mv88e6xxx.c | 12 ++++++++++++ 5 files changed, 12 insertions(+), 56 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 1cd30ac19c1a..5df06d8c3ed2 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -54,20 +54,6 @@ static const char *mv88e6123_drv_probe(struct device *dsa_dev, static int mv88e6123_setup_global(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - u32 upstream_port = dsa_upstream_port(ds); - int ret; - u32 reg; - - /* Configure the upstream port, and configure the upstream - * port as the port to which ingress and egress monitor frames - * are to be sent. - */ - reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | - upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | - upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); - if (ret) - return ret; /* Disable remote management for now, and set the switch's * DSA device number. diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 1c3b245cd110..c8e3974163dc 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -61,20 +61,7 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev, static int mv88e6131_setup_global(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - u32 upstream_port = dsa_upstream_port(ds); int ret; - u32 reg; - - /* Disable ARP mirroring, and configure the upstream port as - * the port to which ingress and egress monitor frames are to - * be sent. - */ - reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | - upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | - GLOBAL_MONITOR_CONTROL_ARP_DISABLED; - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); - if (ret) - return ret; /* Disable cascade port functionality unless this device * is used in a cascade configuration, and set the switch's diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 6c8554ce24e6..a848aefb4c74 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -61,21 +61,6 @@ static const char *mv88e6171_drv_probe(struct device *dsa_dev, static int mv88e6171_setup_global(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - u32 upstream_port = dsa_upstream_port(ds); - int ret; - u32 reg; - - /* Configure the upstream port, and configure the upstream - * port as the port to which ingress and egress monitor frames - * are to be sent. - */ - reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | - upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | - upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT | - upstream_port << GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT; - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); - if (ret) - return ret; /* Disable remote management for now, and set the switch's * DSA device number. diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index a27616c00ad6..e0988706c882 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -80,20 +80,6 @@ static const char *mv88e6352_drv_probe(struct device *dsa_dev, static int mv88e6352_setup_global(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - u32 upstream_port = dsa_upstream_port(ds); - int ret; - u32 reg; - - /* Configure the upstream port, and configure the upstream - * port as the port to which ingress and egress monitor frames - * are to be sent. - */ - reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | - upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | - upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); - if (ret) - return ret; /* Disable remote management for now, and set the switch's * DSA device number. diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index f1cd66073bf7..27551c1f1cd0 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2922,6 +2922,8 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) { + struct dsa_switch *ds = ps->ds; + u32 upstream_port = dsa_upstream_port(ds); u16 reg; int err; int i; @@ -2938,6 +2940,16 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) if (err) return err; + /* Configure the upstream port, and configure it as the port to which + * ingress and egress and ARP monitor frames are to be sent. + */ + reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | + upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | + upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); + if (err) + return err; + /* Set the default address aging time to 5 minutes, and * enable address learn messages to be sent to all message * ports. -- cgit v1.2.3 From 50484ff4d11c1eca0059f3b3d407ecec0f1b83b0 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:54 -0400 Subject: net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL_2 setup All switch models setup the GLOBAL_CONTROL_2 register with slightly differences. Since the cascade mode is valid even in a single chip setup, factorize such configuration. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 15 --------------- drivers/net/dsa/mv88e6131.c | 16 ---------------- drivers/net/dsa/mv88e6171.c | 15 --------------- drivers/net/dsa/mv88e6352.c | 14 -------------- drivers/net/dsa/mv88e6xxx.c | 7 +++++++ 5 files changed, 7 insertions(+), 60 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 5df06d8c3ed2..8f3a7c55c178 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -51,17 +51,6 @@ static const char *mv88e6123_drv_probe(struct device *dsa_dev, ARRAY_SIZE(mv88e6123_table)); } -static int mv88e6123_setup_global(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - - /* Disable remote management for now, and set the switch's - * DSA device number. - */ - return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, - ds->index & 0x1f); -} - static int mv88e6123_setup(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -73,10 +62,6 @@ static int mv88e6123_setup(struct dsa_switch *ds) if (ret < 0) return ret; - ret = mv88e6123_setup_global(ds); - if (ret < 0) - return ret; - return mv88e6xxx_setup_ports(ds); } diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index c8e3974163dc..b6ca07b9b938 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -61,22 +61,6 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev, static int mv88e6131_setup_global(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - /* Disable cascade port functionality unless this device - * is used in a cascade configuration, and set the switch's - * DSA device number. - */ - if (ds->dst->pd->nr_chips > 1) - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, - GLOBAL_CONTROL_2_MULTIPLE_CASCADE | - (ds->index & 0x1f)); - else - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, - GLOBAL_CONTROL_2_NO_CASCADE | - (ds->index & 0x1f)); - if (ret) - return ret; /* Force the priority of IGMP/MLD snoop frames and ARP frames * to the highest setting. diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index a848aefb4c74..83678adfd97c 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -58,17 +58,6 @@ static const char *mv88e6171_drv_probe(struct device *dsa_dev, ARRAY_SIZE(mv88e6171_table)); } -static int mv88e6171_setup_global(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - - /* Disable remote management for now, and set the switch's - * DSA device number. - */ - return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, - ds->index & 0x1f); -} - static int mv88e6171_setup(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -80,10 +69,6 @@ static int mv88e6171_setup(struct dsa_switch *ds) if (ret < 0) return ret; - ret = mv88e6171_setup_global(ds); - if (ret < 0) - return ret; - return mv88e6xxx_setup_ports(ds); } diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index e0988706c882..81810ddcc47e 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -77,16 +77,6 @@ static const char *mv88e6352_drv_probe(struct device *dsa_dev, ARRAY_SIZE(mv88e6352_table)); } -static int mv88e6352_setup_global(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - - /* Disable remote management for now, and set the switch's - * DSA device number. - */ - return mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x1c, ds->index & 0x1f); -} - static int mv88e6352_setup(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -98,10 +88,6 @@ static int mv88e6352_setup(struct dsa_switch *ds) if (ret < 0) return ret; - ret = mv88e6352_setup_global(ds); - if (ret < 0) - return ret; - return mv88e6xxx_setup_ports(ds); } diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 27551c1f1cd0..d8bb4c8e005f 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2950,6 +2950,13 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) if (err) return err; + /* Disable remote management, and set the switch's DSA device number. */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, + GLOBAL_CONTROL_2_MULTIPLE_CASCADE | + (ds->index & 0x1f)); + if (err) + return err; + /* Set the default address aging time to 5 minutes, and * enable address learn messages to be sent to all message * ports. -- cgit v1.2.3 From 8698fd9595c3b90a76c878159328ac6ebd923963 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:55 -0400 Subject: net: dsa: mv88e6131: drop frames priorities setup 6131 is the only driver which setups the priority of IGMP/MLD snoop frames and ARP frames to the highest setting. Drop such change until we figure out a common configuration for all switch models. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6131.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index b6ca07b9b938..da2832726672 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -58,20 +58,6 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev, ARRAY_SIZE(mv88e6131_table)); } -static int mv88e6131_setup_global(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - - /* Force the priority of IGMP/MLD snoop frames and ARP frames - * to the highest setting. - */ - return mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE, - GLOBAL2_PRIO_OVERRIDE_FORCE_SNOOP | - 7 << GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT | - GLOBAL2_PRIO_OVERRIDE_FORCE_ARP | - 7 << GLOBAL2_PRIO_OVERRIDE_ARP_SHIFT); -} - static int mv88e6131_setup(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -83,10 +69,6 @@ static int mv88e6131_setup(struct dsa_switch *ds) if (ret < 0) return ret; - ret = mv88e6131_setup_global(ds); - if (ret < 0) - return ret; - return mv88e6xxx_setup_ports(ds); } -- cgit v1.2.3 From a1a6a4d1f76aab009e6e0b1003b9c7bca3991e9c Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:56 -0400 Subject: net: dsa: mv88e6xxx: factorize switch setup Provide a shared mv88e6xxx_setup function to the drivers. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 16 +---------- drivers/net/dsa/mv88e6131.c | 16 +---------- drivers/net/dsa/mv88e6171.c | 16 +---------- drivers/net/dsa/mv88e6352.c | 16 +---------- drivers/net/dsa/mv88e6xxx.c | 69 ++++++++++++++++++++++----------------------- drivers/net/dsa/mv88e6xxx.h | 3 +- 6 files changed, 38 insertions(+), 98 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 8f3a7c55c178..2bc407b5632d 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -51,24 +51,10 @@ static const char *mv88e6123_drv_probe(struct device *dsa_dev, ARRAY_SIZE(mv88e6123_table)); } -static int mv88e6123_setup(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - ps->ds = ds; - - ret = mv88e6xxx_setup_common(ps); - if (ret < 0) - return ret; - - return mv88e6xxx_setup_ports(ds); -} - struct dsa_switch_driver mv88e6123_switch_driver = { .tag_protocol = DSA_TAG_PROTO_EDSA, .probe = mv88e6123_drv_probe, - .setup = mv88e6123_setup, + .setup = mv88e6xxx_setup, .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index da2832726672..22952be7f4de 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -58,24 +58,10 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev, ARRAY_SIZE(mv88e6131_table)); } -static int mv88e6131_setup(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - ps->ds = ds; - - ret = mv88e6xxx_setup_common(ps); - if (ret < 0) - return ret; - - return mv88e6xxx_setup_ports(ds); -} - struct dsa_switch_driver mv88e6131_switch_driver = { .tag_protocol = DSA_TAG_PROTO_DSA, .probe = mv88e6131_drv_probe, - .setup = mv88e6131_setup, + .setup = mv88e6xxx_setup, .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 83678adfd97c..4bf517a86acb 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -58,24 +58,10 @@ static const char *mv88e6171_drv_probe(struct device *dsa_dev, ARRAY_SIZE(mv88e6171_table)); } -static int mv88e6171_setup(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - ps->ds = ds; - - ret = mv88e6xxx_setup_common(ps); - if (ret < 0) - return ret; - - return mv88e6xxx_setup_ports(ds); -} - struct dsa_switch_driver mv88e6171_switch_driver = { .tag_protocol = DSA_TAG_PROTO_EDSA, .probe = mv88e6171_drv_probe, - .setup = mv88e6171_setup, + .setup = mv88e6xxx_setup, .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 81810ddcc47e..d65a90dca0b4 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -77,24 +77,10 @@ static const char *mv88e6352_drv_probe(struct device *dsa_dev, ARRAY_SIZE(mv88e6352_table)); } -static int mv88e6352_setup(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - ps->ds = ds; - - ret = mv88e6xxx_setup_common(ps); - if (ret < 0) - return ret; - - return mv88e6xxx_setup_ports(ds); -} - struct dsa_switch_driver mv88e6352_switch_driver = { .tag_protocol = DSA_TAG_PROTO_EDSA, .probe = mv88e6352_drv_probe, - .setup = mv88e6352_setup, + .setup = mv88e6xxx_setup, .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, .phy_write = mv88e6xxx_phy_write, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index d8bb4c8e005f..7ea30502d221 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2640,14 +2640,12 @@ static int mv88e6xxx_power_on_serdes(struct mv88e6xxx_priv_state *ps) return ret; } -static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) +static int mv88e6xxx_setup_port(struct mv88e6xxx_priv_state *ps, int port) { - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + struct dsa_switch *ds = ps->ds; int ret; u16 reg; - mutex_lock(&ps->smi_mutex); - if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) || @@ -2676,7 +2674,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_PCS_CTRL, reg); if (ret) - goto abort; + return ret; } /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock, @@ -2740,7 +2738,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL, reg); if (ret) - goto abort; + return ret; } /* If this port is connected to a SerDes, make sure the SerDes is not @@ -2749,14 +2747,14 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) if (mv88e6xxx_6352_family(ps)) { ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_STATUS); if (ret < 0) - goto abort; + return ret; ret &= PORT_STATUS_CMODE_MASK; if ((ret == PORT_STATUS_CMODE_100BASE_X) || (ret == PORT_STATUS_CMODE_1000BASE_X) || (ret == PORT_STATUS_CMODE_SGMII)) { ret = mv88e6xxx_power_on_serdes(ps); if (ret < 0) - goto abort; + return ret; } } @@ -2793,7 +2791,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_2, reg); if (ret) - goto abort; + return ret; } /* Port Association Vector: when learning source addresses @@ -2808,13 +2806,13 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_ASSOC_VECTOR, reg); if (ret) - goto abort; + return ret; /* Egress rate control 2: disable egress rate control. */ ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_RATE_CONTROL_2, 0x0000); if (ret) - goto abort; + return ret; if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || @@ -2826,7 +2824,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_PAUSE_CTRL, 0x0000); if (ret) - goto abort; + return ret; /* Port ATU control: disable limiting the number of * address database entries that this port is allowed @@ -2840,7 +2838,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_PRI_OVERRIDE, 0x0000); if (ret) - goto abort; + return ret; /* Port Ethertype: use the Ethertype DSA Ethertype * value. @@ -2848,14 +2846,14 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_ETH_TYPE, ETH_P_EDSA); if (ret) - goto abort; + return ret; /* Tag Remap: use an identity 802.1p prio -> switch * prio mapping. */ ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_TAG_REGMAP_0123, 0x3210); if (ret) - goto abort; + return ret; /* Tag Remap 2: use an identity 802.1p prio -> switch * prio mapping. @@ -2863,7 +2861,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_TAG_REGMAP_4567, 0x7654); if (ret) - goto abort; + return ret; } if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || @@ -2874,7 +2872,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_RATE_CONTROL, 0x0001); if (ret) - goto abort; + return ret; } /* Port Control 1: disable trunking, disable sending @@ -2882,7 +2880,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) */ ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_1, 0x0000); if (ret) - goto abort; + return ret; /* Port based VLAN map: give each port the same default address * database, and allow bidirectional communication between the @@ -2890,33 +2888,20 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) */ ret = _mv88e6xxx_port_fid_set(ps, port, 0); if (ret) - goto abort; + return ret; ret = _mv88e6xxx_port_based_vlan_map(ps, port); if (ret) - goto abort; + return ret; /* Default VLAN ID and priority: don't set a default VLAN * ID, and set the default packet priority to zero. */ ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_DEFAULT_VLAN, 0x0000); -abort: - mutex_unlock(&ps->smi_mutex); - return ret; -} - -int mv88e6xxx_setup_ports(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - int i; + if (ret) + return ret; - for (i = 0; i < ps->info->num_ports; i++) { - ret = mv88e6xxx_setup_port(ds, i); - if (ret < 0) - return ret; - } return 0; } @@ -3123,9 +3108,13 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) return err; } -int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) +int mv88e6xxx_setup(struct dsa_switch *ds) { + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int err; + int i; + + ps->ds = ds; mutex_init(&ps->smi_mutex); @@ -3144,6 +3133,14 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) goto unlock; err = mv88e6xxx_setup_global(ps); + if (err) + goto unlock; + + for (i = 0; i < ps->info->num_ports; i++) { + err = mv88e6xxx_setup_port(ps, i); + if (err) + goto unlock; + } unlock: mutex_unlock(&ps->smi_mutex); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 62f6fc9510aa..a131827cb26d 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -588,8 +588,7 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, const struct mv88e6xxx_info *table, unsigned int num); -int mv88e6xxx_setup_ports(struct dsa_switch *ds); -int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps); +int mv88e6xxx_setup(struct dsa_switch *ds); int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg); int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, int reg, u16 val); -- cgit v1.2.3 From b9729e53ade9be2637b46ac98fd85c7eac1b77c8 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:57 -0400 Subject: net: dsa: mv88e6131: use EDSA tag protocol 6131 is the only driver to set the tag protocol to DSA_TAG_PROTO_DSA. Since it works fine with DSA_TAG_PROTO_EDSA, change its value, like all other mv88e6xxx drivers. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/Kconfig | 2 +- drivers/net/dsa/mv88e6131.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 4aaadced6b81..7e01dce09904 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -17,7 +17,7 @@ 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_TAG_DSA + select NET_DSA_TAG_EDSA ---help--- This enables support for the Marvell 88E6085/6095/6095F/6131 ethernet switch chips. diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 22952be7f4de..bbad199b50aa 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -59,7 +59,7 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev, } struct dsa_switch_driver mv88e6131_switch_driver = { - .tag_protocol = DSA_TAG_PROTO_DSA, + .tag_protocol = DSA_TAG_PROTO_EDSA, .probe = mv88e6131_drv_probe, .setup = mv88e6xxx_setup, .set_addr = mv88e6xxx_set_addr, -- cgit v1.2.3 From f81ec90fe9cbf512f3c632130a37c6d353fa94ea Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:58 -0400 Subject: net: dsa: mv88e6xxx: factorize the switch driver Now that all drivers support the same set of functions and the same setup code, drop every model-specific DSA switch driver and replace them with a common mv88e6xxx driver. This merges the info tables into one, removes the function exports, the model-specific files, and update the defconfigs. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- arch/arm/configs/multi_v5_defconfig | 5 +- arch/arm/configs/mvebu_v7_defconfig | 2 +- arch/arm/configs/orion5x_defconfig | 3 +- arch/tile/configs/tilegx_defconfig | 3 +- arch/tile/configs/tilepro_defconfig | 3 +- drivers/net/dsa/Kconfig | 40 +--- drivers/net/dsa/Makefile | 15 +- drivers/net/dsa/mv88e6123.c | 93 ---------- drivers/net/dsa/mv88e6131.c | 101 ---------- drivers/net/dsa/mv88e6171.c | 101 ---------- drivers/net/dsa/mv88e6352.c | 121 ------------ drivers/net/dsa/mv88e6xxx.c | 354 +++++++++++++++++++++++++++--------- drivers/net/dsa/mv88e6xxx.h | 91 +++------ 13 files changed, 302 insertions(+), 630 deletions(-) delete mode 100644 drivers/net/dsa/mv88e6123.c delete mode 100644 drivers/net/dsa/mv88e6131.c delete mode 100644 drivers/net/dsa/mv88e6171.c delete mode 100644 drivers/net/dsa/mv88e6352.c diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig index e11d99d529ee..690352d3ba4c 100644 --- a/arch/arm/configs/multi_v5_defconfig +++ b/arch/arm/configs/multi_v5_defconfig @@ -91,10 +91,7 @@ CONFIG_SATA_AHCI=y CONFIG_SATA_MV=y CONFIG_NETDEVICES=y CONFIG_NET_DSA_MV88E6060=y -CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123=y -CONFIG_NET_DSA_MV88E6171=y -CONFIG_NET_DSA_MV88E6352=y +CONFIG_NET_DSA_MV88E6XXX=y CONFIG_MV643XX_ETH=y CONFIG_R8169=y CONFIG_MARVELL_PHY=y diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig index dc5797a2efab..6492407efd7e 100644 --- a/arch/arm/configs/mvebu_v7_defconfig +++ b/arch/arm/configs/mvebu_v7_defconfig @@ -66,7 +66,7 @@ CONFIG_SATA_AHCI=y CONFIG_AHCI_MVEBU=y CONFIG_SATA_MV=y CONFIG_NETDEVICES=y -CONFIG_NET_DSA_MV88E6171=y +CONFIG_NET_DSA_MV88E6XXX=y CONFIG_MV643XX_ETH=y CONFIG_MVNETA=y CONFIG_MVPP2=y diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 6a5bc27538f1..27a70a7a50f6 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig @@ -85,8 +85,7 @@ CONFIG_ATA=y CONFIG_SATA_MV=y CONFIG_NETDEVICES=y CONFIG_MII=y -CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123=y +CONFIG_NET_DSA_MV88E6XXX=y CONFIG_MV643XX_ETH=y CONFIG_MARVELL_PHY=y # CONFIG_INPUT_MOUSEDEV is not set diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index 3f3dfb8b150a..718905557f7e 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig @@ -221,8 +221,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_TUN=y CONFIG_VETH=m CONFIG_NET_DSA_MV88E6060=y -CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123=y +CONFIG_NET_DSA_MV88E6XXX=y CONFIG_SKY2=y CONFIG_PTP_1588_CLOCK_TILEGX=y # CONFIG_WLAN is not set diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index ef9e27eb2f50..dc85468afd5e 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig @@ -340,8 +340,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_TUN=y CONFIG_VETH=m CONFIG_NET_DSA_MV88E6060=y -CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123=y +CONFIG_NET_DSA_MV88E6XXX=y # CONFIG_NET_VENDOR_3COM is not set CONFIG_E1000E=y # CONFIG_WLAN is not set diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 7e01dce09904..200663c43ce9 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -1,10 +1,6 @@ menu "Distributed Switch Architecture drivers" depends on HAVE_NET_DSA -config NET_DSA_MV88E6XXX - tristate - default n - config NET_DSA_MV88E6060 tristate "Marvell 88E6060 ethernet switch chip support" depends on NET_DSA @@ -13,41 +9,13 @@ config NET_DSA_MV88E6060 This enables support for the Marvell 88E6060 ethernet switch chip. -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_TAG_EDSA - ---help--- - This enables support for the Marvell 88E6085/6095/6095F/6131 - ethernet switch chips. - -config NET_DSA_MV88E6123 - tristate "Marvell 88E6123/6161/6165 ethernet switch chip support" - depends on NET_DSA - select NET_DSA_MV88E6XXX - select NET_DSA_TAG_EDSA - ---help--- - This enables support for the Marvell 88E6123/6161/6165 - ethernet switch chips. - -config NET_DSA_MV88E6171 - tristate "Marvell 88E6171/6175/6350/6351 ethernet switch chip support" - depends on NET_DSA - select NET_DSA_MV88E6XXX - select NET_DSA_TAG_EDSA - ---help--- - This enables support for the Marvell 88E6171/6175/6350/6351 - ethernet switches chips. - -config NET_DSA_MV88E6352 - tristate "Marvell 88E6172/6176/6320/6321/6352 ethernet switch chip support" +config NET_DSA_MV88E6XXX + tristate "Marvell 88E6xxx Ethernet switch chip support" depends on NET_DSA - select NET_DSA_MV88E6XXX select NET_DSA_TAG_EDSA ---help--- - This enables support for the Marvell 88E6172, 88E6176, 88E6320, - 88E6321 and 88E6352 ethernet switch chips. + This enables support for most of the Marvell 88E6xxx models of + Ethernet switch chips, except 88E6060. config NET_DSA_BCM_SF2 tristate "Broadcom Starfighter 2 Ethernet switch support" diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile index a6e09939be65..76b751dd9efd 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile @@ -1,16 +1,3 @@ obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o -obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o -mv88e6xxx_drv-y += mv88e6xxx.o -ifdef CONFIG_NET_DSA_MV88E6123 -mv88e6xxx_drv-y += mv88e6123.o -endif -ifdef CONFIG_NET_DSA_MV88E6131 -mv88e6xxx_drv-y += mv88e6131.o -endif -ifdef CONFIG_NET_DSA_MV88E6352 -mv88e6xxx_drv-y += mv88e6352.o -endif -ifdef CONFIG_NET_DSA_MV88E6171 -mv88e6xxx_drv-y += mv88e6171.o -endif +obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm_sf2.o diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c deleted file mode 100644 index 2bc407b5632d..000000000000 --- a/drivers/net/dsa/mv88e6123.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support - * Copyright (c) 2008-2009 Marvell Semiconductor - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "mv88e6xxx.h" - -static const struct mv88e6xxx_info mv88e6123_table[] = { - { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6123, - .family = MV88E6XXX_FAMILY_6165, - .name = "Marvell 88E6123", - .num_databases = 4096, - .num_ports = 3, - .flags = MV88E6XXX_FLAGS_FAMILY_6165, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6161, - .family = MV88E6XXX_FAMILY_6165, - .name = "Marvell 88E6161", - .num_databases = 4096, - .num_ports = 6, - .flags = MV88E6XXX_FLAGS_FAMILY_6165, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6165, - .family = MV88E6XXX_FAMILY_6165, - .name = "Marvell 88E6165", - .num_databases = 4096, - .num_ports = 6, - .flags = MV88E6XXX_FLAGS_FAMILY_6165, - } -}; - -static const char *mv88e6123_drv_probe(struct device *dsa_dev, - struct device *host_dev, int sw_addr, - void **priv) -{ - return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, - mv88e6123_table, - ARRAY_SIZE(mv88e6123_table)); -} - -struct dsa_switch_driver mv88e6123_switch_driver = { - .tag_protocol = DSA_TAG_PROTO_EDSA, - .probe = mv88e6123_drv_probe, - .setup = mv88e6xxx_setup, - .set_addr = mv88e6xxx_set_addr, - .phy_read = mv88e6xxx_phy_read, - .phy_write = mv88e6xxx_phy_write, - .set_eee = mv88e6xxx_set_eee, - .get_eee = mv88e6xxx_get_eee, - .get_strings = mv88e6xxx_get_strings, - .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, - .get_sset_count = mv88e6xxx_get_sset_count, - .adjust_link = mv88e6xxx_adjust_link, -#ifdef CONFIG_NET_DSA_HWMON - .get_temp = mv88e6xxx_get_temp, - .get_temp_limit = mv88e6xxx_get_temp_limit, - .set_temp_limit = mv88e6xxx_set_temp_limit, - .get_temp_alarm = mv88e6xxx_get_temp_alarm, -#endif - .get_eeprom = mv88e6xxx_get_eeprom, - .set_eeprom = mv88e6xxx_set_eeprom, - .get_regs_len = mv88e6xxx_get_regs_len, - .get_regs = mv88e6xxx_get_regs, - .port_bridge_join = mv88e6xxx_port_bridge_join, - .port_bridge_leave = mv88e6xxx_port_bridge_leave, - .port_stp_state_set = mv88e6xxx_port_stp_state_set, - .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, - .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, - .port_vlan_add = mv88e6xxx_port_vlan_add, - .port_vlan_del = mv88e6xxx_port_vlan_del, - .port_vlan_dump = mv88e6xxx_port_vlan_dump, - .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, - .port_fdb_add = mv88e6xxx_port_fdb_add, - .port_fdb_del = mv88e6xxx_port_fdb_del, - .port_fdb_dump = mv88e6xxx_port_fdb_dump, -}; - -MODULE_ALIAS("platform:mv88e6123"); -MODULE_ALIAS("platform:mv88e6161"); -MODULE_ALIAS("platform:mv88e6165"); diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c deleted file mode 100644 index bbad199b50aa..000000000000 --- a/drivers/net/dsa/mv88e6131.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * net/dsa/mv88e6131.c - Marvell 88e6095/6095f/6131 switch chip support - * Copyright (c) 2008-2009 Marvell Semiconductor - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "mv88e6xxx.h" - -static const struct mv88e6xxx_info mv88e6131_table[] = { - { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6095, - .family = MV88E6XXX_FAMILY_6095, - .name = "Marvell 88E6095/88E6095F", - .num_databases = 256, - .num_ports = 11, - .flags = MV88E6XXX_FLAGS_FAMILY_6095, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6085, - .family = MV88E6XXX_FAMILY_6097, - .name = "Marvell 88E6085", - .num_databases = 4096, - .num_ports = 10, - .flags = MV88E6XXX_FLAGS_FAMILY_6097, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6131, - .family = MV88E6XXX_FAMILY_6185, - .name = "Marvell 88E6131", - .num_databases = 256, - .num_ports = 8, - .flags = MV88E6XXX_FLAGS_FAMILY_6185, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6185, - .family = MV88E6XXX_FAMILY_6185, - .name = "Marvell 88E6185", - .num_databases = 256, - .num_ports = 10, - .flags = MV88E6XXX_FLAGS_FAMILY_6185, - } -}; - -static const char *mv88e6131_drv_probe(struct device *dsa_dev, - struct device *host_dev, int sw_addr, - void **priv) -{ - return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, - mv88e6131_table, - ARRAY_SIZE(mv88e6131_table)); -} - -struct dsa_switch_driver mv88e6131_switch_driver = { - .tag_protocol = DSA_TAG_PROTO_EDSA, - .probe = mv88e6131_drv_probe, - .setup = mv88e6xxx_setup, - .set_addr = mv88e6xxx_set_addr, - .phy_read = mv88e6xxx_phy_read, - .phy_write = mv88e6xxx_phy_write, - .set_eee = mv88e6xxx_set_eee, - .get_eee = mv88e6xxx_get_eee, - .get_strings = mv88e6xxx_get_strings, - .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, - .get_sset_count = mv88e6xxx_get_sset_count, - .get_eeprom = mv88e6xxx_get_eeprom, - .set_eeprom = mv88e6xxx_set_eeprom, - .get_regs_len = mv88e6xxx_get_regs_len, - .get_regs = mv88e6xxx_get_regs, -#ifdef CONFIG_NET_DSA_HWMON - .get_temp = mv88e6xxx_get_temp, - .get_temp_limit = mv88e6xxx_get_temp_limit, - .set_temp_limit = mv88e6xxx_set_temp_limit, - .get_temp_alarm = mv88e6xxx_get_temp_alarm, -#endif - .adjust_link = mv88e6xxx_adjust_link, - .port_bridge_join = mv88e6xxx_port_bridge_join, - .port_bridge_leave = mv88e6xxx_port_bridge_leave, - .port_stp_state_set = mv88e6xxx_port_stp_state_set, - .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, - .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, - .port_vlan_add = mv88e6xxx_port_vlan_add, - .port_vlan_del = mv88e6xxx_port_vlan_del, - .port_vlan_dump = mv88e6xxx_port_vlan_dump, - .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, - .port_fdb_add = mv88e6xxx_port_fdb_add, - .port_fdb_del = mv88e6xxx_port_fdb_del, - .port_fdb_dump = mv88e6xxx_port_fdb_dump, -}; - -MODULE_ALIAS("platform:mv88e6085"); -MODULE_ALIAS("platform:mv88e6095"); -MODULE_ALIAS("platform:mv88e6095f"); -MODULE_ALIAS("platform:mv88e6131"); diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c deleted file mode 100644 index 4bf517a86acb..000000000000 --- a/drivers/net/dsa/mv88e6171.c +++ /dev/null @@ -1,101 +0,0 @@ -/* net/dsa/mv88e6171.c - Marvell 88e6171 switch chip support - * Copyright (c) 2008-2009 Marvell Semiconductor - * Copyright (c) 2014 Claudio Leite - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "mv88e6xxx.h" - -static const struct mv88e6xxx_info mv88e6171_table[] = { - { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6171, - .family = MV88E6XXX_FAMILY_6351, - .name = "Marvell 88E6171", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6351, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6175, - .family = MV88E6XXX_FAMILY_6351, - .name = "Marvell 88E6175", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6351, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6350, - .family = MV88E6XXX_FAMILY_6351, - .name = "Marvell 88E6350", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6351, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6351, - .family = MV88E6XXX_FAMILY_6351, - .name = "Marvell 88E6351", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6351, - } -}; - -static const char *mv88e6171_drv_probe(struct device *dsa_dev, - struct device *host_dev, int sw_addr, - void **priv) -{ - return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, - mv88e6171_table, - ARRAY_SIZE(mv88e6171_table)); -} - -struct dsa_switch_driver mv88e6171_switch_driver = { - .tag_protocol = DSA_TAG_PROTO_EDSA, - .probe = mv88e6171_drv_probe, - .setup = mv88e6xxx_setup, - .set_addr = mv88e6xxx_set_addr, - .phy_read = mv88e6xxx_phy_read, - .phy_write = mv88e6xxx_phy_write, - .set_eee = mv88e6xxx_set_eee, - .get_eee = mv88e6xxx_get_eee, - .get_strings = mv88e6xxx_get_strings, - .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, - .get_sset_count = mv88e6xxx_get_sset_count, - .adjust_link = mv88e6xxx_adjust_link, -#ifdef CONFIG_NET_DSA_HWMON - .get_temp = mv88e6xxx_get_temp, - .get_temp_limit = mv88e6xxx_get_temp_limit, - .set_temp_limit = mv88e6xxx_set_temp_limit, - .get_temp_alarm = mv88e6xxx_get_temp_alarm, -#endif - .get_eeprom = mv88e6xxx_get_eeprom, - .set_eeprom = mv88e6xxx_set_eeprom, - .get_regs_len = mv88e6xxx_get_regs_len, - .get_regs = mv88e6xxx_get_regs, - .port_bridge_join = mv88e6xxx_port_bridge_join, - .port_bridge_leave = mv88e6xxx_port_bridge_leave, - .port_stp_state_set = mv88e6xxx_port_stp_state_set, - .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, - .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, - .port_vlan_add = mv88e6xxx_port_vlan_add, - .port_vlan_del = mv88e6xxx_port_vlan_del, - .port_vlan_dump = mv88e6xxx_port_vlan_dump, - .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, - .port_fdb_add = mv88e6xxx_port_fdb_add, - .port_fdb_del = mv88e6xxx_port_fdb_del, - .port_fdb_dump = mv88e6xxx_port_fdb_dump, -}; - -MODULE_ALIAS("platform:mv88e6171"); -MODULE_ALIAS("platform:mv88e6175"); -MODULE_ALIAS("platform:mv88e6350"); -MODULE_ALIAS("platform:mv88e6351"); diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c deleted file mode 100644 index d65a90dca0b4..000000000000 --- a/drivers/net/dsa/mv88e6352.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * net/dsa/mv88e6352.c - Marvell 88e6352 switch chip support - * - * Copyright (c) 2014 Guenter Roeck - * - * Derived from mv88e6123_61_65.c - * Copyright (c) 2008-2009 Marvell Semiconductor - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "mv88e6xxx.h" - -static const struct mv88e6xxx_info mv88e6352_table[] = { - { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6320, - .family = MV88E6XXX_FAMILY_6320, - .name = "Marvell 88E6320", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6320, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6321, - .family = MV88E6XXX_FAMILY_6320, - .name = "Marvell 88E6321", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6320, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6172, - .family = MV88E6XXX_FAMILY_6352, - .name = "Marvell 88E6172", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6352, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6176, - .family = MV88E6XXX_FAMILY_6352, - .name = "Marvell 88E6176", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6352, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6240, - .family = MV88E6XXX_FAMILY_6352, - .name = "Marvell 88E6240", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6352, - }, { - .prod_num = PORT_SWITCH_ID_PROD_NUM_6352, - .family = MV88E6XXX_FAMILY_6352, - .name = "Marvell 88E6352", - .num_databases = 4096, - .num_ports = 7, - .flags = MV88E6XXX_FLAGS_FAMILY_6352, - } -}; - -static const char *mv88e6352_drv_probe(struct device *dsa_dev, - struct device *host_dev, int sw_addr, - void **priv) -{ - return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, - mv88e6352_table, - ARRAY_SIZE(mv88e6352_table)); -} - -struct dsa_switch_driver mv88e6352_switch_driver = { - .tag_protocol = DSA_TAG_PROTO_EDSA, - .probe = mv88e6352_drv_probe, - .setup = mv88e6xxx_setup, - .set_addr = mv88e6xxx_set_addr, - .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, - .adjust_link = mv88e6xxx_adjust_link, - .set_eee = mv88e6xxx_set_eee, - .get_eee = mv88e6xxx_get_eee, -#ifdef CONFIG_NET_DSA_HWMON - .get_temp = mv88e6xxx_get_temp, - .get_temp_limit = mv88e6xxx_get_temp_limit, - .set_temp_limit = mv88e6xxx_set_temp_limit, - .get_temp_alarm = mv88e6xxx_get_temp_alarm, -#endif - .get_eeprom = mv88e6xxx_get_eeprom, - .set_eeprom = mv88e6xxx_set_eeprom, - .get_regs_len = mv88e6xxx_get_regs_len, - .get_regs = mv88e6xxx_get_regs, - .port_bridge_join = mv88e6xxx_port_bridge_join, - .port_bridge_leave = mv88e6xxx_port_bridge_leave, - .port_stp_state_set = mv88e6xxx_port_stp_state_set, - .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, - .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, - .port_vlan_add = mv88e6xxx_port_vlan_add, - .port_vlan_del = mv88e6xxx_port_vlan_del, - .port_vlan_dump = mv88e6xxx_port_vlan_dump, - .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, - .port_fdb_add = mv88e6xxx_port_fdb_add, - .port_fdb_del = mv88e6xxx_port_fdb_del, - .port_fdb_dump = mv88e6xxx_port_fdb_dump, -}; - -MODULE_ALIAS("platform:mv88e6172"); -MODULE_ALIAS("platform:mv88e6176"); -MODULE_ALIAS("platform:mv88e6320"); -MODULE_ALIAS("platform:mv88e6321"); -MODULE_ALIAS("platform:mv88e6352"); diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 7ea30502d221..1e5ca8e0f48e 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -467,8 +467,8 @@ static bool mv88e6xxx_has_stu(struct mv88e6xxx_priv_state *ps) * phy. However, in the case of a fixed link phy, we force the port * settings from the fixed link settings. */ -void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, - struct phy_device *phydev) +static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, + struct phy_device *phydev) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); u32 reg; @@ -714,7 +714,8 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_priv_state *ps, return value; } -void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data) +static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, + uint8_t *data) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_hw_stat *stat; @@ -730,7 +731,7 @@ void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data) } } -int mv88e6xxx_get_sset_count(struct dsa_switch *ds) +static int mv88e6xxx_get_sset_count(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_hw_stat *stat; @@ -744,9 +745,8 @@ int mv88e6xxx_get_sset_count(struct dsa_switch *ds) return j; } -void -mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, - int port, uint64_t *data) +static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port, + uint64_t *data) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_hw_stat *stat; @@ -771,13 +771,13 @@ mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, mutex_unlock(&ps->smi_mutex); } -int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port) +static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port) { return 32 * sizeof(u16); } -void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, - struct ethtool_regs *regs, void *_p) +static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, + struct ethtool_regs *regs, void *_p) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); u16 *p = _p; @@ -876,8 +876,8 @@ error: return ret; } -int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, - u8 *data) +static int mv88e6xxx_get_eeprom(struct dsa_switch *ds, + struct ethtool_eeprom *eeprom, u8 *data) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int offset; @@ -982,8 +982,8 @@ error: return ret; } -int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, - u8 *data) +static int mv88e6xxx_set_eeprom(struct dsa_switch *ds, + struct ethtool_eeprom *eeprom, u8 *data) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int offset; @@ -1104,7 +1104,8 @@ static int _mv88e6xxx_phy_write_indirect(struct mv88e6xxx_priv_state *ps, return _mv88e6xxx_phy_wait(ps); } -int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) +static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, + struct ethtool_eee *e) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int reg; @@ -1133,8 +1134,8 @@ out: return reg; } -int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, - struct phy_device *phydev, struct ethtool_eee *e) +static int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, + struct phy_device *phydev, struct ethtool_eee *e) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int reg; @@ -1364,7 +1365,8 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_priv_state *ps, return _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_BASE_VLAN, reg); } -void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) +static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, + u8 state) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int stp_state; @@ -1587,9 +1589,9 @@ static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_priv_state *ps, return 0; } -int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, - struct switchdev_obj_port_vlan *vlan, - int (*cb)(struct switchdev_obj *obj)) +static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, + struct switchdev_obj_port_vlan *vlan, + int (*cb)(struct switchdev_obj *obj)) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_vtu_stu_entry next; @@ -2014,8 +2016,8 @@ static const char * const mv88e6xxx_port_8021q_mode_names[] = { [PORT_CONTROL_2_8021Q_SECURE] = "Secure", }; -int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, - bool vlan_filtering) +static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, + bool vlan_filtering) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); u16 old, new = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE : @@ -2054,9 +2056,9 @@ unlock: return ret; } -int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct switchdev_trans *trans) +static int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct switchdev_trans *trans) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int err; @@ -2095,9 +2097,9 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_priv_state *ps, int port, return _mv88e6xxx_vtu_loadpurge(ps, &vlan); } -void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct switchdev_trans *trans) +static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct switchdev_trans *trans) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; @@ -2157,8 +2159,8 @@ static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_priv_state *ps, return _mv88e6xxx_atu_remove(ps, vlan.fid, port, false); } -int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan) +static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); u16 pvid, vid; @@ -2271,9 +2273,9 @@ static int _mv88e6xxx_port_fdb_load(struct mv88e6xxx_priv_state *ps, int port, return _mv88e6xxx_atu_load(ps, &entry); } -int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb, - struct switchdev_trans *trans) +static int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_fdb *fdb, + struct switchdev_trans *trans) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -2286,9 +2288,9 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, return 0; } -void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb, - struct switchdev_trans *trans) +static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_fdb *fdb, + struct switchdev_trans *trans) { int state = is_multicast_ether_addr(fdb->addr) ? GLOBAL_ATU_DATA_STATE_MC_STATIC : @@ -2304,8 +2306,8 @@ void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, mutex_unlock(&ps->smi_mutex); } -int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb) +static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_fdb *fdb) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int ret; @@ -2407,9 +2409,9 @@ static int _mv88e6xxx_port_fdb_dump_one(struct mv88e6xxx_priv_state *ps, return err; } -int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, - struct switchdev_obj_port_fdb *fdb, - int (*cb)(struct switchdev_obj *obj)) +static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, + struct switchdev_obj_port_fdb *fdb, + int (*cb)(struct switchdev_obj *obj)) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_vtu_stu_entry vlan = { @@ -2457,8 +2459,8 @@ unlock: return err; } -int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, - struct net_device *bridge) +static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, + struct net_device *bridge) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int i, err = 0; @@ -2484,7 +2486,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, return err; } -void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) +static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct net_device *bridge = ps->ports[port].bridge_dev; @@ -3108,7 +3110,7 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) return err; } -int mv88e6xxx_setup(struct dsa_switch *ds) +static int mv88e6xxx_setup(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int err; @@ -3181,8 +3183,7 @@ static int mv88e6xxx_port_to_phy_addr(struct mv88e6xxx_priv_state *ps, return -EINVAL; } -int -mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum) +static int mv88e6xxx_phy_read(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); @@ -3204,8 +3205,8 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum) return ret; } -int -mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) +static int mv88e6xxx_phy_write(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); @@ -3291,7 +3292,7 @@ static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp) return 0; } -int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) +static int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -3304,7 +3305,7 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) return mv88e61xx_get_temp(ds, temp); } -int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) +static int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; @@ -3324,7 +3325,7 @@ int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) return 0; } -int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) +static int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; @@ -3341,7 +3342,7 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) (ret & 0xe0ff) | (temp << 8)); } -int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm) +static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; @@ -3362,6 +3363,161 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm) } #endif /* CONFIG_NET_DSA_HWMON */ +static const struct mv88e6xxx_info mv88e6xxx_table[] = { + [MV88E6085] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6085, + .family = MV88E6XXX_FAMILY_6097, + .name = "Marvell 88E6085", + .num_databases = 4096, + .num_ports = 10, + .flags = MV88E6XXX_FLAGS_FAMILY_6097, + }, + + [MV88E6095] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6095, + .family = MV88E6XXX_FAMILY_6095, + .name = "Marvell 88E6095/88E6095F", + .num_databases = 256, + .num_ports = 11, + .flags = MV88E6XXX_FLAGS_FAMILY_6095, + }, + + [MV88E6123] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6123, + .family = MV88E6XXX_FAMILY_6165, + .name = "Marvell 88E6123", + .num_databases = 4096, + .num_ports = 3, + .flags = MV88E6XXX_FLAGS_FAMILY_6165, + }, + + [MV88E6131] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6131, + .family = MV88E6XXX_FAMILY_6185, + .name = "Marvell 88E6131", + .num_databases = 256, + .num_ports = 8, + .flags = MV88E6XXX_FLAGS_FAMILY_6185, + }, + + [MV88E6161] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6161, + .family = MV88E6XXX_FAMILY_6165, + .name = "Marvell 88E6161", + .num_databases = 4096, + .num_ports = 6, + .flags = MV88E6XXX_FLAGS_FAMILY_6165, + }, + + [MV88E6165] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6165, + .family = MV88E6XXX_FAMILY_6165, + .name = "Marvell 88E6165", + .num_databases = 4096, + .num_ports = 6, + .flags = MV88E6XXX_FLAGS_FAMILY_6165, + }, + + [MV88E6171] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6171, + .family = MV88E6XXX_FAMILY_6351, + .name = "Marvell 88E6171", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6351, + }, + + [MV88E6172] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6172, + .family = MV88E6XXX_FAMILY_6352, + .name = "Marvell 88E6172", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6352, + }, + + [MV88E6175] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6175, + .family = MV88E6XXX_FAMILY_6351, + .name = "Marvell 88E6175", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6351, + }, + + [MV88E6176] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6176, + .family = MV88E6XXX_FAMILY_6352, + .name = "Marvell 88E6176", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6352, + }, + + [MV88E6185] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6185, + .family = MV88E6XXX_FAMILY_6185, + .name = "Marvell 88E6185", + .num_databases = 256, + .num_ports = 10, + .flags = MV88E6XXX_FLAGS_FAMILY_6185, + }, + + [MV88E6240] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6240, + .family = MV88E6XXX_FAMILY_6352, + .name = "Marvell 88E6240", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6352, + }, + + [MV88E6320] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6320, + .family = MV88E6XXX_FAMILY_6320, + .name = "Marvell 88E6320", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6320, + }, + + [MV88E6321] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6321, + .family = MV88E6XXX_FAMILY_6320, + .name = "Marvell 88E6321", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6320, + }, + + [MV88E6350] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6350, + .family = MV88E6XXX_FAMILY_6351, + .name = "Marvell 88E6350", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6351, + }, + + [MV88E6351] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6351, + .family = MV88E6XXX_FAMILY_6351, + .name = "Marvell 88E6351", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6351, + }, + + [MV88E6352] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6352, + .family = MV88E6XXX_FAMILY_6352, + .name = "Marvell 88E6352", + .num_databases = 4096, + .num_ports = 7, + .flags = MV88E6XXX_FLAGS_FAMILY_6352, + }, +}; + static const struct mv88e6xxx_info * mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table, unsigned int num) @@ -3375,10 +3531,9 @@ mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table, return NULL; } -const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, - int sw_addr, void **priv, - const struct mv88e6xxx_info *table, - unsigned int num) +static const char *mv88e6xxx_probe(struct device *dsa_dev, + struct device *host_dev, int sw_addr, + void **priv) { const struct mv88e6xxx_info *info; struct mv88e6xxx_priv_state *ps; @@ -3397,7 +3552,8 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, prod_num = (id & 0xfff0) >> 4; rev = id & 0x000f; - info = mv88e6xxx_lookup_info(prod_num, table, num); + info = mv88e6xxx_lookup_info(prod_num, mv88e6xxx_table, + ARRAY_SIZE(mv88e6xxx_table)); if (!info) return NULL; @@ -3419,41 +3575,73 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, return name; } +struct dsa_switch_driver mv88e6xxx_switch_driver = { + .tag_protocol = DSA_TAG_PROTO_EDSA, + .probe = mv88e6xxx_probe, + .setup = mv88e6xxx_setup, + .set_addr = mv88e6xxx_set_addr, + .phy_read = mv88e6xxx_phy_read, + .phy_write = mv88e6xxx_phy_write, + .adjust_link = mv88e6xxx_adjust_link, + .get_strings = mv88e6xxx_get_strings, + .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, + .get_sset_count = mv88e6xxx_get_sset_count, + .set_eee = mv88e6xxx_set_eee, + .get_eee = mv88e6xxx_get_eee, +#ifdef CONFIG_NET_DSA_HWMON + .get_temp = mv88e6xxx_get_temp, + .get_temp_limit = mv88e6xxx_get_temp_limit, + .set_temp_limit = mv88e6xxx_set_temp_limit, + .get_temp_alarm = mv88e6xxx_get_temp_alarm, +#endif + .get_eeprom = mv88e6xxx_get_eeprom, + .set_eeprom = mv88e6xxx_set_eeprom, + .get_regs_len = mv88e6xxx_get_regs_len, + .get_regs = mv88e6xxx_get_regs, + .port_bridge_join = mv88e6xxx_port_bridge_join, + .port_bridge_leave = mv88e6xxx_port_bridge_leave, + .port_stp_state_set = mv88e6xxx_port_stp_state_set, + .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, + .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, + .port_vlan_add = mv88e6xxx_port_vlan_add, + .port_vlan_del = mv88e6xxx_port_vlan_del, + .port_vlan_dump = mv88e6xxx_port_vlan_dump, + .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, + .port_fdb_add = mv88e6xxx_port_fdb_add, + .port_fdb_del = mv88e6xxx_port_fdb_del, + .port_fdb_dump = mv88e6xxx_port_fdb_dump, +}; + static int __init mv88e6xxx_init(void) { -#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) - register_switch_driver(&mv88e6131_switch_driver); -#endif -#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123) - register_switch_driver(&mv88e6123_switch_driver); -#endif -#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352) - register_switch_driver(&mv88e6352_switch_driver); -#endif -#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) - register_switch_driver(&mv88e6171_switch_driver); -#endif + register_switch_driver(&mv88e6xxx_switch_driver); + return 0; } module_init(mv88e6xxx_init); static void __exit mv88e6xxx_cleanup(void) { -#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) - unregister_switch_driver(&mv88e6171_switch_driver); -#endif -#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352) - unregister_switch_driver(&mv88e6352_switch_driver); -#endif -#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123) - unregister_switch_driver(&mv88e6123_switch_driver); -#endif -#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) - unregister_switch_driver(&mv88e6131_switch_driver); -#endif + unregister_switch_driver(&mv88e6xxx_switch_driver); } module_exit(mv88e6xxx_cleanup); +MODULE_ALIAS("platform:mv88e6085"); +MODULE_ALIAS("platform:mv88e6095"); +MODULE_ALIAS("platform:mv88e6095f"); +MODULE_ALIAS("platform:mv88e6123"); +MODULE_ALIAS("platform:mv88e6131"); +MODULE_ALIAS("platform:mv88e6161"); +MODULE_ALIAS("platform:mv88e6165"); +MODULE_ALIAS("platform:mv88e6171"); +MODULE_ALIAS("platform:mv88e6172"); +MODULE_ALIAS("platform:mv88e6175"); +MODULE_ALIAS("platform:mv88e6176"); +MODULE_ALIAS("platform:mv88e6320"); +MODULE_ALIAS("platform:mv88e6321"); +MODULE_ALIAS("platform:mv88e6350"); +MODULE_ALIAS("platform:mv88e6351"); +MODULE_ALIAS("platform:mv88e6352"); MODULE_AUTHOR("Lennert Buytenhek "); MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index a131827cb26d..ca69a93a42a0 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -338,6 +338,27 @@ #define MV88E6XXX_N_FID 4096 +/* List of supported models */ +enum mv88e6xxx_model { + MV88E6085, + MV88E6095, + MV88E6123, + MV88E6131, + MV88E6161, + MV88E6165, + MV88E6171, + MV88E6172, + MV88E6175, + MV88E6176, + MV88E6185, + MV88E6240, + MV88E6320, + MV88E6321, + MV88E6350, + MV88E6351, + MV88E6352, +}; + enum mv88e6xxx_family { MV88E6XXX_FAMILY_NONE, MV88E6XXX_FAMILY_6065, /* 6031 6035 6061 6065 */ @@ -583,74 +604,4 @@ static inline bool mv88e6xxx_has(struct mv88e6xxx_priv_state *ps, return (ps->info->flags & flags) == flags; } -const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, - int sw_addr, void **priv, - const struct mv88e6xxx_info *table, - unsigned int num); - -int mv88e6xxx_setup(struct dsa_switch *ds); -int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg); -int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, - int reg, u16 val); -int mv88e6xxx_set_addr(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); -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); -int mv88e6xxx_get_sset_count(struct dsa_switch *ds); -int mv88e6xxx_get_sset_count_basic(struct dsa_switch *ds); -void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, - struct phy_device *phydev); -int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port); -void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, - struct ethtool_regs *regs, void *_p); -int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp); -int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp); -int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp); -int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm); -int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, - u8 *data); -int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, - u8 *data); -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); -int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, - struct net_device *bridge); -void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port); -void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); -int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, - bool vlan_filtering); -int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct switchdev_trans *trans); -void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct switchdev_trans *trans); -int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan); -int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, - struct switchdev_obj_port_vlan *vlan, - int (*cb)(struct switchdev_obj *obj)); -int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb, - struct switchdev_trans *trans); -void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb, - struct switchdev_trans *trans); -int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb); -int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, - struct switchdev_obj_port_fdb *fdb, - int (*cb)(struct switchdev_obj *obj)); -int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg); -int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page, - int reg, int val); - -extern struct dsa_switch_driver mv88e6131_switch_driver; -extern struct dsa_switch_driver mv88e6123_switch_driver; -extern struct dsa_switch_driver mv88e6352_switch_driver; -extern struct dsa_switch_driver mv88e6171_switch_driver; - #endif -- cgit v1.2.3