From ac271f93f24abb8dac14e1a5d0149110e72e3df6 Mon Sep 17 00:00:00 2001 From: "Bastien Curutchet (Schneider Electric)" Date: Tue, 5 May 2026 16:25:01 +0200 Subject: [PATCH 1/9] net: dsa: microchip: Remove unused ksz8_all_queues_split() ksz8_all_queues_split() isn't used anywhere. Remove it. Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-1-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz8.c | 15 --------------- drivers/net/dsa/microchip/ksz8.h | 1 - 2 files changed, 16 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c index c354abdafc1b..dc29b028f840 100644 --- a/drivers/net/dsa/microchip/ksz8.c +++ b/drivers/net/dsa/microchip/ksz8.c @@ -267,21 +267,6 @@ static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues) return ksz_prmw8(dev, port, reg_2q, mask_2q, data_2q); } -int ksz8_all_queues_split(struct ksz_device *dev, int queues) -{ - struct dsa_switch *ds = dev->ds; - const struct dsa_port *dp; - - dsa_switch_for_each_port(dp, ds) { - int ret = ksz8_port_queue_split(dev, dp->index, queues); - - if (ret) - return ret; - } - - return 0; -} - void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt) { const u32 *masks; diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h index 0f2cd1474b44..52b7d944d9d9 100644 --- a/drivers/net/dsa/microchip/ksz8.h +++ b/drivers/net/dsa/microchip/ksz8.h @@ -61,7 +61,6 @@ void ksz8_phylink_mac_link_up(struct phylink_config *config, struct phy_device *phydev, unsigned int mode, phy_interface_t interface, int speed, int duplex, bool tx_pause, bool rx_pause); -int ksz8_all_queues_split(struct ksz_device *dev, int queues); u32 ksz8463_get_port_addr(int port, int offset); int ksz8463_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); From 7ab8c9db2d3294ba3b8dfabe17f244cbbe1970fa Mon Sep 17 00:00:00 2001 From: "Bastien Curutchet (Schneider Electric)" Date: Tue, 5 May 2026 16:25:02 +0200 Subject: [PATCH 2/9] net: dsa: microchip: remove unused port_cleanup() callback ksz_dev_ops :: port_cleanup() isn't used anywhere. Remove it. Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-2-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 18f13ee9c7b6..cf2d0d91f173 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -363,7 +363,6 @@ struct ksz_dev_ops { u32 (*get_port_addr)(int port, int offset); void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member); void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); - void (*port_cleanup)(struct ksz_device *dev, int port); void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); int (*set_ageing_time)(struct ksz_device *dev, unsigned int msecs); From 2d0a20e4afd388b8e4f4ed05cca0ac04adf94557 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 5 May 2026 16:25:03 +0200 Subject: [PATCH 3/9] net: dsa: microchip: move KSZ8 ksz_dev_ops to ksz8.c The ksz_dev_ops() are specific to each switch family so they should belong to the individual drivers instead of the common section. Move the ksz_dev_ops() definitions of the KSZ8xxx to ksz8.c Set static the functions that aren't exported anymore. Signed-off-by: Vladimir Oltean Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-3-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz8.c | 200 +++++++++++++++++++------ drivers/net/dsa/microchip/ksz8.h | 51 +------ drivers/net/dsa/microchip/ksz_common.c | 102 ------------- 3 files changed, 155 insertions(+), 198 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c index dc29b028f840..56560f60223a 100644 --- a/drivers/net/dsa/microchip/ksz8.c +++ b/drivers/net/dsa/microchip/ksz8.c @@ -114,26 +114,26 @@ static int ksz8_ind_read8(struct ksz_device *dev, u8 table, u16 addr, u8 *val) return ret; } -int ksz8_pme_write8(struct ksz_device *dev, u32 reg, u8 value) +static int ksz8_pme_write8(struct ksz_device *dev, u32 reg, u8 value) { return ksz8_ind_write8(dev, (u8)(reg >> 8), (u8)(reg), value); } -int ksz8_pme_pread8(struct ksz_device *dev, int port, int offset, u8 *data) +static int ksz8_pme_pread8(struct ksz_device *dev, int port, int offset, u8 *data) { u8 table = (u8)(offset >> 8 | (port + 1)); return ksz8_ind_read8(dev, table, (u8)(offset), data); } -int ksz8_pme_pwrite8(struct ksz_device *dev, int port, int offset, u8 data) +static int ksz8_pme_pwrite8(struct ksz_device *dev, int port, int offset, u8 data) { u8 table = (u8)(offset >> 8 | (port + 1)); return ksz8_ind_write8(dev, table, (u8)(offset), data); } -int ksz8_reset_switch(struct ksz_device *dev) +static int ksz8_reset_switch(struct ksz_device *dev) { if (ksz_is_ksz88x3(dev)) { /* reset switch */ @@ -186,7 +186,7 @@ static int ksz8795_change_mtu(struct ksz_device *dev, int frame_size) return ksz_rmw8(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE, ctrl2); } -int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu) +static int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu) { u16 frame_size; @@ -267,7 +267,7 @@ static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues) return ksz_prmw8(dev, port, reg_2q, mask_2q, data_2q); } -void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt) +static void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt) { const u32 *masks; const u16 *regs; @@ -390,8 +390,8 @@ static void ksz8863_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, } } -void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, - u64 *dropped, u64 *cnt) +static void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, + u64 *dropped, u64 *cnt) { if (is_ksz88xx(dev)) ksz8863_r_mib_pkt(dev, port, addr, dropped, cnt); @@ -399,7 +399,7 @@ void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, ksz8795_r_mib_pkt(dev, port, addr, dropped, cnt); } -void ksz8_freeze_mib(struct ksz_device *dev, int port, bool freeze) +static void ksz8_freeze_mib(struct ksz_device *dev, int port, bool freeze) { if (is_ksz88xx(dev)) return; @@ -414,7 +414,7 @@ void ksz8_freeze_mib(struct ksz_device *dev, int port, bool freeze) ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), false); } -void ksz8_port_init_cnt(struct ksz_device *dev, int port) +static void ksz8_port_init_cnt(struct ksz_device *dev, int port) { struct ksz_port_mib *mib = &dev->ports[port].mib; u64 *dropped; @@ -939,7 +939,7 @@ static int ksz8_r_phy_bmcr(struct ksz_device *dev, u16 port, u16 *val) return 0; } -int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) +static int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) { u8 ctrl, link, val1, val2; int processed = true; @@ -1203,7 +1203,7 @@ static int ksz8_w_phy_bmcr(struct ksz_device *dev, u16 port, u16 val) restart); } -int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) +static int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) { const u16 *regs; u8 ctrl, data; @@ -1263,7 +1263,7 @@ int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) return 0; } -void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member) +static void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member) { int offset = P_MIRROR_CTRL; u8 data; @@ -1276,7 +1276,7 @@ void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member) ksz_pwrite8(dev, port, offset, data); } -void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) +static void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) { u8 learn[DSA_MAX_PORTS]; int first, index, cnt; @@ -1311,8 +1311,8 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) } } -int ksz8_fdb_dump(struct ksz_device *dev, int port, - dsa_fdb_dump_cb_t *cb, void *data) +static int ksz8_fdb_dump(struct ksz_device *dev, int port, + dsa_fdb_dump_cb_t *cb, void *data) { u8 mac[ETH_ALEN]; u8 src_port, fid; @@ -1416,32 +1416,34 @@ static int ksz8_del_sta_mac(struct ksz_device *dev, int port, return ksz8_w_sta_mac_table(dev, index, &alu); } -int ksz8_mdb_add(struct ksz_device *dev, int port, - const struct switchdev_obj_port_mdb *mdb, struct dsa_db db) +static int ksz8_mdb_add(struct ksz_device *dev, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db) { return ksz8_add_sta_mac(dev, port, mdb->addr, mdb->vid); } -int ksz8_mdb_del(struct ksz_device *dev, int port, - const struct switchdev_obj_port_mdb *mdb, struct dsa_db db) +static int ksz8_mdb_del(struct ksz_device *dev, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db) { return ksz8_del_sta_mac(dev, port, mdb->addr, mdb->vid); } -int ksz8_fdb_add(struct ksz_device *dev, int port, const unsigned char *addr, - u16 vid, struct dsa_db db) +static int ksz8_fdb_add(struct ksz_device *dev, int port, + const unsigned char *addr, u16 vid, struct dsa_db db) { return ksz8_add_sta_mac(dev, port, addr, vid); } -int ksz8_fdb_del(struct ksz_device *dev, int port, const unsigned char *addr, - u16 vid, struct dsa_db db) +static int ksz8_fdb_del(struct ksz_device *dev, int port, + const unsigned char *addr, u16 vid, struct dsa_db db) { return ksz8_del_sta_mac(dev, port, addr, vid); } -int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag, - struct netlink_ext_ack *extack) +static int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag, + struct netlink_ext_ack *extack) { if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev)) return -ENOTSUPP; @@ -1470,9 +1472,9 @@ static void ksz8_port_enable_pvid(struct ksz_device *dev, int port, bool state) } } -int ksz8_port_vlan_add(struct ksz_device *dev, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack) +static int ksz8_port_vlan_add(struct ksz_device *dev, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack) { bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; struct ksz_port *p = &dev->ports[port]; @@ -1542,8 +1544,8 @@ int ksz8_port_vlan_add(struct ksz_device *dev, int port, return 0; } -int ksz8_port_vlan_del(struct ksz_device *dev, int port, - const struct switchdev_obj_port_vlan *vlan) +static int ksz8_port_vlan_del(struct ksz_device *dev, int port, + const struct switchdev_obj_port_vlan *vlan) { u16 data, pvid; u8 fid, member, valid; @@ -1574,9 +1576,9 @@ int ksz8_port_vlan_del(struct ksz_device *dev, int port, return 0; } -int ksz8_port_mirror_add(struct ksz_device *dev, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress, struct netlink_ext_ack *extack) +static int ksz8_port_mirror_add(struct ksz_device *dev, int port, + struct dsa_mall_mirror_tc_entry *mirror, + bool ingress, struct netlink_ext_ack *extack) { int offset = P_MIRROR_CTRL; @@ -1600,8 +1602,8 @@ int ksz8_port_mirror_add(struct ksz_device *dev, int port, return 0; } -void ksz8_port_mirror_del(struct ksz_device *dev, int port, - struct dsa_mall_mirror_tc_entry *mirror) +static void ksz8_port_mirror_del(struct ksz_device *dev, int port, + struct dsa_mall_mirror_tc_entry *mirror) { int offset = P_MIRROR_CTRL; u8 data; @@ -1639,7 +1641,7 @@ static void ksz8795_cpu_interface_select(struct ksz_device *dev, int port) } } -void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) +static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) { const u16 *regs = dev->info->regs; struct dsa_switch *ds = dev->ds; @@ -1694,7 +1696,7 @@ static void ksz88x3_config_rmii_clk(struct ksz_device *dev) KSZ88X3_PORT3_RMII_CLK_INTERNAL, rmii_clk_internal); } -void ksz8_config_cpu_port(struct dsa_switch *ds) +static void ksz8_config_cpu_port(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; struct ksz_port *p; @@ -1903,7 +1905,7 @@ static int ksz8_handle_global_errata(struct dsa_switch *ds) return ret; } -int ksz8_enable_stp_addr(struct ksz_device *dev) +static int ksz8_enable_stp_addr(struct ksz_device *dev) { struct alu_struct alu; @@ -1917,7 +1919,7 @@ int ksz8_enable_stp_addr(struct ksz_device *dev) return ksz8_w_sta_mac_table(dev, 0, &alu); } -int ksz8_setup(struct dsa_switch *ds) +static int ksz8_setup(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; const u16 *regs = dev->info->regs; @@ -1980,8 +1982,8 @@ int ksz8_setup(struct dsa_switch *ds) return ret; } -void ksz8_get_caps(struct ksz_device *dev, int port, - struct phylink_config *config) +static void ksz8_get_caps(struct ksz_device *dev, int port, + struct phylink_config *config) { config->mac_capabilities = MAC_10 | MAC_100; @@ -1998,12 +2000,12 @@ void ksz8_get_caps(struct ksz_device *dev, int port, config->mac_capabilities |= MAC_ASYM_PAUSE; } -u32 ksz8_get_port_addr(int port, int offset) +static u32 ksz8_get_port_addr(int port, int offset) { return PORT_CTRL_ADDR(port, offset); } -u32 ksz8463_get_port_addr(int port, int offset) +static u32 ksz8463_get_port_addr(int port, int offset) { return offset + 0x18 * port; } @@ -2013,7 +2015,7 @@ static u16 ksz8463_get_phy_addr(u16 phy, u16 reg, u16 offset) return offset + reg * 2 + phy * (P2MBCR - P1MBCR); } -int ksz8463_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) +static int ksz8463_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) { u16 sw_reg = 0; u16 data = 0; @@ -2053,7 +2055,7 @@ int ksz8463_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) return 0; } -int ksz8463_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) +static int ksz8463_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) { u16 sw_reg = 0; int ret; @@ -2081,7 +2083,7 @@ int ksz8463_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) return 0; } -int ksz8_switch_init(struct ksz_device *dev) +static int ksz8_switch_init(struct ksz_device *dev) { dev->cpu_port = fls(dev->info->cpu_ports) - 1; dev->phy_port_cnt = dev->info->port_cnt - 1; @@ -2090,11 +2092,113 @@ int ksz8_switch_init(struct ksz_device *dev) return 0; } -void ksz8_switch_exit(struct ksz_device *dev) +static void ksz8_switch_exit(struct ksz_device *dev) { ksz8_reset_switch(dev); } +const struct ksz_dev_ops ksz8463_dev_ops = { + .setup = ksz8_setup, + .get_port_addr = ksz8463_get_port_addr, + .cfg_port_member = ksz8_cfg_port_member, + .flush_dyn_mac_table = ksz8_flush_dyn_mac_table, + .port_setup = ksz8_port_setup, + .r_phy = ksz8463_r_phy, + .w_phy = ksz8463_w_phy, + .r_mib_cnt = ksz8_r_mib_cnt, + .r_mib_pkt = ksz8_r_mib_pkt, + .r_mib_stat64 = ksz88xx_r_mib_stats64, + .freeze_mib = ksz8_freeze_mib, + .port_init_cnt = ksz8_port_init_cnt, + .fdb_dump = ksz8_fdb_dump, + .fdb_add = ksz8_fdb_add, + .fdb_del = ksz8_fdb_del, + .mdb_add = ksz8_mdb_add, + .mdb_del = ksz8_mdb_del, + .vlan_filtering = ksz8_port_vlan_filtering, + .vlan_add = ksz8_port_vlan_add, + .vlan_del = ksz8_port_vlan_del, + .mirror_add = ksz8_port_mirror_add, + .mirror_del = ksz8_port_mirror_del, + .get_caps = ksz8_get_caps, + .config_cpu_port = ksz8_config_cpu_port, + .enable_stp_addr = ksz8_enable_stp_addr, + .reset = ksz8_reset_switch, + .init = ksz8_switch_init, + .exit = ksz8_switch_exit, + .change_mtu = ksz8_change_mtu, +}; + +const struct ksz_dev_ops ksz87xx_dev_ops = { + .setup = ksz8_setup, + .get_port_addr = ksz8_get_port_addr, + .cfg_port_member = ksz8_cfg_port_member, + .flush_dyn_mac_table = ksz8_flush_dyn_mac_table, + .port_setup = ksz8_port_setup, + .r_phy = ksz8_r_phy, + .w_phy = ksz8_w_phy, + .r_mib_cnt = ksz8_r_mib_cnt, + .r_mib_pkt = ksz8_r_mib_pkt, + .r_mib_stat64 = ksz_r_mib_stats64, + .freeze_mib = ksz8_freeze_mib, + .port_init_cnt = ksz8_port_init_cnt, + .fdb_dump = ksz8_fdb_dump, + .fdb_add = ksz8_fdb_add, + .fdb_del = ksz8_fdb_del, + .mdb_add = ksz8_mdb_add, + .mdb_del = ksz8_mdb_del, + .vlan_filtering = ksz8_port_vlan_filtering, + .vlan_add = ksz8_port_vlan_add, + .vlan_del = ksz8_port_vlan_del, + .mirror_add = ksz8_port_mirror_add, + .mirror_del = ksz8_port_mirror_del, + .get_caps = ksz8_get_caps, + .config_cpu_port = ksz8_config_cpu_port, + .enable_stp_addr = ksz8_enable_stp_addr, + .reset = ksz8_reset_switch, + .init = ksz8_switch_init, + .exit = ksz8_switch_exit, + .change_mtu = ksz8_change_mtu, + .pme_write8 = ksz8_pme_write8, + .pme_pread8 = ksz8_pme_pread8, + .pme_pwrite8 = ksz8_pme_pwrite8, +}; + +const struct ksz_dev_ops ksz88xx_dev_ops = { + .setup = ksz8_setup, + .get_port_addr = ksz8_get_port_addr, + .cfg_port_member = ksz8_cfg_port_member, + .flush_dyn_mac_table = ksz8_flush_dyn_mac_table, + .port_setup = ksz8_port_setup, + .r_phy = ksz8_r_phy, + .w_phy = ksz8_w_phy, + .r_mib_cnt = ksz8_r_mib_cnt, + .r_mib_pkt = ksz8_r_mib_pkt, + .r_mib_stat64 = ksz88xx_r_mib_stats64, + .freeze_mib = ksz8_freeze_mib, + .port_init_cnt = ksz8_port_init_cnt, + .fdb_dump = ksz8_fdb_dump, + .fdb_add = ksz8_fdb_add, + .fdb_del = ksz8_fdb_del, + .mdb_add = ksz8_mdb_add, + .mdb_del = ksz8_mdb_del, + .vlan_filtering = ksz8_port_vlan_filtering, + .vlan_add = ksz8_port_vlan_add, + .vlan_del = ksz8_port_vlan_del, + .mirror_add = ksz8_port_mirror_add, + .mirror_del = ksz8_port_mirror_del, + .get_caps = ksz8_get_caps, + .config_cpu_port = ksz8_config_cpu_port, + .enable_stp_addr = ksz8_enable_stp_addr, + .reset = ksz8_reset_switch, + .init = ksz8_switch_init, + .exit = ksz8_switch_exit, + .change_mtu = ksz8_change_mtu, + .pme_write8 = ksz8_pme_write8, + .pme_pread8 = ksz8_pme_pread8, + .pme_pwrite8 = ksz8_pme_pwrite8, +}; + MODULE_AUTHOR("Tristram Ha "); MODULE_DESCRIPTION("Microchip KSZ8795 Series Switch DSA Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h index 52b7d944d9d9..4b798ce29daa 100644 --- a/drivers/net/dsa/microchip/ksz8.h +++ b/drivers/net/dsa/microchip/ksz8.h @@ -12,58 +12,13 @@ #include #include "ksz_common.h" -int ksz8_setup(struct dsa_switch *ds); -u32 ksz8_get_port_addr(int port, int offset); -void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member); -void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port); -void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port); -int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); -int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val); -void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt); -void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, - u64 *dropped, u64 *cnt); -void ksz8_freeze_mib(struct ksz_device *dev, int port, bool freeze); -void ksz8_port_init_cnt(struct ksz_device *dev, int port); -int ksz8_fdb_dump(struct ksz_device *dev, int port, - dsa_fdb_dump_cb_t *cb, void *data); -int ksz8_fdb_add(struct ksz_device *dev, int port, const unsigned char *addr, - u16 vid, struct dsa_db db); -int ksz8_fdb_del(struct ksz_device *dev, int port, const unsigned char *addr, - u16 vid, struct dsa_db db); -int ksz8_mdb_add(struct ksz_device *dev, int port, - const struct switchdev_obj_port_mdb *mdb, struct dsa_db db); -int ksz8_mdb_del(struct ksz_device *dev, int port, - const struct switchdev_obj_port_mdb *mdb, struct dsa_db db); -int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag, - struct netlink_ext_ack *extack); -int ksz8_port_vlan_add(struct ksz_device *dev, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack); -int ksz8_port_vlan_del(struct ksz_device *dev, int port, - const struct switchdev_obj_port_vlan *vlan); -int ksz8_port_mirror_add(struct ksz_device *dev, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress, struct netlink_ext_ack *extack); -void ksz8_port_mirror_del(struct ksz_device *dev, int port, - struct dsa_mall_mirror_tc_entry *mirror); -void ksz8_get_caps(struct ksz_device *dev, int port, - struct phylink_config *config); -void ksz8_config_cpu_port(struct dsa_switch *ds); -int ksz8_enable_stp_addr(struct ksz_device *dev); -int ksz8_reset_switch(struct ksz_device *dev); -int ksz8_switch_init(struct ksz_device *dev); -void ksz8_switch_exit(struct ksz_device *dev); -int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu); -int ksz8_pme_write8(struct ksz_device *dev, u32 reg, u8 value); -int ksz8_pme_pread8(struct ksz_device *dev, int port, int offset, u8 *data); -int ksz8_pme_pwrite8(struct ksz_device *dev, int port, int offset, u8 data); void ksz8_phylink_mac_link_up(struct phylink_config *config, struct phy_device *phydev, unsigned int mode, phy_interface_t interface, int speed, int duplex, bool tx_pause, bool rx_pause); -u32 ksz8463_get_port_addr(int port, int offset); -int ksz8463_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); -int ksz8463_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val); +extern const struct ksz_dev_ops ksz8463_dev_ops; +extern const struct ksz_dev_ops ksz87xx_dev_ops; +extern const struct ksz_dev_ops ksz88xx_dev_ops; #endif diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 144373e13bea..4d7834149d0c 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -332,108 +332,6 @@ static const struct phylink_mac_ops ksz8_phylink_mac_ops = { .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, }; -static const struct ksz_dev_ops ksz8463_dev_ops = { - .setup = ksz8_setup, - .get_port_addr = ksz8463_get_port_addr, - .cfg_port_member = ksz8_cfg_port_member, - .flush_dyn_mac_table = ksz8_flush_dyn_mac_table, - .port_setup = ksz8_port_setup, - .r_phy = ksz8463_r_phy, - .w_phy = ksz8463_w_phy, - .r_mib_cnt = ksz8_r_mib_cnt, - .r_mib_pkt = ksz8_r_mib_pkt, - .r_mib_stat64 = ksz88xx_r_mib_stats64, - .freeze_mib = ksz8_freeze_mib, - .port_init_cnt = ksz8_port_init_cnt, - .fdb_dump = ksz8_fdb_dump, - .fdb_add = ksz8_fdb_add, - .fdb_del = ksz8_fdb_del, - .mdb_add = ksz8_mdb_add, - .mdb_del = ksz8_mdb_del, - .vlan_filtering = ksz8_port_vlan_filtering, - .vlan_add = ksz8_port_vlan_add, - .vlan_del = ksz8_port_vlan_del, - .mirror_add = ksz8_port_mirror_add, - .mirror_del = ksz8_port_mirror_del, - .get_caps = ksz8_get_caps, - .config_cpu_port = ksz8_config_cpu_port, - .enable_stp_addr = ksz8_enable_stp_addr, - .reset = ksz8_reset_switch, - .init = ksz8_switch_init, - .exit = ksz8_switch_exit, - .change_mtu = ksz8_change_mtu, -}; - -static const struct ksz_dev_ops ksz88xx_dev_ops = { - .setup = ksz8_setup, - .get_port_addr = ksz8_get_port_addr, - .cfg_port_member = ksz8_cfg_port_member, - .flush_dyn_mac_table = ksz8_flush_dyn_mac_table, - .port_setup = ksz8_port_setup, - .r_phy = ksz8_r_phy, - .w_phy = ksz8_w_phy, - .r_mib_cnt = ksz8_r_mib_cnt, - .r_mib_pkt = ksz8_r_mib_pkt, - .r_mib_stat64 = ksz88xx_r_mib_stats64, - .freeze_mib = ksz8_freeze_mib, - .port_init_cnt = ksz8_port_init_cnt, - .fdb_dump = ksz8_fdb_dump, - .fdb_add = ksz8_fdb_add, - .fdb_del = ksz8_fdb_del, - .mdb_add = ksz8_mdb_add, - .mdb_del = ksz8_mdb_del, - .vlan_filtering = ksz8_port_vlan_filtering, - .vlan_add = ksz8_port_vlan_add, - .vlan_del = ksz8_port_vlan_del, - .mirror_add = ksz8_port_mirror_add, - .mirror_del = ksz8_port_mirror_del, - .get_caps = ksz8_get_caps, - .config_cpu_port = ksz8_config_cpu_port, - .enable_stp_addr = ksz8_enable_stp_addr, - .reset = ksz8_reset_switch, - .init = ksz8_switch_init, - .exit = ksz8_switch_exit, - .change_mtu = ksz8_change_mtu, - .pme_write8 = ksz8_pme_write8, - .pme_pread8 = ksz8_pme_pread8, - .pme_pwrite8 = ksz8_pme_pwrite8, -}; - -static const struct ksz_dev_ops ksz87xx_dev_ops = { - .setup = ksz8_setup, - .get_port_addr = ksz8_get_port_addr, - .cfg_port_member = ksz8_cfg_port_member, - .flush_dyn_mac_table = ksz8_flush_dyn_mac_table, - .port_setup = ksz8_port_setup, - .r_phy = ksz8_r_phy, - .w_phy = ksz8_w_phy, - .r_mib_cnt = ksz8_r_mib_cnt, - .r_mib_pkt = ksz8_r_mib_pkt, - .r_mib_stat64 = ksz_r_mib_stats64, - .freeze_mib = ksz8_freeze_mib, - .port_init_cnt = ksz8_port_init_cnt, - .fdb_dump = ksz8_fdb_dump, - .fdb_add = ksz8_fdb_add, - .fdb_del = ksz8_fdb_del, - .mdb_add = ksz8_mdb_add, - .mdb_del = ksz8_mdb_del, - .vlan_filtering = ksz8_port_vlan_filtering, - .vlan_add = ksz8_port_vlan_add, - .vlan_del = ksz8_port_vlan_del, - .mirror_add = ksz8_port_mirror_add, - .mirror_del = ksz8_port_mirror_del, - .get_caps = ksz8_get_caps, - .config_cpu_port = ksz8_config_cpu_port, - .enable_stp_addr = ksz8_enable_stp_addr, - .reset = ksz8_reset_switch, - .init = ksz8_switch_init, - .exit = ksz8_switch_exit, - .change_mtu = ksz8_change_mtu, - .pme_write8 = ksz8_pme_write8, - .pme_pread8 = ksz8_pme_pread8, - .pme_pwrite8 = ksz8_pme_pwrite8, -}; - static void ksz9477_phylink_mac_link_up(struct phylink_config *config, struct phy_device *phydev, unsigned int mode, From 0e3e45d330e7cb21cf34ca7d11dd9a659baa43a4 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 5 May 2026 16:25:04 +0200 Subject: [PATCH 4/9] net: dsa: microchip: move KSZ9477 and LAN937 ksz_dev_ops to individual drivers The ksz_dev_ops() are specific to each switch family so they should belong to the individual drivers instead of the common section. Move the ksz_dev_ops() definitions of the KSZ9477 and the LAN937 to their individual drivers. Set static the functions that aren't exported anymore. Signed-off-by: Vladimir Oltean Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-4-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz9477.c | 66 +++++++++++++++----- drivers/net/dsa/microchip/ksz9477.h | 15 +---- drivers/net/dsa/microchip/ksz_common.c | 76 ------------------------ drivers/net/dsa/microchip/lan937x.h | 19 +----- drivers/net/dsa/microchip/lan937x_main.c | 72 ++++++++++++++++------ 5 files changed, 110 insertions(+), 138 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index d3c23dcaea8c..3275996cda96 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -43,7 +43,7 @@ static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset, bits, set ? bits : 0); } -int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu) +static int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu) { u16 frame_size; @@ -308,7 +308,7 @@ static int ksz9477_pcs_write(struct mii_bus *bus, int phy, int mmd, int reg, return 0; } -int ksz9477_pcs_create(struct ksz_device *dev) +static int ksz9477_pcs_create(struct ksz_device *dev) { int port = ksz_get_sgmii_port(dev); struct ksz_port *p = &dev->ports[port]; @@ -341,7 +341,7 @@ int ksz9477_pcs_create(struct ksz_device *dev) return 0; } -int ksz9477_reset_switch(struct ksz_device *dev) +static int ksz9477_reset_switch(struct ksz_device *dev) { u8 data8; u32 data32; @@ -516,7 +516,7 @@ static void ksz9477_r_phy_quirks(struct ksz_device *dev, u16 addr, u16 reg, *data &= ~(BMSR_ESTATEN | BMSR_ERCAP); } -int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) +static int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) { u16 val = 0xffff; int ret; @@ -572,7 +572,7 @@ int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) return 0; } -int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) +static int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) { u32 mask, val32; @@ -1150,8 +1150,8 @@ static phy_interface_t ksz9477_get_interface(struct ksz_device *dev, int port) return interface; } -void ksz9477_get_caps(struct ksz_device *dev, int port, - struct phylink_config *config) +static void ksz9477_get_caps(struct ksz_device *dev, int port, + struct phylink_config *config) { config->mac_capabilities = MAC_10 | MAC_100 | MAC_ASYM_PAUSE | MAC_SYM_PAUSE; @@ -1168,7 +1168,7 @@ void ksz9477_get_caps(struct ksz_device *dev, int port, } } -int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs) +static int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs) { u32 secs = msecs / 1000; u8 data, mult, value; @@ -1234,7 +1234,7 @@ void ksz9477_port_queue_split(struct ksz_device *dev, int port) ksz_prmw8(dev, port, REG_PORT_CTRL_0, PORT_QUEUE_SPLIT_MASK, data); } -void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) +static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) { const u16 *regs = dev->info->regs; struct dsa_switch *ds = dev->ds; @@ -1289,7 +1289,7 @@ void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) ksz_pwrite8(dev, port, regs[REG_PORT_PME_CTRL], 0); } -void ksz9477_config_cpu_port(struct dsa_switch *ds) +static void ksz9477_config_cpu_port(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; struct ksz_port *p; @@ -1454,7 +1454,7 @@ int ksz9477_enable_stp_addr(struct ksz_device *dev) return 0; } -int ksz9477_setup(struct dsa_switch *ds) +static int ksz9477_setup(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; const u16 *regs = dev->info->regs; @@ -1500,7 +1500,7 @@ u32 ksz9477_get_port_addr(int port, int offset) return PORT_CTRL_ADDR(port, offset); } -int ksz9477_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val) +static int ksz9477_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val) { val = val >> 8; @@ -1584,7 +1584,7 @@ void ksz9477_hsr_leave(struct dsa_switch *ds, int port, struct net_device *hsr) ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL, PORT_SRC_ADDR_FILTER, false); } -int ksz9477_switch_init(struct ksz_device *dev) +static int ksz9477_switch_init(struct ksz_device *dev) { u8 data8; int ret; @@ -1604,11 +1604,49 @@ int ksz9477_switch_init(struct ksz_device *dev) return 0; } -void ksz9477_switch_exit(struct ksz_device *dev) +static void ksz9477_switch_exit(struct ksz_device *dev) { ksz9477_reset_switch(dev); } +const struct ksz_dev_ops ksz9477_dev_ops = { + .setup = ksz9477_setup, + .get_port_addr = ksz9477_get_port_addr, + .cfg_port_member = ksz9477_cfg_port_member, + .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, + .port_setup = ksz9477_port_setup, + .set_ageing_time = ksz9477_set_ageing_time, + .r_phy = ksz9477_r_phy, + .w_phy = ksz9477_w_phy, + .r_mib_cnt = ksz9477_r_mib_cnt, + .r_mib_pkt = ksz9477_r_mib_pkt, + .r_mib_stat64 = ksz_r_mib_stats64, + .freeze_mib = ksz9477_freeze_mib, + .port_init_cnt = ksz9477_port_init_cnt, + .vlan_filtering = ksz9477_port_vlan_filtering, + .vlan_add = ksz9477_port_vlan_add, + .vlan_del = ksz9477_port_vlan_del, + .mirror_add = ksz9477_port_mirror_add, + .mirror_del = ksz9477_port_mirror_del, + .get_caps = ksz9477_get_caps, + .fdb_dump = ksz9477_fdb_dump, + .fdb_add = ksz9477_fdb_add, + .fdb_del = ksz9477_fdb_del, + .mdb_add = ksz9477_mdb_add, + .mdb_del = ksz9477_mdb_del, + .change_mtu = ksz9477_change_mtu, + .pme_write8 = ksz_write8, + .pme_pread8 = ksz_pread8, + .pme_pwrite8 = ksz_pwrite8, + .config_cpu_port = ksz9477_config_cpu_port, + .tc_cbs_set_cinc = ksz9477_tc_cbs_set_cinc, + .enable_stp_addr = ksz9477_enable_stp_addr, + .reset = ksz9477_reset_switch, + .init = ksz9477_switch_init, + .exit = ksz9477_switch_exit, + .pcs_create = ksz9477_pcs_create, +}; + MODULE_AUTHOR("Woojung Huh "); MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch DSA Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/dsa/microchip/ksz9477.h b/drivers/net/dsa/microchip/ksz9477.h index 0d1a6dfda23e..30ab0c8807db 100644 --- a/drivers/net/dsa/microchip/ksz9477.h +++ b/drivers/net/dsa/microchip/ksz9477.h @@ -11,14 +11,9 @@ #include #include "ksz_common.h" -int ksz9477_setup(struct dsa_switch *ds); u32 ksz9477_get_port_addr(int port, int offset); void ksz9477_cfg_port_member(struct ksz_device *dev, int port, u8 member); void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port); -void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port); -int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs); -int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data); -int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val); void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt); void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, u64 *dropped, u64 *cnt); @@ -38,8 +33,6 @@ void ksz9477_port_mirror_del(struct ksz_device *dev, int port, struct dsa_mall_mirror_tc_entry *mirror); int ksz9477_errata_monitor(struct ksz_device *dev, int port, u64 tx_late_col); -void ksz9477_get_caps(struct ksz_device *dev, int port, - struct phylink_config *config); int ksz9477_fdb_dump(struct ksz_device *dev, int port, dsa_fdb_dump_cb_t *cb, void *data); int ksz9477_fdb_add(struct ksz_device *dev, int port, @@ -50,13 +43,7 @@ int ksz9477_mdb_add(struct ksz_device *dev, int port, const struct switchdev_obj_port_mdb *mdb, struct dsa_db db); int ksz9477_mdb_del(struct ksz_device *dev, int port, const struct switchdev_obj_port_mdb *mdb, struct dsa_db db); -int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu); -void ksz9477_config_cpu_port(struct dsa_switch *ds); -int ksz9477_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val); int ksz9477_enable_stp_addr(struct ksz_device *dev); -int ksz9477_reset_switch(struct ksz_device *dev); -int ksz9477_switch_init(struct ksz_device *dev); -void ksz9477_switch_exit(struct ksz_device *dev); void ksz9477_port_queue_split(struct ksz_device *dev, int port); void ksz9477_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr); void ksz9477_hsr_leave(struct dsa_switch *ds, int port, struct net_device *hsr); @@ -97,6 +84,6 @@ void ksz9477_acl_match_process_l2(struct ksz_device *dev, int port, u16 ethtype, u8 *src_mac, u8 *dst_mac, unsigned long cookie, u32 prio); -int ksz9477_pcs_create(struct ksz_device *dev); +extern const struct ksz_dev_ops ksz9477_dev_ops; #endif diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 4d7834149d0c..88446bc32465 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -364,44 +364,6 @@ static const struct phylink_mac_ops ksz9477_phylink_mac_ops = { .mac_select_pcs = ksz_phylink_mac_select_pcs, }; -static const struct ksz_dev_ops ksz9477_dev_ops = { - .setup = ksz9477_setup, - .get_port_addr = ksz9477_get_port_addr, - .cfg_port_member = ksz9477_cfg_port_member, - .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, - .port_setup = ksz9477_port_setup, - .set_ageing_time = ksz9477_set_ageing_time, - .r_phy = ksz9477_r_phy, - .w_phy = ksz9477_w_phy, - .r_mib_cnt = ksz9477_r_mib_cnt, - .r_mib_pkt = ksz9477_r_mib_pkt, - .r_mib_stat64 = ksz_r_mib_stats64, - .freeze_mib = ksz9477_freeze_mib, - .port_init_cnt = ksz9477_port_init_cnt, - .vlan_filtering = ksz9477_port_vlan_filtering, - .vlan_add = ksz9477_port_vlan_add, - .vlan_del = ksz9477_port_vlan_del, - .mirror_add = ksz9477_port_mirror_add, - .mirror_del = ksz9477_port_mirror_del, - .get_caps = ksz9477_get_caps, - .fdb_dump = ksz9477_fdb_dump, - .fdb_add = ksz9477_fdb_add, - .fdb_del = ksz9477_fdb_del, - .mdb_add = ksz9477_mdb_add, - .mdb_del = ksz9477_mdb_del, - .change_mtu = ksz9477_change_mtu, - .pme_write8 = ksz_write8, - .pme_pread8 = ksz_pread8, - .pme_pwrite8 = ksz_pwrite8, - .config_cpu_port = ksz9477_config_cpu_port, - .tc_cbs_set_cinc = ksz9477_tc_cbs_set_cinc, - .enable_stp_addr = ksz9477_enable_stp_addr, - .reset = ksz9477_reset_switch, - .init = ksz9477_switch_init, - .exit = ksz9477_switch_exit, - .pcs_create = ksz9477_pcs_create, -}; - static const struct phylink_mac_ops lan937x_phylink_mac_ops = { .mac_config = ksz_phylink_mac_config, .mac_link_down = ksz_phylink_mac_link_down, @@ -410,44 +372,6 @@ static const struct phylink_mac_ops lan937x_phylink_mac_ops = { .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, }; -static const struct ksz_dev_ops lan937x_dev_ops = { - .setup = lan937x_setup, - .teardown = lan937x_teardown, - .get_port_addr = ksz9477_get_port_addr, - .cfg_port_member = ksz9477_cfg_port_member, - .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, - .port_setup = lan937x_port_setup, - .set_ageing_time = lan937x_set_ageing_time, - .mdio_bus_preinit = lan937x_mdio_bus_preinit, - .create_phy_addr_map = lan937x_create_phy_addr_map, - .r_phy = lan937x_r_phy, - .w_phy = lan937x_w_phy, - .r_mib_cnt = ksz9477_r_mib_cnt, - .r_mib_pkt = ksz9477_r_mib_pkt, - .r_mib_stat64 = ksz_r_mib_stats64, - .freeze_mib = ksz9477_freeze_mib, - .port_init_cnt = ksz9477_port_init_cnt, - .vlan_filtering = ksz9477_port_vlan_filtering, - .vlan_add = ksz9477_port_vlan_add, - .vlan_del = ksz9477_port_vlan_del, - .mirror_add = ksz9477_port_mirror_add, - .mirror_del = ksz9477_port_mirror_del, - .get_caps = lan937x_phylink_get_caps, - .setup_rgmii_delay = lan937x_setup_rgmii_delay, - .fdb_dump = ksz9477_fdb_dump, - .fdb_add = ksz9477_fdb_add, - .fdb_del = ksz9477_fdb_del, - .mdb_add = ksz9477_mdb_add, - .mdb_del = ksz9477_mdb_del, - .change_mtu = lan937x_change_mtu, - .config_cpu_port = lan937x_config_cpu_port, - .tc_cbs_set_cinc = lan937x_tc_cbs_set_cinc, - .enable_stp_addr = ksz9477_enable_stp_addr, - .reset = lan937x_reset_switch, - .init = lan937x_switch_init, - .exit = lan937x_switch_exit, -}; - static const u16 ksz8463_regs[] = { [REG_SW_MAC_ADDR] = 0x10, [REG_IND_CTRL_0] = 0x30, diff --git a/drivers/net/dsa/microchip/lan937x.h b/drivers/net/dsa/microchip/lan937x.h index df13ebbd356f..48fc49775094 100644 --- a/drivers/net/dsa/microchip/lan937x.h +++ b/drivers/net/dsa/microchip/lan937x.h @@ -6,21 +6,6 @@ #ifndef __LAN937X_CFG_H #define __LAN937X_CFG_H -int lan937x_reset_switch(struct ksz_device *dev); -int lan937x_setup(struct dsa_switch *ds); -void lan937x_teardown(struct dsa_switch *ds); -void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port); -void lan937x_config_cpu_port(struct dsa_switch *ds); -int lan937x_switch_init(struct ksz_device *dev); -void lan937x_switch_exit(struct ksz_device *dev); -int lan937x_mdio_bus_preinit(struct ksz_device *dev, bool side_mdio); -int lan937x_create_phy_addr_map(struct ksz_device *dev, bool side_mdio); -int lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data); -int lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val); -int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu); -void lan937x_phylink_get_caps(struct ksz_device *dev, int port, - struct phylink_config *config); -void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port); -int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs); -int lan937x_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val); +extern const struct ksz_dev_ops lan937x_dev_ops; + #endif diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index 5a1496fff445..ced381f67392 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -137,7 +137,7 @@ static int lan937x_port_cfg(struct ksz_device *dev, int port, int offset, * * Return: 0 on success, error code on failure. */ -int lan937x_create_phy_addr_map(struct ksz_device *dev, bool side_mdio) +static int lan937x_create_phy_addr_map(struct ksz_device *dev, bool side_mdio) { static const u8 *phy_addr_map; u32 strap_val; @@ -221,7 +221,7 @@ int lan937x_create_phy_addr_map(struct ksz_device *dev, bool side_mdio) * * Return: 0 on success, error code on failure. */ -int lan937x_mdio_bus_preinit(struct ksz_device *dev, bool side_mdio) +static int lan937x_mdio_bus_preinit(struct ksz_device *dev, bool side_mdio) { u16 data16; int ret; @@ -332,17 +332,17 @@ static int lan937x_internal_phy_read(struct ksz_device *dev, int addr, int reg, return ksz_read16(dev, REG_VPHY_IND_DATA__2, val); } -int lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) +static int lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) { return lan937x_internal_phy_read(dev, addr, reg, data); } -int lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) +static int lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) { return lan937x_internal_phy_write(dev, addr, reg, val); } -int lan937x_reset_switch(struct ksz_device *dev) +static int lan937x_reset_switch(struct ksz_device *dev) { u32 data32; int ret; @@ -373,7 +373,7 @@ int lan937x_reset_switch(struct ksz_device *dev) return ksz_read32(dev, REG_SW_PORT_INT_STATUS__4, &data32); } -void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port) +static void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port) { const u32 *masks = dev->info->masks; const u16 *regs = dev->info->regs; @@ -409,7 +409,7 @@ void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port) dev->dev_ops->cfg_port_member(dev, port, member); } -void lan937x_config_cpu_port(struct dsa_switch *ds) +static void lan937x_config_cpu_port(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; struct dsa_port *dp; @@ -428,7 +428,7 @@ void lan937x_config_cpu_port(struct dsa_switch *ds) } } -int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu) +static int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu) { struct dsa_switch *ds = dev->ds; int ret; @@ -459,7 +459,7 @@ int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu) return 0; } -int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs) +static int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs) { u8 data, mult, value8; bool in_msec = false; @@ -572,8 +572,8 @@ static void lan937x_set_rgmii_rx_delay(struct ksz_device *dev, int port) lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_4, val); } -void lan937x_phylink_get_caps(struct ksz_device *dev, int port, - struct phylink_config *config) +static void lan937x_phylink_get_caps(struct ksz_device *dev, int port, + struct phylink_config *config) { config->mac_capabilities = MAC_100FD; @@ -587,7 +587,7 @@ void lan937x_phylink_get_caps(struct ksz_device *dev, int port, } } -void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port) +static void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port) { struct ksz_port *p = &dev->ports[port]; @@ -604,19 +604,19 @@ void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port) } } -int lan937x_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val) +static int lan937x_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val) { return ksz_pwrite32(dev, port, REG_PORT_MTI_CREDIT_INCREMENT, val); } -int lan937x_switch_init(struct ksz_device *dev) +static int lan937x_switch_init(struct ksz_device *dev) { dev->port_mask = (1 << dev->info->port_cnt) - 1; return 0; } -int lan937x_setup(struct dsa_switch *ds) +static int lan937x_setup(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; int ret; @@ -656,16 +656,54 @@ int lan937x_setup(struct dsa_switch *ds) SW_VPHY_DISABLE); } -void lan937x_teardown(struct dsa_switch *ds) +static void lan937x_teardown(struct dsa_switch *ds) { } -void lan937x_switch_exit(struct ksz_device *dev) +static void lan937x_switch_exit(struct ksz_device *dev) { lan937x_reset_switch(dev); } +const struct ksz_dev_ops lan937x_dev_ops = { + .setup = lan937x_setup, + .teardown = lan937x_teardown, + .get_port_addr = ksz9477_get_port_addr, + .cfg_port_member = ksz9477_cfg_port_member, + .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, + .port_setup = lan937x_port_setup, + .set_ageing_time = lan937x_set_ageing_time, + .mdio_bus_preinit = lan937x_mdio_bus_preinit, + .create_phy_addr_map = lan937x_create_phy_addr_map, + .r_phy = lan937x_r_phy, + .w_phy = lan937x_w_phy, + .r_mib_cnt = ksz9477_r_mib_cnt, + .r_mib_pkt = ksz9477_r_mib_pkt, + .r_mib_stat64 = ksz_r_mib_stats64, + .freeze_mib = ksz9477_freeze_mib, + .port_init_cnt = ksz9477_port_init_cnt, + .vlan_filtering = ksz9477_port_vlan_filtering, + .vlan_add = ksz9477_port_vlan_add, + .vlan_del = ksz9477_port_vlan_del, + .mirror_add = ksz9477_port_mirror_add, + .mirror_del = ksz9477_port_mirror_del, + .get_caps = lan937x_phylink_get_caps, + .setup_rgmii_delay = lan937x_setup_rgmii_delay, + .fdb_dump = ksz9477_fdb_dump, + .fdb_add = ksz9477_fdb_add, + .fdb_del = ksz9477_fdb_del, + .mdb_add = ksz9477_mdb_add, + .mdb_del = ksz9477_mdb_del, + .change_mtu = lan937x_change_mtu, + .config_cpu_port = lan937x_config_cpu_port, + .tc_cbs_set_cinc = lan937x_tc_cbs_set_cinc, + .enable_stp_addr = ksz9477_enable_stp_addr, + .reset = lan937x_reset_switch, + .init = lan937x_switch_init, + .exit = lan937x_switch_exit, +}; + MODULE_AUTHOR("Arun Ramadoss "); MODULE_DESCRIPTION("Microchip LAN937x Series Switch DSA Driver"); MODULE_LICENSE("GPL"); From 617bd10450ef1f993e5f56cfce9012311ef90818 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 5 May 2026 16:25:05 +0200 Subject: [PATCH 5/9] net: dsa: microchip: move phylink_mac_ops to individual drivers Similar to ksz_dev_ops, struct phylink_mac_ops shouldn't be part of the common code. Instead, the common code should provide callable functionality. Invert the paradigm and export the common aspects from ksz_common.c, and move the chip-specific stuff in individual drivers. Signed-off-by: Vladimir Oltean Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-5-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz8.c | 36 ++++- drivers/net/dsa/microchip/ksz8.h | 7 +- drivers/net/dsa/microchip/ksz9477.c | 126 +++++++++++++++ drivers/net/dsa/microchip/ksz9477.h | 8 + drivers/net/dsa/microchip/ksz_common.c | 194 ++--------------------- drivers/net/dsa/microchip/ksz_common.h | 10 ++ drivers/net/dsa/microchip/lan937x.h | 1 + drivers/net/dsa/microchip/lan937x_main.c | 8 + 8 files changed, 196 insertions(+), 194 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c index 56560f60223a..f311901c693f 100644 --- a/drivers/net/dsa/microchip/ksz8.c +++ b/drivers/net/dsa/microchip/ksz8.c @@ -1870,10 +1870,12 @@ static void ksz8_cpu_port_link_up(struct ksz_device *dev, int speed, int duplex, SW_10_MBIT, ctrl); } -void ksz8_phylink_mac_link_up(struct phylink_config *config, - struct phy_device *phydev, unsigned int mode, - phy_interface_t interface, int speed, int duplex, - bool tx_pause, bool rx_pause) +static void ksz8_phylink_mac_link_up(struct phylink_config *config, + struct phy_device *phydev, + unsigned int mode, + phy_interface_t interface, + int speed, int duplex, + bool tx_pause, bool rx_pause) { struct dsa_port *dp = dsa_phylink_to_port(config); struct ksz_device *dev = dp->ds->priv; @@ -2097,6 +2099,32 @@ static void ksz8_switch_exit(struct ksz_device *dev) ksz8_reset_switch(dev); } +static void ksz88x3_phylink_mac_config(struct phylink_config *config, + unsigned int mode, + const struct phylink_link_state *state) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + struct ksz_device *dev = dp->ds->priv; + + dev->ports[dp->index].manual_flow = !(state->pause & MLO_PAUSE_AN); +} + +const struct phylink_mac_ops ksz88x3_phylink_mac_ops = { + .mac_config = ksz88x3_phylink_mac_config, + .mac_link_down = ksz_phylink_mac_link_down, + .mac_link_up = ksz8_phylink_mac_link_up, + .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, + .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, +}; + +const struct phylink_mac_ops ksz8_phylink_mac_ops = { + .mac_config = ksz_phylink_mac_config, + .mac_link_down = ksz_phylink_mac_link_down, + .mac_link_up = ksz8_phylink_mac_link_up, + .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, + .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, +}; + const struct ksz_dev_ops ksz8463_dev_ops = { .setup = ksz8_setup, .get_port_addr = ksz8463_get_port_addr, diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h index 4b798ce29daa..2d787d6d96b0 100644 --- a/drivers/net/dsa/microchip/ksz8.h +++ b/drivers/net/dsa/microchip/ksz8.h @@ -12,13 +12,10 @@ #include #include "ksz_common.h" -void ksz8_phylink_mac_link_up(struct phylink_config *config, - struct phy_device *phydev, unsigned int mode, - phy_interface_t interface, int speed, int duplex, - bool tx_pause, bool rx_pause); - extern const struct ksz_dev_ops ksz8463_dev_ops; extern const struct ksz_dev_ops ksz87xx_dev_ops; extern const struct ksz_dev_ops ksz88xx_dev_ops; +extern const struct phylink_mac_ops ksz88x3_phylink_mac_ops; +extern const struct phylink_mac_ops ksz8_phylink_mac_ops; #endif diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 3275996cda96..3fd2174364ac 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1609,6 +1609,132 @@ static void ksz9477_switch_exit(struct ksz_device *dev) ksz9477_reset_switch(dev); } +static void ksz9477_set_gbit(struct ksz_device *dev, int port, bool gbit) +{ + const u8 *bitval = dev->info->xmii_ctrl1; + const u16 *regs = dev->info->regs; + u8 data8; + + ksz_pread8(dev, port, regs[P_XMII_CTRL_1], &data8); + + data8 &= ~P_GMII_1GBIT_M; + + if (gbit) + data8 |= FIELD_PREP(P_GMII_1GBIT_M, bitval[P_GMII_1GBIT]); + else + data8 |= FIELD_PREP(P_GMII_1GBIT_M, bitval[P_GMII_NOT_1GBIT]); + + /* Write the updated value */ + ksz_pwrite8(dev, port, regs[P_XMII_CTRL_1], data8); +} + +static void ksz9477_set_100_10mbit(struct ksz_device *dev, int port, int speed) +{ + const u8 *bitval = dev->info->xmii_ctrl0; + const u16 *regs = dev->info->regs; + u8 data8; + + ksz_pread8(dev, port, regs[P_XMII_CTRL_0], &data8); + + data8 &= ~P_MII_100MBIT_M; + + if (speed == SPEED_100) + data8 |= FIELD_PREP(P_MII_100MBIT_M, bitval[P_MII_100MBIT]); + else + data8 |= FIELD_PREP(P_MII_100MBIT_M, bitval[P_MII_10MBIT]); + + /* Write the updated value */ + ksz_pwrite8(dev, port, regs[P_XMII_CTRL_0], data8); +} + +static void ksz9477_port_set_xmii_speed(struct ksz_device *dev, int port, + int speed) +{ + if (speed == SPEED_1000) + ksz9477_set_gbit(dev, port, true); + else + ksz9477_set_gbit(dev, port, false); + + if (speed == SPEED_100 || speed == SPEED_10) + ksz9477_set_100_10mbit(dev, port, speed); +} + +static void ksz9477_duplex_flowctrl(struct ksz_device *dev, int port, int duplex, + bool tx_pause, bool rx_pause) +{ + const u8 *bitval = dev->info->xmii_ctrl0; + const u32 *masks = dev->info->masks; + const u16 *regs = dev->info->regs; + u8 mask; + u8 val; + + mask = P_MII_DUPLEX_M | masks[P_MII_TX_FLOW_CTRL] | + masks[P_MII_RX_FLOW_CTRL]; + + if (duplex == DUPLEX_FULL) + val = FIELD_PREP(P_MII_DUPLEX_M, bitval[P_MII_FULL_DUPLEX]); + else + val = FIELD_PREP(P_MII_DUPLEX_M, bitval[P_MII_HALF_DUPLEX]); + + if (tx_pause) + val |= masks[P_MII_TX_FLOW_CTRL]; + + if (rx_pause) + val |= masks[P_MII_RX_FLOW_CTRL]; + + ksz_prmw8(dev, port, regs[P_XMII_CTRL_0], mask, val); +} + +void ksz9477_phylink_mac_link_up(struct phylink_config *config, + struct phy_device *phydev, + unsigned int mode, + phy_interface_t interface, + int speed, int duplex, bool tx_pause, + bool rx_pause) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + struct ksz_device *dev = dp->ds->priv; + int port = dp->index; + struct ksz_port *p; + + p = &dev->ports[port]; + + /* Internal PHYs */ + if (dev->info->internal_phy[port]) + return; + + p->speed = speed; + + ksz9477_port_set_xmii_speed(dev, port, speed); + + ksz9477_duplex_flowctrl(dev, port, duplex, tx_pause, rx_pause); +} + +static struct phylink_pcs * +ksz9477_phylink_mac_select_pcs(struct phylink_config *config, + phy_interface_t interface) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + struct ksz_device *dev = dp->ds->priv; + struct ksz_port *p = &dev->ports[dp->index]; + + if (ksz_is_sgmii_port(dev, dp->index) && + (interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_1000BASEX)) + return p->pcs; + + return NULL; +} + +const struct phylink_mac_ops ksz9477_phylink_mac_ops = { + .mac_config = ksz_phylink_mac_config, + .mac_link_down = ksz_phylink_mac_link_down, + .mac_link_up = ksz9477_phylink_mac_link_up, + .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, + .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, + .mac_select_pcs = ksz9477_phylink_mac_select_pcs, +}; + const struct ksz_dev_ops ksz9477_dev_ops = { .setup = ksz9477_setup, .get_port_addr = ksz9477_get_port_addr, diff --git a/drivers/net/dsa/microchip/ksz9477.h b/drivers/net/dsa/microchip/ksz9477.h index 30ab0c8807db..26a91f1a4c87 100644 --- a/drivers/net/dsa/microchip/ksz9477.h +++ b/drivers/net/dsa/microchip/ksz9477.h @@ -84,6 +84,14 @@ void ksz9477_acl_match_process_l2(struct ksz_device *dev, int port, u16 ethtype, u8 *src_mac, u8 *dst_mac, unsigned long cookie, u32 prio); +void ksz9477_phylink_mac_link_up(struct phylink_config *config, + struct phy_device *phydev, + unsigned int mode, + phy_interface_t interface, + int speed, int duplex, bool tx_pause, + bool rx_pause); + extern const struct ksz_dev_ops ksz9477_dev_ops; +extern const struct phylink_mac_ops ksz9477_phylink_mac_ops; #endif diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 88446bc32465..308740829e76 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -256,16 +256,6 @@ static const struct ksz_drive_strength ksz88x3_drive_strengths[] = { { KSZ8873_DRIVE_STRENGTH_16MA, 16000 }, }; -static void ksz88x3_phylink_mac_config(struct phylink_config *config, - unsigned int mode, - const struct phylink_link_state *state); -static void ksz_phylink_mac_config(struct phylink_config *config, - unsigned int mode, - const struct phylink_link_state *state); -static void ksz_phylink_mac_link_down(struct phylink_config *config, - unsigned int mode, - phy_interface_t interface); - /** * ksz_phylink_mac_disable_tx_lpi() - Callback to signal LPI support (Dummy) * @config: phylink config structure @@ -273,7 +263,7 @@ static void ksz_phylink_mac_link_down(struct phylink_config *config, * This function is a dummy handler. See ksz_phylink_mac_enable_tx_lpi() for * a detailed explanation of EEE/LPI handling in KSZ switches. */ -static void ksz_phylink_mac_disable_tx_lpi(struct phylink_config *config) +void ksz_phylink_mac_disable_tx_lpi(struct phylink_config *config) { } @@ -310,68 +300,12 @@ static void ksz_phylink_mac_disable_tx_lpi(struct phylink_config *config) * * Returns: 0 (Always success) */ -static int ksz_phylink_mac_enable_tx_lpi(struct phylink_config *config, - u32 timer, bool tx_clock_stop) +int ksz_phylink_mac_enable_tx_lpi(struct phylink_config *config, + u32 timer, bool tx_clock_stop) { return 0; } -static const struct phylink_mac_ops ksz88x3_phylink_mac_ops = { - .mac_config = ksz88x3_phylink_mac_config, - .mac_link_down = ksz_phylink_mac_link_down, - .mac_link_up = ksz8_phylink_mac_link_up, - .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, - .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, -}; - -static const struct phylink_mac_ops ksz8_phylink_mac_ops = { - .mac_config = ksz_phylink_mac_config, - .mac_link_down = ksz_phylink_mac_link_down, - .mac_link_up = ksz8_phylink_mac_link_up, - .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, - .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, -}; - -static void ksz9477_phylink_mac_link_up(struct phylink_config *config, - struct phy_device *phydev, - unsigned int mode, - phy_interface_t interface, - int speed, int duplex, bool tx_pause, - bool rx_pause); - -static struct phylink_pcs * -ksz_phylink_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) -{ - struct dsa_port *dp = dsa_phylink_to_port(config); - struct ksz_device *dev = dp->ds->priv; - struct ksz_port *p = &dev->ports[dp->index]; - - if (ksz_is_sgmii_port(dev, dp->index) && - (interface == PHY_INTERFACE_MODE_SGMII || - interface == PHY_INTERFACE_MODE_1000BASEX)) - return p->pcs; - - return NULL; -} - -static const struct phylink_mac_ops ksz9477_phylink_mac_ops = { - .mac_config = ksz_phylink_mac_config, - .mac_link_down = ksz_phylink_mac_link_down, - .mac_link_up = ksz9477_phylink_mac_link_up, - .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, - .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, - .mac_select_pcs = ksz_phylink_mac_select_pcs, -}; - -static const struct phylink_mac_ops lan937x_phylink_mac_ops = { - .mac_config = ksz_phylink_mac_config, - .mac_link_down = ksz_phylink_mac_link_down, - .mac_link_up = ksz9477_phylink_mac_link_up, - .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, - .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, -}; - static const u16 ksz8463_regs[] = { [REG_SW_MAC_ADDR] = 0x10, [REG_IND_CTRL_0] = 0x30, @@ -3068,9 +3002,9 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port) return 0; } -static void ksz_phylink_mac_link_down(struct phylink_config *config, - unsigned int mode, - phy_interface_t interface) +void ksz_phylink_mac_link_down(struct phylink_config *config, + unsigned int mode, + phy_interface_t interface) { struct dsa_port *dp = dsa_phylink_to_port(config); struct ksz_device *dev = dp->ds->priv; @@ -3657,19 +3591,9 @@ phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit) return interface; } -static void ksz88x3_phylink_mac_config(struct phylink_config *config, - unsigned int mode, - const struct phylink_link_state *state) -{ - struct dsa_port *dp = dsa_phylink_to_port(config); - struct ksz_device *dev = dp->ds->priv; - - dev->ports[dp->index].manual_flow = !(state->pause & MLO_PAUSE_AN); -} - -static void ksz_phylink_mac_config(struct phylink_config *config, - unsigned int mode, - const struct phylink_link_state *state) +void ksz_phylink_mac_config(struct phylink_config *config, + unsigned int mode, + const struct phylink_link_state *state) { struct dsa_port *dp = dsa_phylink_to_port(config); struct ksz_device *dev = dp->ds->priv; @@ -3712,106 +3636,6 @@ bool ksz_get_gbit(struct ksz_device *dev, int port) return gbit; } -static void ksz_set_gbit(struct ksz_device *dev, int port, bool gbit) -{ - const u8 *bitval = dev->info->xmii_ctrl1; - const u16 *regs = dev->info->regs; - u8 data8; - - ksz_pread8(dev, port, regs[P_XMII_CTRL_1], &data8); - - data8 &= ~P_GMII_1GBIT_M; - - if (gbit) - data8 |= FIELD_PREP(P_GMII_1GBIT_M, bitval[P_GMII_1GBIT]); - else - data8 |= FIELD_PREP(P_GMII_1GBIT_M, bitval[P_GMII_NOT_1GBIT]); - - /* Write the updated value */ - ksz_pwrite8(dev, port, regs[P_XMII_CTRL_1], data8); -} - -static void ksz_set_100_10mbit(struct ksz_device *dev, int port, int speed) -{ - const u8 *bitval = dev->info->xmii_ctrl0; - const u16 *regs = dev->info->regs; - u8 data8; - - ksz_pread8(dev, port, regs[P_XMII_CTRL_0], &data8); - - data8 &= ~P_MII_100MBIT_M; - - if (speed == SPEED_100) - data8 |= FIELD_PREP(P_MII_100MBIT_M, bitval[P_MII_100MBIT]); - else - data8 |= FIELD_PREP(P_MII_100MBIT_M, bitval[P_MII_10MBIT]); - - /* Write the updated value */ - ksz_pwrite8(dev, port, regs[P_XMII_CTRL_0], data8); -} - -static void ksz_port_set_xmii_speed(struct ksz_device *dev, int port, int speed) -{ - if (speed == SPEED_1000) - ksz_set_gbit(dev, port, true); - else - ksz_set_gbit(dev, port, false); - - if (speed == SPEED_100 || speed == SPEED_10) - ksz_set_100_10mbit(dev, port, speed); -} - -static void ksz_duplex_flowctrl(struct ksz_device *dev, int port, int duplex, - bool tx_pause, bool rx_pause) -{ - const u8 *bitval = dev->info->xmii_ctrl0; - const u32 *masks = dev->info->masks; - const u16 *regs = dev->info->regs; - u8 mask; - u8 val; - - mask = P_MII_DUPLEX_M | masks[P_MII_TX_FLOW_CTRL] | - masks[P_MII_RX_FLOW_CTRL]; - - if (duplex == DUPLEX_FULL) - val = FIELD_PREP(P_MII_DUPLEX_M, bitval[P_MII_FULL_DUPLEX]); - else - val = FIELD_PREP(P_MII_DUPLEX_M, bitval[P_MII_HALF_DUPLEX]); - - if (tx_pause) - val |= masks[P_MII_TX_FLOW_CTRL]; - - if (rx_pause) - val |= masks[P_MII_RX_FLOW_CTRL]; - - ksz_prmw8(dev, port, regs[P_XMII_CTRL_0], mask, val); -} - -static void ksz9477_phylink_mac_link_up(struct phylink_config *config, - struct phy_device *phydev, - unsigned int mode, - phy_interface_t interface, - int speed, int duplex, bool tx_pause, - bool rx_pause) -{ - struct dsa_port *dp = dsa_phylink_to_port(config); - struct ksz_device *dev = dp->ds->priv; - int port = dp->index; - struct ksz_port *p; - - p = &dev->ports[port]; - - /* Internal PHYs */ - if (dev->info->internal_phy[port]) - return; - - p->speed = speed; - - ksz_port_set_xmii_speed(dev, port, speed); - - ksz_duplex_flowctrl(dev, port, duplex, tx_pause, rx_pause); -} - static int ksz_switch_detect(struct ksz_device *dev) { u8 id1, id2, id4; diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index cf2d0d91f173..519e080c8910 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -479,6 +479,16 @@ void ksz_switch_macaddr_put(struct dsa_switch *ds); void ksz_switch_shutdown(struct ksz_device *dev); int ksz_handle_wake_reason(struct ksz_device *dev, int port); +void ksz_phylink_mac_disable_tx_lpi(struct phylink_config *config); +int ksz_phylink_mac_enable_tx_lpi(struct phylink_config *config, + u32 timer, bool tx_clock_stop); +void ksz_phylink_mac_config(struct phylink_config *config, + unsigned int mode, + const struct phylink_link_state *state); +void ksz_phylink_mac_link_down(struct phylink_config *config, + unsigned int mode, + phy_interface_t interface); + /* Common register access functions */ static inline struct regmap *ksz_regmap_8(struct ksz_device *dev) { diff --git a/drivers/net/dsa/microchip/lan937x.h b/drivers/net/dsa/microchip/lan937x.h index 48fc49775094..c5e745a9f47f 100644 --- a/drivers/net/dsa/microchip/lan937x.h +++ b/drivers/net/dsa/microchip/lan937x.h @@ -7,5 +7,6 @@ #define __LAN937X_CFG_H extern const struct ksz_dev_ops lan937x_dev_ops; +extern const struct phylink_mac_ops lan937x_phylink_mac_ops; #endif diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index ced381f67392..4846ae2a2d69 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -666,6 +666,14 @@ static void lan937x_switch_exit(struct ksz_device *dev) lan937x_reset_switch(dev); } +const struct phylink_mac_ops lan937x_phylink_mac_ops = { + .mac_config = ksz_phylink_mac_config, + .mac_link_down = ksz_phylink_mac_link_down, + .mac_link_up = ksz9477_phylink_mac_link_up, + .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, + .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, +}; + const struct ksz_dev_ops lan937x_dev_ops = { .setup = lan937x_setup, .teardown = lan937x_teardown, From a774b19c117d76552054cf3d771220bc2d896dd0 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 5 May 2026 16:25:06 +0200 Subject: [PATCH 6/9] net: dsa: microchip: ensure each ksz_dev_ops has its own dsa_switch_ops Currently we have a single dsa_switch_ops for 4 very distinct families of switches, and many dsa_switch_ops methods are simply a dispatches through ksz_dev_ops. That creates an avoidable level of indirection. As a preparation for removing that indirection layer, create a separate dsa_switch_ops structure wherever we have a ksz_dev_ops. These structures are not yet used - ksz_switch_ops from ksz_common.c still is. However, this reduces the noise from subsequent changes. All new dsa_switch_ops are exact copies of ksz_switch_ops. But we need to export function prototypes from ksz_common.c so that they are callable from individual drivers. Note that "individual drivers" are not actual separate kernel modules. All of ksz8.c, ksz9477.c and lan937x_main.c are part of the same ksz_switch.ko. Only the "register interface" drivers are different modules (ksz9477_i2c.o for I2C, ksz_spi.o for SPI, ksz8863_smi.o for MDIO). So we don't need to export any symbol. Signed-off-by: Vladimir Oltean Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-6-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz8.c | 184 +++++++++++++++++++++ drivers/net/dsa/microchip/ksz8.h | 3 + drivers/net/dsa/microchip/ksz9477.c | 62 ++++++++ drivers/net/dsa/microchip/ksz9477.h | 1 + drivers/net/dsa/microchip/ksz_common.c | 193 +++++++++++++---------- drivers/net/dsa/microchip/ksz_common.h | 96 +++++++++++ drivers/net/dsa/microchip/lan937x.h | 1 + drivers/net/dsa/microchip/lan937x_main.c | 62 ++++++++ 8 files changed, 516 insertions(+), 86 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c index f311901c693f..f7801269b11a 100644 --- a/drivers/net/dsa/microchip/ksz8.c +++ b/drivers/net/dsa/microchip/ksz8.c @@ -31,6 +31,7 @@ #include #include "ksz_common.h" +#include "ksz_dcb.h" #include "ksz8_reg.h" #include "ksz8.h" @@ -2227,6 +2228,189 @@ const struct ksz_dev_ops ksz88xx_dev_ops = { .pme_pwrite8 = ksz8_pme_pwrite8, }; +const struct dsa_switch_ops ksz8463_switch_ops = { + .get_tag_protocol = ksz_get_tag_protocol, + .connect_tag_protocol = ksz_connect_tag_protocol, + .get_phy_flags = ksz_get_phy_flags, + .setup = ksz_setup, + .teardown = ksz_teardown, + .phy_read = ksz_phy_read16, + .phy_write = ksz_phy_write16, + .phylink_get_caps = ksz_phylink_get_caps, + .port_setup = ksz_port_setup, + .set_ageing_time = ksz_set_ageing_time, + .get_strings = ksz_get_strings, + .get_ethtool_stats = ksz_get_ethtool_stats, + .get_sset_count = ksz_sset_count, + .port_bridge_join = ksz_port_bridge_join, + .port_bridge_leave = ksz_port_bridge_leave, + .port_hsr_join = ksz_hsr_join, + .port_hsr_leave = ksz_hsr_leave, + .port_set_mac_address = ksz_port_set_mac_address, + .port_stp_state_set = ksz_port_stp_state_set, + .port_teardown = ksz_port_teardown, + .port_pre_bridge_flags = ksz_port_pre_bridge_flags, + .port_bridge_flags = ksz_port_bridge_flags, + .port_fast_age = ksz_port_fast_age, + .port_vlan_filtering = ksz_port_vlan_filtering, + .port_vlan_add = ksz_port_vlan_add, + .port_vlan_del = ksz_port_vlan_del, + .port_fdb_dump = ksz_port_fdb_dump, + .port_fdb_add = ksz_port_fdb_add, + .port_fdb_del = ksz_port_fdb_del, + .port_mdb_add = ksz_port_mdb_add, + .port_mdb_del = ksz_port_mdb_del, + .port_mirror_add = ksz_port_mirror_add, + .port_mirror_del = ksz_port_mirror_del, + .get_stats64 = ksz_get_stats64, + .get_pause_stats = ksz_get_pause_stats, + .port_change_mtu = ksz_change_mtu, + .port_max_mtu = ksz_max_mtu, + .get_wol = ksz_get_wol, + .set_wol = ksz_set_wol, + .suspend = ksz_suspend, + .resume = ksz_resume, + .get_ts_info = ksz_get_ts_info, + .port_hwtstamp_get = ksz_hwtstamp_get, + .port_hwtstamp_set = ksz_hwtstamp_set, + .port_txtstamp = ksz_port_txtstamp, + .port_rxtstamp = ksz_port_rxtstamp, + .cls_flower_add = ksz_cls_flower_add, + .cls_flower_del = ksz_cls_flower_del, + .port_setup_tc = ksz_setup_tc, + .support_eee = ksz_support_eee, + .set_mac_eee = ksz_set_mac_eee, + .port_get_default_prio = ksz_port_get_default_prio, + .port_set_default_prio = ksz_port_set_default_prio, + .port_get_dscp_prio = ksz_port_get_dscp_prio, + .port_add_dscp_prio = ksz_port_add_dscp_prio, + .port_del_dscp_prio = ksz_port_del_dscp_prio, + .port_get_apptrust = ksz_port_get_apptrust, + .port_set_apptrust = ksz_port_set_apptrust, +}; + +const struct dsa_switch_ops ksz87xx_switch_ops = { + .get_tag_protocol = ksz_get_tag_protocol, + .connect_tag_protocol = ksz_connect_tag_protocol, + .get_phy_flags = ksz_get_phy_flags, + .setup = ksz_setup, + .teardown = ksz_teardown, + .phy_read = ksz_phy_read16, + .phy_write = ksz_phy_write16, + .phylink_get_caps = ksz_phylink_get_caps, + .port_setup = ksz_port_setup, + .set_ageing_time = ksz_set_ageing_time, + .get_strings = ksz_get_strings, + .get_ethtool_stats = ksz_get_ethtool_stats, + .get_sset_count = ksz_sset_count, + .port_bridge_join = ksz_port_bridge_join, + .port_bridge_leave = ksz_port_bridge_leave, + .port_hsr_join = ksz_hsr_join, + .port_hsr_leave = ksz_hsr_leave, + .port_set_mac_address = ksz_port_set_mac_address, + .port_stp_state_set = ksz_port_stp_state_set, + .port_teardown = ksz_port_teardown, + .port_pre_bridge_flags = ksz_port_pre_bridge_flags, + .port_bridge_flags = ksz_port_bridge_flags, + .port_fast_age = ksz_port_fast_age, + .port_vlan_filtering = ksz_port_vlan_filtering, + .port_vlan_add = ksz_port_vlan_add, + .port_vlan_del = ksz_port_vlan_del, + .port_fdb_dump = ksz_port_fdb_dump, + .port_fdb_add = ksz_port_fdb_add, + .port_fdb_del = ksz_port_fdb_del, + .port_mdb_add = ksz_port_mdb_add, + .port_mdb_del = ksz_port_mdb_del, + .port_mirror_add = ksz_port_mirror_add, + .port_mirror_del = ksz_port_mirror_del, + .get_stats64 = ksz_get_stats64, + .get_pause_stats = ksz_get_pause_stats, + .port_change_mtu = ksz_change_mtu, + .port_max_mtu = ksz_max_mtu, + .get_wol = ksz_get_wol, + .set_wol = ksz_set_wol, + .suspend = ksz_suspend, + .resume = ksz_resume, + .get_ts_info = ksz_get_ts_info, + .port_hwtstamp_get = ksz_hwtstamp_get, + .port_hwtstamp_set = ksz_hwtstamp_set, + .port_txtstamp = ksz_port_txtstamp, + .port_rxtstamp = ksz_port_rxtstamp, + .cls_flower_add = ksz_cls_flower_add, + .cls_flower_del = ksz_cls_flower_del, + .port_setup_tc = ksz_setup_tc, + .support_eee = ksz_support_eee, + .set_mac_eee = ksz_set_mac_eee, + .port_get_default_prio = ksz_port_get_default_prio, + .port_set_default_prio = ksz_port_set_default_prio, + .port_get_dscp_prio = ksz_port_get_dscp_prio, + .port_add_dscp_prio = ksz_port_add_dscp_prio, + .port_del_dscp_prio = ksz_port_del_dscp_prio, + .port_get_apptrust = ksz_port_get_apptrust, + .port_set_apptrust = ksz_port_set_apptrust, +}; + +const struct dsa_switch_ops ksz88xx_switch_ops = { + .get_tag_protocol = ksz_get_tag_protocol, + .connect_tag_protocol = ksz_connect_tag_protocol, + .get_phy_flags = ksz_get_phy_flags, + .setup = ksz_setup, + .teardown = ksz_teardown, + .phy_read = ksz_phy_read16, + .phy_write = ksz_phy_write16, + .phylink_get_caps = ksz_phylink_get_caps, + .port_setup = ksz_port_setup, + .set_ageing_time = ksz_set_ageing_time, + .get_strings = ksz_get_strings, + .get_ethtool_stats = ksz_get_ethtool_stats, + .get_sset_count = ksz_sset_count, + .port_bridge_join = ksz_port_bridge_join, + .port_bridge_leave = ksz_port_bridge_leave, + .port_hsr_join = ksz_hsr_join, + .port_hsr_leave = ksz_hsr_leave, + .port_set_mac_address = ksz_port_set_mac_address, + .port_stp_state_set = ksz_port_stp_state_set, + .port_teardown = ksz_port_teardown, + .port_pre_bridge_flags = ksz_port_pre_bridge_flags, + .port_bridge_flags = ksz_port_bridge_flags, + .port_fast_age = ksz_port_fast_age, + .port_vlan_filtering = ksz_port_vlan_filtering, + .port_vlan_add = ksz_port_vlan_add, + .port_vlan_del = ksz_port_vlan_del, + .port_fdb_dump = ksz_port_fdb_dump, + .port_fdb_add = ksz_port_fdb_add, + .port_fdb_del = ksz_port_fdb_del, + .port_mdb_add = ksz_port_mdb_add, + .port_mdb_del = ksz_port_mdb_del, + .port_mirror_add = ksz_port_mirror_add, + .port_mirror_del = ksz_port_mirror_del, + .get_stats64 = ksz_get_stats64, + .get_pause_stats = ksz_get_pause_stats, + .port_change_mtu = ksz_change_mtu, + .port_max_mtu = ksz_max_mtu, + .get_wol = ksz_get_wol, + .set_wol = ksz_set_wol, + .suspend = ksz_suspend, + .resume = ksz_resume, + .get_ts_info = ksz_get_ts_info, + .port_hwtstamp_get = ksz_hwtstamp_get, + .port_hwtstamp_set = ksz_hwtstamp_set, + .port_txtstamp = ksz_port_txtstamp, + .port_rxtstamp = ksz_port_rxtstamp, + .cls_flower_add = ksz_cls_flower_add, + .cls_flower_del = ksz_cls_flower_del, + .port_setup_tc = ksz_setup_tc, + .support_eee = ksz_support_eee, + .set_mac_eee = ksz_set_mac_eee, + .port_get_default_prio = ksz_port_get_default_prio, + .port_set_default_prio = ksz_port_set_default_prio, + .port_get_dscp_prio = ksz_port_get_dscp_prio, + .port_add_dscp_prio = ksz_port_add_dscp_prio, + .port_del_dscp_prio = ksz_port_del_dscp_prio, + .port_get_apptrust = ksz_port_get_apptrust, + .port_set_apptrust = ksz_port_set_apptrust, +}; + MODULE_AUTHOR("Tristram Ha "); MODULE_DESCRIPTION("Microchip KSZ8795 Series Switch DSA Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h index 2d787d6d96b0..bc371cc26c6f 100644 --- a/drivers/net/dsa/microchip/ksz8.h +++ b/drivers/net/dsa/microchip/ksz8.h @@ -17,5 +17,8 @@ extern const struct ksz_dev_ops ksz87xx_dev_ops; extern const struct ksz_dev_ops ksz88xx_dev_ops; extern const struct phylink_mac_ops ksz88x3_phylink_mac_ops; extern const struct phylink_mac_ops ksz8_phylink_mac_ops; +extern const struct dsa_switch_ops ksz8463_switch_ops; +extern const struct dsa_switch_ops ksz87xx_switch_ops; +extern const struct dsa_switch_ops ksz88xx_switch_ops; #endif diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 3fd2174364ac..9fb0169b5e29 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -17,6 +17,7 @@ #include "ksz9477_reg.h" #include "ksz_common.h" +#include "ksz_dcb.h" #include "ksz9477.h" static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set) @@ -1773,6 +1774,67 @@ const struct ksz_dev_ops ksz9477_dev_ops = { .pcs_create = ksz9477_pcs_create, }; +const struct dsa_switch_ops ksz9477_switch_ops = { + .get_tag_protocol = ksz_get_tag_protocol, + .connect_tag_protocol = ksz_connect_tag_protocol, + .get_phy_flags = ksz_get_phy_flags, + .setup = ksz_setup, + .teardown = ksz_teardown, + .phy_read = ksz_phy_read16, + .phy_write = ksz_phy_write16, + .phylink_get_caps = ksz_phylink_get_caps, + .port_setup = ksz_port_setup, + .set_ageing_time = ksz_set_ageing_time, + .get_strings = ksz_get_strings, + .get_ethtool_stats = ksz_get_ethtool_stats, + .get_sset_count = ksz_sset_count, + .port_bridge_join = ksz_port_bridge_join, + .port_bridge_leave = ksz_port_bridge_leave, + .port_hsr_join = ksz_hsr_join, + .port_hsr_leave = ksz_hsr_leave, + .port_set_mac_address = ksz_port_set_mac_address, + .port_stp_state_set = ksz_port_stp_state_set, + .port_teardown = ksz_port_teardown, + .port_pre_bridge_flags = ksz_port_pre_bridge_flags, + .port_bridge_flags = ksz_port_bridge_flags, + .port_fast_age = ksz_port_fast_age, + .port_vlan_filtering = ksz_port_vlan_filtering, + .port_vlan_add = ksz_port_vlan_add, + .port_vlan_del = ksz_port_vlan_del, + .port_fdb_dump = ksz_port_fdb_dump, + .port_fdb_add = ksz_port_fdb_add, + .port_fdb_del = ksz_port_fdb_del, + .port_mdb_add = ksz_port_mdb_add, + .port_mdb_del = ksz_port_mdb_del, + .port_mirror_add = ksz_port_mirror_add, + .port_mirror_del = ksz_port_mirror_del, + .get_stats64 = ksz_get_stats64, + .get_pause_stats = ksz_get_pause_stats, + .port_change_mtu = ksz_change_mtu, + .port_max_mtu = ksz_max_mtu, + .get_wol = ksz_get_wol, + .set_wol = ksz_set_wol, + .suspend = ksz_suspend, + .resume = ksz_resume, + .get_ts_info = ksz_get_ts_info, + .port_hwtstamp_get = ksz_hwtstamp_get, + .port_hwtstamp_set = ksz_hwtstamp_set, + .port_txtstamp = ksz_port_txtstamp, + .port_rxtstamp = ksz_port_rxtstamp, + .cls_flower_add = ksz_cls_flower_add, + .cls_flower_del = ksz_cls_flower_del, + .port_setup_tc = ksz_setup_tc, + .support_eee = ksz_support_eee, + .set_mac_eee = ksz_set_mac_eee, + .port_get_default_prio = ksz_port_get_default_prio, + .port_set_default_prio = ksz_port_set_default_prio, + .port_get_dscp_prio = ksz_port_get_dscp_prio, + .port_add_dscp_prio = ksz_port_add_dscp_prio, + .port_del_dscp_prio = ksz_port_del_dscp_prio, + .port_get_apptrust = ksz_port_get_apptrust, + .port_set_apptrust = ksz_port_set_apptrust, +}; + MODULE_AUTHOR("Woojung Huh "); MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch DSA Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/dsa/microchip/ksz9477.h b/drivers/net/dsa/microchip/ksz9477.h index 26a91f1a4c87..bacadcbc478c 100644 --- a/drivers/net/dsa/microchip/ksz9477.h +++ b/drivers/net/dsa/microchip/ksz9477.h @@ -93,5 +93,6 @@ void ksz9477_phylink_mac_link_up(struct phylink_config *config, extern const struct ksz_dev_ops ksz9477_dev_ops; extern const struct phylink_mac_ops ksz9477_phylink_mac_ops; +extern const struct dsa_switch_ops ksz9477_switch_ops; #endif diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 308740829e76..e48b9d5c0630 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -1258,6 +1258,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 4, .ops = &ksz8463_dev_ops, + .switch_ops = &ksz8463_switch_ops, .phylink_mac_ops = &ksz88x3_phylink_mac_ops, .mib_names = ksz88xx_mib_names, .mib_cnt = ARRAY_SIZE(ksz88xx_mib_names), @@ -1283,6 +1284,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_ipms = 8, .tc_cbs_supported = true, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .phylink_mac_ops = &ksz9477_phylink_mac_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1313,6 +1315,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 4, .ops = &ksz87xx_dev_ops, + .switch_ops = &ksz87xx_switch_ops, .phylink_mac_ops = &ksz8_phylink_mac_ops, .ksz87xx_eee_link_erratum = true, .mib_names = ksz9477_mib_names, @@ -1354,6 +1357,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 4, .ops = &ksz87xx_dev_ops, + .switch_ops = &ksz87xx_switch_ops, .phylink_mac_ops = &ksz8_phylink_mac_ops, .ksz87xx_eee_link_erratum = true, .mib_names = ksz9477_mib_names, @@ -1381,6 +1385,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 4, .ops = &ksz87xx_dev_ops, + .switch_ops = &ksz87xx_switch_ops, .phylink_mac_ops = &ksz8_phylink_mac_ops, .ksz87xx_eee_link_erratum = true, .mib_names = ksz9477_mib_names, @@ -1408,6 +1413,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 4, .ops = &ksz88xx_dev_ops, + .switch_ops = &ksz88xx_switch_ops, .phylink_mac_ops = &ksz88x3_phylink_mac_ops, .mib_names = ksz88xx_mib_names, .mib_cnt = ARRAY_SIZE(ksz88xx_mib_names), @@ -1442,6 +1448,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 4, .ops = &ksz88xx_dev_ops, + .switch_ops = &ksz88xx_switch_ops, .phylink_mac_ops = &ksz88x3_phylink_mac_ops, .mib_names = ksz88xx_mib_names, .mib_cnt = ARRAY_SIZE(ksz88xx_mib_names), @@ -1465,6 +1472,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 4, .ops = &ksz88xx_dev_ops, + .switch_ops = &ksz88xx_switch_ops, .phylink_mac_ops = &ksz88x3_phylink_mac_ops, .mib_names = ksz88xx_mib_names, .mib_cnt = ARRAY_SIZE(ksz88xx_mib_names), @@ -1490,6 +1498,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_ipms = 8, .tc_cbs_supported = true, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .phylink_mac_ops = &ksz9477_phylink_mac_ops, .phy_errata_9477 = true, .mib_names = ksz9477_mib_names, @@ -1527,6 +1536,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 8, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .phylink_mac_ops = &ksz9477_phylink_mac_ops, .phy_errata_9477 = true, .mib_names = ksz9477_mib_names, @@ -1562,6 +1572,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 8, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .phylink_mac_ops = &ksz9477_phylink_mac_ops, .phy_errata_9477 = true, .mib_names = ksz9477_mib_names, @@ -1595,6 +1606,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 8, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .phylink_mac_ops = &ksz9477_phylink_mac_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1624,6 +1636,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_ipms = 8, .tc_cbs_supported = true, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .phylink_mac_ops = &ksz9477_phylink_mac_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1654,6 +1667,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_ipms = 8, .tc_cbs_supported = true, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .phylink_mac_ops = &ksz9477_phylink_mac_ops, .phy_errata_9477 = true, .mib_names = ksz9477_mib_names, @@ -1690,6 +1704,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_ipms = 8, .tc_cbs_supported = true, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), .reg_mib_cnt = MIB_COUNTER_NUM, @@ -1724,6 +1739,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .tc_cbs_supported = true, .phy_side_mdio_supported = true, .ops = &lan937x_dev_ops, + .switch_ops = &lan937x_switch_ops, .phylink_mac_ops = &lan937x_phylink_mac_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1754,6 +1770,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .tc_cbs_supported = true, .phy_side_mdio_supported = true, .ops = &lan937x_dev_ops, + .switch_ops = &lan937x_switch_ops, .phylink_mac_ops = &lan937x_phylink_mac_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1784,6 +1801,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .tc_cbs_supported = true, .phy_side_mdio_supported = true, .ops = &lan937x_dev_ops, + .switch_ops = &lan937x_switch_ops, .phylink_mac_ops = &lan937x_phylink_mac_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1818,6 +1836,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .tc_cbs_supported = true, .phy_side_mdio_supported = true, .ops = &lan937x_dev_ops, + .switch_ops = &lan937x_switch_ops, .phylink_mac_ops = &lan937x_phylink_mac_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1852,6 +1871,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .tc_cbs_supported = true, .phy_side_mdio_supported = true, .ops = &lan937x_dev_ops, + .switch_ops = &lan937x_switch_ops, .phylink_mac_ops = &lan937x_phylink_mac_ops, .mib_names = ksz9477_mib_names, .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1884,6 +1904,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .num_tx_queues = 4, .num_ipms = 8, .ops = &ksz9477_dev_ops, + .switch_ops = &ksz9477_switch_ops, .phylink_mac_ops = &ksz9477_phylink_mac_ops, .phy_errata_9477 = true, .mib_names = ksz9477_mib_names, @@ -1949,8 +1970,8 @@ static int ksz_check_device_id(struct ksz_device *dev) return 0; } -static void ksz_phylink_get_caps(struct dsa_switch *ds, int port, - struct phylink_config *config) +void ksz_phylink_get_caps(struct dsa_switch *ds, int port, + struct phylink_config *config) { struct ksz_device *dev = ds->priv; @@ -2095,8 +2116,8 @@ void ksz88xx_r_mib_stats64(struct ksz_device *dev, int port) spin_unlock(&mib->stats64_lock); } -static void ksz_get_stats64(struct dsa_switch *ds, int port, - struct rtnl_link_stats64 *s) +void ksz_get_stats64(struct dsa_switch *ds, int port, + struct rtnl_link_stats64 *s) { struct ksz_device *dev = ds->priv; struct ksz_port_mib *mib; @@ -2108,8 +2129,8 @@ static void ksz_get_stats64(struct dsa_switch *ds, int port, spin_unlock(&mib->stats64_lock); } -static void ksz_get_pause_stats(struct dsa_switch *ds, int port, - struct ethtool_pause_stats *pause_stats) +void ksz_get_pause_stats(struct dsa_switch *ds, int port, + struct ethtool_pause_stats *pause_stats) { struct ksz_device *dev = ds->priv; struct ksz_port_mib *mib; @@ -2121,8 +2142,8 @@ static void ksz_get_pause_stats(struct dsa_switch *ds, int port, spin_unlock(&mib->stats64_lock); } -static void ksz_get_strings(struct dsa_switch *ds, int port, - u32 stringset, uint8_t *buf) +void ksz_get_strings(struct dsa_switch *ds, int port, + u32 stringset, uint8_t *buf) { struct ksz_device *dev = ds->priv; int i; @@ -2729,7 +2750,7 @@ static int ksz_pirq_setup(struct ksz_device *dev, u8 p) static int ksz_parse_drive_strength(struct ksz_device *dev); -static int ksz_setup(struct dsa_switch *ds) +int ksz_setup(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; u16 storm_mask, storm_rate; @@ -2859,7 +2880,7 @@ static int ksz_setup(struct dsa_switch *ds) return ret; } -static void ksz_teardown(struct dsa_switch *ds) +void ksz_teardown(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; struct dsa_port *dp; @@ -2959,7 +2980,7 @@ void ksz_init_mib_timer(struct ksz_device *dev) } } -static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg) +int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg) { struct ksz_device *dev = ds->priv; u16 val = 0xffff; @@ -2972,7 +2993,7 @@ static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg) return val; } -static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val) +int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val) { struct ksz_device *dev = ds->priv; int ret; @@ -2984,7 +3005,7 @@ static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val) return 0; } -static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port) +u32 ksz_get_phy_flags(struct dsa_switch *ds, int port) { struct ksz_device *dev = ds->priv; @@ -3016,7 +3037,7 @@ void ksz_phylink_mac_link_down(struct phylink_config *config, schedule_delayed_work(&dev->mib_read, 0); } -static int ksz_sset_count(struct dsa_switch *ds, int port, int sset) +int ksz_sset_count(struct dsa_switch *ds, int port, int sset) { struct ksz_device *dev = ds->priv; @@ -3026,8 +3047,8 @@ static int ksz_sset_count(struct dsa_switch *ds, int port, int sset) return dev->info->mib_cnt; } -static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, - uint64_t *buf) +void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, + uint64_t *buf) { const struct dsa_port *dp = dsa_to_port(ds, port); struct ksz_device *dev = ds->priv; @@ -3044,10 +3065,10 @@ static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, mutex_unlock(&mib->cnt_mutex); } -static int ksz_port_bridge_join(struct dsa_switch *ds, int port, - struct dsa_bridge bridge, - bool *tx_fwd_offload, - struct netlink_ext_ack *extack) +int ksz_port_bridge_join(struct dsa_switch *ds, int port, + struct dsa_bridge bridge, + bool *tx_fwd_offload, + struct netlink_ext_ack *extack) { /* port_stp_state_set() will be called after to put the port in * appropriate state so there is no need to do anything. @@ -3056,22 +3077,22 @@ static int ksz_port_bridge_join(struct dsa_switch *ds, int port, return 0; } -static void ksz_port_bridge_leave(struct dsa_switch *ds, int port, - struct dsa_bridge bridge) +void ksz_port_bridge_leave(struct dsa_switch *ds, int port, + struct dsa_bridge bridge) { /* port_stp_state_set() will be called after to put the port in * forwarding state so there is no need to do anything. */ } -static void ksz_port_fast_age(struct dsa_switch *ds, int port) +void ksz_port_fast_age(struct dsa_switch *ds, int port) { struct ksz_device *dev = ds->priv; dev->dev_ops->flush_dyn_mac_table(dev, port); } -static int ksz_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) +int ksz_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) { struct ksz_device *dev = ds->priv; @@ -3081,9 +3102,9 @@ static int ksz_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) return dev->dev_ops->set_ageing_time(dev, msecs); } -static int ksz_port_fdb_add(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid, - struct dsa_db db) +int ksz_port_fdb_add(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) { struct ksz_device *dev = ds->priv; @@ -3093,9 +3114,9 @@ static int ksz_port_fdb_add(struct dsa_switch *ds, int port, return dev->dev_ops->fdb_add(dev, port, addr, vid, db); } -static int ksz_port_fdb_del(struct dsa_switch *ds, int port, - const unsigned char *addr, - u16 vid, struct dsa_db db) +int ksz_port_fdb_del(struct dsa_switch *ds, int port, + const unsigned char *addr, + u16 vid, struct dsa_db db) { struct ksz_device *dev = ds->priv; @@ -3105,8 +3126,8 @@ static int ksz_port_fdb_del(struct dsa_switch *ds, int port, return dev->dev_ops->fdb_del(dev, port, addr, vid, db); } -static int ksz_port_fdb_dump(struct dsa_switch *ds, int port, - dsa_fdb_dump_cb_t *cb, void *data) +int ksz_port_fdb_dump(struct dsa_switch *ds, int port, + dsa_fdb_dump_cb_t *cb, void *data) { struct ksz_device *dev = ds->priv; @@ -3116,9 +3137,9 @@ static int ksz_port_fdb_dump(struct dsa_switch *ds, int port, return dev->dev_ops->fdb_dump(dev, port, cb, data); } -static int ksz_port_mdb_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_mdb *mdb, - struct dsa_db db) +int ksz_port_mdb_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db) { struct ksz_device *dev = ds->priv; @@ -3128,9 +3149,9 @@ static int ksz_port_mdb_add(struct dsa_switch *ds, int port, return dev->dev_ops->mdb_add(dev, port, mdb, db); } -static int ksz_port_mdb_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_mdb *mdb, - struct dsa_db db) +int ksz_port_mdb_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db) { struct ksz_device *dev = ds->priv; @@ -3163,7 +3184,7 @@ static int ksz9477_set_default_prio_queue_mapping(struct ksz_device *dev, return ksz_pwrite32(dev, port, KSZ9477_PORT_MRI_TC_MAP__4, queue_map); } -static int ksz_port_setup(struct dsa_switch *ds, int port) +int ksz_port_setup(struct dsa_switch *ds, int port) { struct ksz_device *dev = ds->priv; int ret; @@ -3233,7 +3254,7 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) ksz_update_port_member(dev, port); } -static void ksz_port_teardown(struct dsa_switch *ds, int port) +void ksz_port_teardown(struct dsa_switch *ds, int port) { struct ksz_device *dev = ds->priv; @@ -3252,9 +3273,9 @@ static void ksz_port_teardown(struct dsa_switch *ds, int port) } } -static int ksz_port_pre_bridge_flags(struct dsa_switch *ds, int port, - struct switchdev_brport_flags flags, - struct netlink_ext_ack *extack) +int ksz_port_pre_bridge_flags(struct dsa_switch *ds, int port, + struct switchdev_brport_flags flags, + struct netlink_ext_ack *extack) { if (flags.mask & ~(BR_LEARNING | BR_ISOLATED)) return -EINVAL; @@ -3262,9 +3283,9 @@ static int ksz_port_pre_bridge_flags(struct dsa_switch *ds, int port, return 0; } -static int ksz_port_bridge_flags(struct dsa_switch *ds, int port, - struct switchdev_brport_flags flags, - struct netlink_ext_ack *extack) +int ksz_port_bridge_flags(struct dsa_switch *ds, int port, + struct switchdev_brport_flags flags, + struct netlink_ext_ack *extack) { struct ksz_device *dev = ds->priv; struct ksz_port *p = &dev->ports[port]; @@ -3283,9 +3304,9 @@ static int ksz_port_bridge_flags(struct dsa_switch *ds, int port, return 0; } -static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, - int port, - enum dsa_tag_protocol mp) +enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp) { struct ksz_device *dev = ds->priv; enum dsa_tag_protocol proto = DSA_TAG_PROTO_NONE; @@ -3314,8 +3335,8 @@ static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, return proto; } -static int ksz_connect_tag_protocol(struct dsa_switch *ds, - enum dsa_tag_protocol proto) +int ksz_connect_tag_protocol(struct dsa_switch *ds, + enum dsa_tag_protocol proto) { struct ksz_tagger_data *tagger_data; @@ -3333,8 +3354,8 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds, } } -static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, - bool flag, struct netlink_ext_ack *extack) +int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, + bool flag, struct netlink_ext_ack *extack) { struct ksz_device *dev = ds->priv; @@ -3344,9 +3365,9 @@ static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, return dev->dev_ops->vlan_filtering(dev, port, flag, extack); } -static int ksz_port_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack) +int ksz_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack) { struct ksz_device *dev = ds->priv; @@ -3356,8 +3377,8 @@ static int ksz_port_vlan_add(struct dsa_switch *ds, int port, return dev->dev_ops->vlan_add(dev, port, vlan, extack); } -static int ksz_port_vlan_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan) +int ksz_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) { struct ksz_device *dev = ds->priv; @@ -3367,9 +3388,9 @@ static int ksz_port_vlan_del(struct dsa_switch *ds, int port, return dev->dev_ops->vlan_del(dev, port, vlan); } -static int ksz_port_mirror_add(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress, struct netlink_ext_ack *extack) +int ksz_port_mirror_add(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror, + bool ingress, struct netlink_ext_ack *extack) { struct ksz_device *dev = ds->priv; @@ -3379,8 +3400,8 @@ static int ksz_port_mirror_add(struct dsa_switch *ds, int port, return dev->dev_ops->mirror_add(dev, port, mirror, ingress, extack); } -static void ksz_port_mirror_del(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror) +void ksz_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror) { struct ksz_device *dev = ds->priv; @@ -3388,7 +3409,7 @@ static void ksz_port_mirror_del(struct dsa_switch *ds, int port, dev->dev_ops->mirror_del(dev, port, mirror); } -static int ksz_change_mtu(struct dsa_switch *ds, int port, int mtu) +int ksz_change_mtu(struct dsa_switch *ds, int port, int mtu) { struct ksz_device *dev = ds->priv; @@ -3398,7 +3419,7 @@ static int ksz_change_mtu(struct dsa_switch *ds, int port, int mtu) return dev->dev_ops->change_mtu(dev, port, mtu); } -static int ksz_max_mtu(struct dsa_switch *ds, int port) +int ksz_max_mtu(struct dsa_switch *ds, int port) { struct ksz_device *dev = ds->priv; @@ -3446,7 +3467,7 @@ static int ksz_max_mtu(struct dsa_switch *ds, int port) * Returns: true if the internal PHY on the given port supports fully * operational EEE, false otherwise. */ -static bool ksz_support_eee(struct dsa_switch *ds, int port) +bool ksz_support_eee(struct dsa_switch *ds, int port) { struct ksz_device *dev = ds->priv; @@ -3489,8 +3510,8 @@ static bool ksz_support_eee(struct dsa_switch *ds, int port) return false; } -static int ksz_set_mac_eee(struct dsa_switch *ds, int port, - struct ethtool_keee *e) +int ksz_set_mac_eee(struct dsa_switch *ds, int port, + struct ethtool_keee *e) { struct ksz_device *dev = ds->priv; @@ -3735,8 +3756,8 @@ static int ksz_switch_detect(struct ksz_device *dev) return 0; } -static int ksz_cls_flower_add(struct dsa_switch *ds, int port, - struct flow_cls_offload *cls, bool ingress) +int ksz_cls_flower_add(struct dsa_switch *ds, int port, + struct flow_cls_offload *cls, bool ingress) { struct ksz_device *dev = ds->priv; @@ -3756,8 +3777,8 @@ static int ksz_cls_flower_add(struct dsa_switch *ds, int port, return -EOPNOTSUPP; } -static int ksz_cls_flower_del(struct dsa_switch *ds, int port, - struct flow_cls_offload *cls, bool ingress) +int ksz_cls_flower_del(struct dsa_switch *ds, int port, + struct flow_cls_offload *cls, bool ingress) { struct ksz_device *dev = ds->priv; @@ -4160,8 +4181,8 @@ static int ksz_tc_setup_qdisc_ets(struct dsa_switch *ds, int port, return -EOPNOTSUPP; } -static int ksz_setup_tc(struct dsa_switch *ds, int port, - enum tc_setup_type type, void *type_data) +int ksz_setup_tc(struct dsa_switch *ds, int port, + enum tc_setup_type type, void *type_data) { switch (type) { case TC_SETUP_QDISC_CBS: @@ -4220,8 +4241,8 @@ int ksz_handle_wake_reason(struct ksz_device *dev, int port) * If enabled and supported, it sets the supported and active WoL * flags. */ -static void ksz_get_wol(struct dsa_switch *ds, int port, - struct ethtool_wolinfo *wol) +void ksz_get_wol(struct dsa_switch *ds, int port, + struct ethtool_wolinfo *wol) { struct ksz_device *dev = ds->priv; const u16 *regs = dev->info->regs; @@ -4268,8 +4289,8 @@ static void ksz_get_wol(struct dsa_switch *ds, int port, * * Return: 0 on success, or other error codes on failure. */ -static int ksz_set_wol(struct dsa_switch *ds, int port, - struct ethtool_wolinfo *wol) +int ksz_set_wol(struct dsa_switch *ds, int port, + struct ethtool_wolinfo *wol) { u8 pme_ctrl = 0, pme_ctrl_old = 0; struct ksz_device *dev = ds->priv; @@ -4383,8 +4404,8 @@ static void ksz_wol_pre_shutdown(struct ksz_device *dev, bool *wol_enabled) } } -static int ksz_port_set_mac_address(struct dsa_switch *ds, int port, - const unsigned char *addr) +int ksz_port_set_mac_address(struct dsa_switch *ds, int port, + const unsigned char *addr) { struct dsa_port *dp = dsa_to_port(ds, port); struct ethtool_wolinfo wol; @@ -4536,8 +4557,8 @@ void ksz_switch_macaddr_put(struct dsa_switch *ds) kfree(switch_macaddr); } -static int ksz_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr, - struct netlink_ext_ack *extack) +int ksz_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr, + struct netlink_ext_ack *extack) { struct ksz_device *dev = ds->priv; enum hsr_version ver; @@ -4585,8 +4606,8 @@ static int ksz_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr, return 0; } -static int ksz_hsr_leave(struct dsa_switch *ds, int port, - struct net_device *hsr) +int ksz_hsr_leave(struct dsa_switch *ds, int port, + struct net_device *hsr) { struct ksz_device *dev = ds->priv; @@ -4602,7 +4623,7 @@ static int ksz_hsr_leave(struct dsa_switch *ds, int port, return 0; } -static int ksz_suspend(struct dsa_switch *ds) +int ksz_suspend(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; @@ -4610,7 +4631,7 @@ static int ksz_suspend(struct dsa_switch *ds) return 0; } -static int ksz_resume(struct dsa_switch *ds) +int ksz_resume(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 519e080c8910..125740deb5a2 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -73,6 +73,7 @@ struct ksz_chip_data { */ bool phy_side_mdio_supported; const struct ksz_dev_ops *ops; + const struct dsa_switch_ops *switch_ops; const struct phylink_mac_ops *phylink_mac_ops; bool phy_errata_9477; bool ksz87xx_eee_link_erratum; @@ -465,6 +466,16 @@ void ksz_switch_remove(struct ksz_device *dev); int ksz_switch_suspend(struct device *dev); int ksz_switch_resume(struct device *dev); +int ksz_setup(struct dsa_switch *ds); +void ksz_teardown(struct dsa_switch *ds); +int ksz_port_setup(struct dsa_switch *ds, int port); +void ksz_port_teardown(struct dsa_switch *ds, int port); + +enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp); +int ksz_connect_tag_protocol(struct dsa_switch *ds, + enum dsa_tag_protocol proto); void ksz_init_mib_timer(struct ksz_device *dev); bool ksz_is_port_mac_global_usable(struct dsa_switch *ds, int port); void ksz_r_mib_stats64(struct ksz_device *dev, int port); @@ -479,6 +490,58 @@ void ksz_switch_macaddr_put(struct dsa_switch *ds); void ksz_switch_shutdown(struct ksz_device *dev); int ksz_handle_wake_reason(struct ksz_device *dev, int port); +int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg); +int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val); +u32 ksz_get_phy_flags(struct dsa_switch *ds, int port); + +int ksz_sset_count(struct dsa_switch *ds, int port, int sset); +void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, + uint64_t *buf); +void ksz_get_stats64(struct dsa_switch *ds, int port, + struct rtnl_link_stats64 *s); +void ksz_get_pause_stats(struct dsa_switch *ds, int port, + struct ethtool_pause_stats *pause_stats); +void ksz_get_strings(struct dsa_switch *ds, int port, + u32 stringset, uint8_t *buf); + +int ksz_port_bridge_join(struct dsa_switch *ds, int port, + struct dsa_bridge bridge, + bool *tx_fwd_offload, + struct netlink_ext_ack *extack); +void ksz_port_bridge_leave(struct dsa_switch *ds, int port, + struct dsa_bridge bridge); +int ksz_port_pre_bridge_flags(struct dsa_switch *ds, int port, + struct switchdev_brport_flags flags, + struct netlink_ext_ack *extack); +int ksz_port_bridge_flags(struct dsa_switch *ds, int port, + struct switchdev_brport_flags flags, + struct netlink_ext_ack *extack); +int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, + bool flag, struct netlink_ext_ack *extack); +int ksz_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack); +int ksz_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan); +void ksz_port_fast_age(struct dsa_switch *ds, int port); +int ksz_set_ageing_time(struct dsa_switch *ds, unsigned int msecs); +int ksz_port_fdb_add(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db); +int ksz_port_fdb_del(struct dsa_switch *ds, int port, + const unsigned char *addr, + u16 vid, struct dsa_db db); +int ksz_port_fdb_dump(struct dsa_switch *ds, int port, + dsa_fdb_dump_cb_t *cb, void *data); +int ksz_port_mdb_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db); +int ksz_port_mdb_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db); + +void ksz_phylink_get_caps(struct dsa_switch *ds, int port, + struct phylink_config *config); void ksz_phylink_mac_disable_tx_lpi(struct phylink_config *config); int ksz_phylink_mac_enable_tx_lpi(struct phylink_config *config, u32 timer, bool tx_clock_stop); @@ -489,6 +552,39 @@ void ksz_phylink_mac_link_down(struct phylink_config *config, unsigned int mode, phy_interface_t interface); +int ksz_port_mirror_add(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror, + bool ingress, struct netlink_ext_ack *extack); +void ksz_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror); +int ksz_change_mtu(struct dsa_switch *ds, int port, int mtu); +int ksz_max_mtu(struct dsa_switch *ds, int port); + +bool ksz_support_eee(struct dsa_switch *ds, int port); +int ksz_set_mac_eee(struct dsa_switch *ds, int port, + struct ethtool_keee *e); + +int ksz_cls_flower_add(struct dsa_switch *ds, int port, + struct flow_cls_offload *cls, bool ingress); +int ksz_cls_flower_del(struct dsa_switch *ds, int port, + struct flow_cls_offload *cls, bool ingress); +int ksz_setup_tc(struct dsa_switch *ds, int port, + enum tc_setup_type type, void *type_data); + +void ksz_get_wol(struct dsa_switch *ds, int port, + struct ethtool_wolinfo *wol); +int ksz_set_wol(struct dsa_switch *ds, int port, + struct ethtool_wolinfo *wol); +int ksz_port_set_mac_address(struct dsa_switch *ds, int port, + const unsigned char *addr); +int ksz_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr, + struct netlink_ext_ack *extack); +int ksz_hsr_leave(struct dsa_switch *ds, int port, + struct net_device *hsr); + +int ksz_suspend(struct dsa_switch *ds); +int ksz_resume(struct dsa_switch *ds); + /* Common register access functions */ static inline struct regmap *ksz_regmap_8(struct ksz_device *dev) { diff --git a/drivers/net/dsa/microchip/lan937x.h b/drivers/net/dsa/microchip/lan937x.h index c5e745a9f47f..d12483f9081d 100644 --- a/drivers/net/dsa/microchip/lan937x.h +++ b/drivers/net/dsa/microchip/lan937x.h @@ -8,5 +8,6 @@ extern const struct ksz_dev_ops lan937x_dev_ops; extern const struct phylink_mac_ops lan937x_phylink_mac_ops; +extern const struct dsa_switch_ops lan937x_switch_ops; #endif diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index 4846ae2a2d69..ff931b1143a5 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -15,6 +15,7 @@ #include "lan937x_reg.h" #include "ksz_common.h" +#include "ksz_dcb.h" #include "ksz9477.h" #include "lan937x.h" @@ -712,6 +713,67 @@ const struct ksz_dev_ops lan937x_dev_ops = { .exit = lan937x_switch_exit, }; +const struct dsa_switch_ops lan937x_switch_ops = { + .get_tag_protocol = ksz_get_tag_protocol, + .connect_tag_protocol = ksz_connect_tag_protocol, + .get_phy_flags = ksz_get_phy_flags, + .setup = ksz_setup, + .teardown = ksz_teardown, + .phy_read = ksz_phy_read16, + .phy_write = ksz_phy_write16, + .phylink_get_caps = ksz_phylink_get_caps, + .port_setup = ksz_port_setup, + .set_ageing_time = ksz_set_ageing_time, + .get_strings = ksz_get_strings, + .get_ethtool_stats = ksz_get_ethtool_stats, + .get_sset_count = ksz_sset_count, + .port_bridge_join = ksz_port_bridge_join, + .port_bridge_leave = ksz_port_bridge_leave, + .port_hsr_join = ksz_hsr_join, + .port_hsr_leave = ksz_hsr_leave, + .port_set_mac_address = ksz_port_set_mac_address, + .port_stp_state_set = ksz_port_stp_state_set, + .port_teardown = ksz_port_teardown, + .port_pre_bridge_flags = ksz_port_pre_bridge_flags, + .port_bridge_flags = ksz_port_bridge_flags, + .port_fast_age = ksz_port_fast_age, + .port_vlan_filtering = ksz_port_vlan_filtering, + .port_vlan_add = ksz_port_vlan_add, + .port_vlan_del = ksz_port_vlan_del, + .port_fdb_dump = ksz_port_fdb_dump, + .port_fdb_add = ksz_port_fdb_add, + .port_fdb_del = ksz_port_fdb_del, + .port_mdb_add = ksz_port_mdb_add, + .port_mdb_del = ksz_port_mdb_del, + .port_mirror_add = ksz_port_mirror_add, + .port_mirror_del = ksz_port_mirror_del, + .get_stats64 = ksz_get_stats64, + .get_pause_stats = ksz_get_pause_stats, + .port_change_mtu = ksz_change_mtu, + .port_max_mtu = ksz_max_mtu, + .get_wol = ksz_get_wol, + .set_wol = ksz_set_wol, + .suspend = ksz_suspend, + .resume = ksz_resume, + .get_ts_info = ksz_get_ts_info, + .port_hwtstamp_get = ksz_hwtstamp_get, + .port_hwtstamp_set = ksz_hwtstamp_set, + .port_txtstamp = ksz_port_txtstamp, + .port_rxtstamp = ksz_port_rxtstamp, + .cls_flower_add = ksz_cls_flower_add, + .cls_flower_del = ksz_cls_flower_del, + .port_setup_tc = ksz_setup_tc, + .support_eee = ksz_support_eee, + .set_mac_eee = ksz_set_mac_eee, + .port_get_default_prio = ksz_port_get_default_prio, + .port_set_default_prio = ksz_port_set_default_prio, + .port_get_dscp_prio = ksz_port_get_dscp_prio, + .port_add_dscp_prio = ksz_port_add_dscp_prio, + .port_del_dscp_prio = ksz_port_del_dscp_prio, + .port_get_apptrust = ksz_port_get_apptrust, + .port_set_apptrust = ksz_port_set_apptrust, +}; + MODULE_AUTHOR("Arun Ramadoss "); MODULE_DESCRIPTION("Microchip LAN937x Series Switch DSA Driver"); MODULE_LICENSE("GPL"); From adb50fc9960bd2b71503ccc88d3473df2d1f77ff Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 5 May 2026 16:25:07 +0200 Subject: [PATCH 7/9] net: dsa: microchip: hook up ksz_switch_alloc() to chip-specific dsa_switch_ops Now that each switch driver has its own dsa_switch_ops (currently a copy of ksz_switch_ops), we no longer need ksz_switch_ops and can remove it. Get to the driver-specific dsa_switch_ops through the ksz_chip_data structure. Reorder the alloc()/get_match_data() calls such as to have that pointer available. Signed-off-by: Vladimir Oltean Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-7-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz8863_smi.c | 8 +-- drivers/net/dsa/microchip/ksz9477_i2c.c | 8 +-- drivers/net/dsa/microchip/ksz_common.c | 67 ++----------------------- drivers/net/dsa/microchip/ksz_common.h | 4 +- drivers/net/dsa/microchip/ksz_spi.c | 8 +-- 5 files changed, 19 insertions(+), 76 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8863_smi.c b/drivers/net/dsa/microchip/ksz8863_smi.c index a8bfcd917bf7..ba08d2cf8e99 100644 --- a/drivers/net/dsa/microchip/ksz8863_smi.c +++ b/drivers/net/dsa/microchip/ksz8863_smi.c @@ -140,14 +140,14 @@ static int ksz8863_smi_probe(struct mdio_device *mdiodev) int ret; int i; - dev = ksz_switch_alloc(&mdiodev->dev, mdiodev); - if (!dev) - return -ENOMEM; - chip = device_get_match_data(ddev); if (!chip) return -EINVAL; + dev = ksz_switch_alloc(&mdiodev->dev, chip, mdiodev); + if (!dev) + return -ENOMEM; + for (i = 0; i < __KSZ_NUM_REGMAPS; i++) { rc = ksz8863_regmap_config[i]; rc.lock_arg = &dev->regmap_mutex; diff --git a/drivers/net/dsa/microchip/ksz9477_i2c.c b/drivers/net/dsa/microchip/ksz9477_i2c.c index a2beb27459f1..8e9d08f2e1d6 100644 --- a/drivers/net/dsa/microchip/ksz9477_i2c.c +++ b/drivers/net/dsa/microchip/ksz9477_i2c.c @@ -22,14 +22,14 @@ static int ksz9477_i2c_probe(struct i2c_client *i2c) struct ksz_device *dev; int i, ret; - dev = ksz_switch_alloc(&i2c->dev, i2c); - if (!dev) - return -ENOMEM; - chip = device_get_match_data(ddev); if (!chip) return -EINVAL; + dev = ksz_switch_alloc(&i2c->dev, chip, i2c); + if (!dev) + return -ENOMEM; + /* Save chip id to do special initialization when probing. */ dev->chip_id = chip->chip_id; for (i = 0; i < __KSZ_NUM_REGMAPS; i++) { diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index e48b9d5c0630..37e575bf4e14 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -4640,68 +4640,9 @@ int ksz_resume(struct dsa_switch *ds) return 0; } -static const struct dsa_switch_ops ksz_switch_ops = { - .get_tag_protocol = ksz_get_tag_protocol, - .connect_tag_protocol = ksz_connect_tag_protocol, - .get_phy_flags = ksz_get_phy_flags, - .setup = ksz_setup, - .teardown = ksz_teardown, - .phy_read = ksz_phy_read16, - .phy_write = ksz_phy_write16, - .phylink_get_caps = ksz_phylink_get_caps, - .port_setup = ksz_port_setup, - .set_ageing_time = ksz_set_ageing_time, - .get_strings = ksz_get_strings, - .get_ethtool_stats = ksz_get_ethtool_stats, - .get_sset_count = ksz_sset_count, - .port_bridge_join = ksz_port_bridge_join, - .port_bridge_leave = ksz_port_bridge_leave, - .port_hsr_join = ksz_hsr_join, - .port_hsr_leave = ksz_hsr_leave, - .port_set_mac_address = ksz_port_set_mac_address, - .port_stp_state_set = ksz_port_stp_state_set, - .port_teardown = ksz_port_teardown, - .port_pre_bridge_flags = ksz_port_pre_bridge_flags, - .port_bridge_flags = ksz_port_bridge_flags, - .port_fast_age = ksz_port_fast_age, - .port_vlan_filtering = ksz_port_vlan_filtering, - .port_vlan_add = ksz_port_vlan_add, - .port_vlan_del = ksz_port_vlan_del, - .port_fdb_dump = ksz_port_fdb_dump, - .port_fdb_add = ksz_port_fdb_add, - .port_fdb_del = ksz_port_fdb_del, - .port_mdb_add = ksz_port_mdb_add, - .port_mdb_del = ksz_port_mdb_del, - .port_mirror_add = ksz_port_mirror_add, - .port_mirror_del = ksz_port_mirror_del, - .get_stats64 = ksz_get_stats64, - .get_pause_stats = ksz_get_pause_stats, - .port_change_mtu = ksz_change_mtu, - .port_max_mtu = ksz_max_mtu, - .get_wol = ksz_get_wol, - .set_wol = ksz_set_wol, - .suspend = ksz_suspend, - .resume = ksz_resume, - .get_ts_info = ksz_get_ts_info, - .port_hwtstamp_get = ksz_hwtstamp_get, - .port_hwtstamp_set = ksz_hwtstamp_set, - .port_txtstamp = ksz_port_txtstamp, - .port_rxtstamp = ksz_port_rxtstamp, - .cls_flower_add = ksz_cls_flower_add, - .cls_flower_del = ksz_cls_flower_del, - .port_setup_tc = ksz_setup_tc, - .support_eee = ksz_support_eee, - .set_mac_eee = ksz_set_mac_eee, - .port_get_default_prio = ksz_port_get_default_prio, - .port_set_default_prio = ksz_port_set_default_prio, - .port_get_dscp_prio = ksz_port_get_dscp_prio, - .port_add_dscp_prio = ksz_port_add_dscp_prio, - .port_del_dscp_prio = ksz_port_del_dscp_prio, - .port_get_apptrust = ksz_port_get_apptrust, - .port_set_apptrust = ksz_port_set_apptrust, -}; - -struct ksz_device *ksz_switch_alloc(struct device *base, void *priv) +struct ksz_device *ksz_switch_alloc(struct device *base, + const struct ksz_chip_data *chip, + void *priv) { struct dsa_switch *ds; struct ksz_device *swdev; @@ -4712,7 +4653,7 @@ struct ksz_device *ksz_switch_alloc(struct device *base, void *priv) ds->dev = base; ds->num_ports = DSA_MAX_PORTS; - ds->ops = &ksz_switch_ops; + ds->ops = chip->switch_ops; swdev = devm_kzalloc(base, sizeof(*swdev), GFP_KERNEL); if (!swdev) diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 125740deb5a2..37923a1c43d8 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -460,7 +460,9 @@ struct ksz_dev_ops { int (*pcs_create)(struct ksz_device *dev); }; -struct ksz_device *ksz_switch_alloc(struct device *base, void *priv); +struct ksz_device *ksz_switch_alloc(struct device *base, + const struct ksz_chip_data *chip, + void *priv); int ksz_switch_register(struct ksz_device *dev); void ksz_switch_remove(struct ksz_device *dev); int ksz_switch_suspend(struct device *dev); diff --git a/drivers/net/dsa/microchip/ksz_spi.c b/drivers/net/dsa/microchip/ksz_spi.c index d8001734b057..373e9054947c 100644 --- a/drivers/net/dsa/microchip/ksz_spi.c +++ b/drivers/net/dsa/microchip/ksz_spi.c @@ -143,14 +143,14 @@ static int ksz_spi_probe(struct spi_device *spi) struct ksz_device *dev; int i, ret = 0; - dev = ksz_switch_alloc(&spi->dev, spi); - if (!dev) - return -ENOMEM; - chip = device_get_match_data(ddev); if (!chip) return -EINVAL; + dev = ksz_switch_alloc(&spi->dev, chip, spi); + if (!dev) + return -ENOMEM; + /* Save chip id to do special initialization when probing. */ dev->chip_id = chip->chip_id; if (chip->chip_id == KSZ88X3_CHIP_ID) From af96c2f08ddb06042ad26debfa4d47b7a9d2089c Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 5 May 2026 16:25:08 +0200 Subject: [PATCH 8/9] net: dsa: microchip: split ksz_get_tag_protocol() All the switch families use a common function to implement .get_tag_protocol(). This function then returns the relevant protocol depending on the chip ID. Make the protocol to dsa_switch_ops association a little bit more obvious by having separate implementations. Change made by manually checking which chip id has which dsa_switch_ops assigned to it, then filtering the common ksz_get_tag_protocol() for just those chip IDs pertaining to it. As an important benefit, we no longer have that weird-looking DSA_TAG_PROTO_NONE fallback which was never actually returned. Signed-off-by: Vladimir Oltean Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-8-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz8.c | 32 +++++++++++++++++++++--- drivers/net/dsa/microchip/ksz9477.c | 16 +++++++++++- drivers/net/dsa/microchip/ksz_common.c | 31 ----------------------- drivers/net/dsa/microchip/ksz_common.h | 3 --- drivers/net/dsa/microchip/lan937x_main.c | 9 ++++++- 5 files changed, 52 insertions(+), 39 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c index f7801269b11a..fa2e1256323c 100644 --- a/drivers/net/dsa/microchip/ksz8.c +++ b/drivers/net/dsa/microchip/ksz8.c @@ -2100,6 +2100,32 @@ static void ksz8_switch_exit(struct ksz_device *dev) ksz8_reset_switch(dev); } +static enum dsa_tag_protocol ksz8463_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp) +{ + return DSA_TAG_PROTO_KSZ9893; +} + +static enum dsa_tag_protocol ksz87xx_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp) +{ + return DSA_TAG_PROTO_KSZ8795; +} + +static enum dsa_tag_protocol ksz88xx_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp) +{ + struct ksz_device *dev = ds->priv; + + if (ksz_is_8895_family(dev)) /* KSZ8864, KSZ8895 */ + return DSA_TAG_PROTO_KSZ8795; + + return DSA_TAG_PROTO_KSZ9893; +} + static void ksz88x3_phylink_mac_config(struct phylink_config *config, unsigned int mode, const struct phylink_link_state *state) @@ -2229,7 +2255,7 @@ const struct ksz_dev_ops ksz88xx_dev_ops = { }; const struct dsa_switch_ops ksz8463_switch_ops = { - .get_tag_protocol = ksz_get_tag_protocol, + .get_tag_protocol = ksz8463_get_tag_protocol, .connect_tag_protocol = ksz_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, @@ -2290,7 +2316,7 @@ const struct dsa_switch_ops ksz8463_switch_ops = { }; const struct dsa_switch_ops ksz87xx_switch_ops = { - .get_tag_protocol = ksz_get_tag_protocol, + .get_tag_protocol = ksz87xx_get_tag_protocol, .connect_tag_protocol = ksz_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, @@ -2351,7 +2377,7 @@ const struct dsa_switch_ops ksz87xx_switch_ops = { }; const struct dsa_switch_ops ksz88xx_switch_ops = { - .get_tag_protocol = ksz_get_tag_protocol, + .get_tag_protocol = ksz88xx_get_tag_protocol, .connect_tag_protocol = ksz_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 9fb0169b5e29..9bac95bb079f 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1610,6 +1610,20 @@ static void ksz9477_switch_exit(struct ksz_device *dev) ksz9477_reset_switch(dev); } +static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp) +{ + struct ksz_device *dev = ds->priv; + + if (dev->chip_id == KSZ8563_CHIP_ID || + dev->chip_id == KSZ9893_CHIP_ID || + dev->chip_id == KSZ9563_CHIP_ID) + return DSA_TAG_PROTO_KSZ9893; + + return DSA_TAG_PROTO_KSZ9477; +} + static void ksz9477_set_gbit(struct ksz_device *dev, int port, bool gbit) { const u8 *bitval = dev->info->xmii_ctrl1; @@ -1775,7 +1789,7 @@ const struct ksz_dev_ops ksz9477_dev_ops = { }; const struct dsa_switch_ops ksz9477_switch_ops = { - .get_tag_protocol = ksz_get_tag_protocol, + .get_tag_protocol = ksz9477_get_tag_protocol, .connect_tag_protocol = ksz_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 37e575bf4e14..1be055d3f199 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -3304,37 +3304,6 @@ int ksz_port_bridge_flags(struct dsa_switch *ds, int port, return 0; } -enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, - int port, - enum dsa_tag_protocol mp) -{ - struct ksz_device *dev = ds->priv; - enum dsa_tag_protocol proto = DSA_TAG_PROTO_NONE; - - if (ksz_is_ksz87xx(dev) || ksz_is_8895_family(dev)) - proto = DSA_TAG_PROTO_KSZ8795; - - if (dev->chip_id == KSZ88X3_CHIP_ID || - dev->chip_id == KSZ8463_CHIP_ID || - dev->chip_id == KSZ8563_CHIP_ID || - dev->chip_id == KSZ9893_CHIP_ID || - dev->chip_id == KSZ9563_CHIP_ID) - proto = DSA_TAG_PROTO_KSZ9893; - - if (dev->chip_id == KSZ8567_CHIP_ID || - dev->chip_id == KSZ9477_CHIP_ID || - dev->chip_id == KSZ9896_CHIP_ID || - dev->chip_id == KSZ9897_CHIP_ID || - dev->chip_id == KSZ9567_CHIP_ID || - dev->chip_id == LAN9646_CHIP_ID) - proto = DSA_TAG_PROTO_KSZ9477; - - if (is_lan937x(dev)) - proto = DSA_TAG_PROTO_LAN937X; - - return proto; -} - int ksz_connect_tag_protocol(struct dsa_switch *ds, enum dsa_tag_protocol proto) { diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 37923a1c43d8..39486b5571bd 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -473,9 +473,6 @@ void ksz_teardown(struct dsa_switch *ds); int ksz_port_setup(struct dsa_switch *ds, int port); void ksz_port_teardown(struct dsa_switch *ds, int port); -enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, - int port, - enum dsa_tag_protocol mp); int ksz_connect_tag_protocol(struct dsa_switch *ds, enum dsa_tag_protocol proto); void ksz_init_mib_timer(struct ksz_device *dev); diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index ff931b1143a5..c39be6eb5012 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -667,6 +667,13 @@ static void lan937x_switch_exit(struct ksz_device *dev) lan937x_reset_switch(dev); } +static enum dsa_tag_protocol lan937x_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp) +{ + return DSA_TAG_PROTO_LAN937X; +} + const struct phylink_mac_ops lan937x_phylink_mac_ops = { .mac_config = ksz_phylink_mac_config, .mac_link_down = ksz_phylink_mac_link_down, @@ -714,7 +721,7 @@ const struct ksz_dev_ops lan937x_dev_ops = { }; const struct dsa_switch_ops lan937x_switch_ops = { - .get_tag_protocol = ksz_get_tag_protocol, + .get_tag_protocol = lan937x_get_tag_protocol, .connect_tag_protocol = ksz_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, From 1df461e527477068e5f3773e645d555120704be6 Mon Sep 17 00:00:00 2001 From: "Bastien Curutchet (Schneider Electric)" Date: Tue, 5 May 2026 16:25:09 +0200 Subject: [PATCH 9/9] net: dsa: microchip: split ksz_connect_tag_protocol() All the KSZ switches use the same ksz_connect_tag_protocol while they don't support all the KSZ tag protocols. So if, for some reason, a given switch tries to connect another KSZ tag protocol, it won't fail. Split the common ksz_connect_tag_protocol() into switch-specific operations. This way, each switch will only accept to connect the tag protocol it supports. Remove the no longer used common operation. Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20260505-clean-ksz-driver-v1-9-05d70fa42461@bootlin.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz8.c | 51 ++++++++++++++++++++++-- drivers/net/dsa/microchip/ksz9477.c | 17 +++++++- drivers/net/dsa/microchip/ksz_common.c | 19 --------- drivers/net/dsa/microchip/ksz_common.h | 2 - drivers/net/dsa/microchip/lan937x_main.c | 17 +++++++- 5 files changed, 80 insertions(+), 26 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c index fa2e1256323c..abee0dc5ec04 100644 --- a/drivers/net/dsa/microchip/ksz8.c +++ b/drivers/net/dsa/microchip/ksz8.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -2107,6 +2108,20 @@ static enum dsa_tag_protocol ksz8463_get_tag_protocol(struct dsa_switch *ds, return DSA_TAG_PROTO_KSZ9893; } +static int ksz8463_connect_tag_protocol(struct dsa_switch *ds, + enum dsa_tag_protocol proto) +{ + struct ksz_tagger_data *tagger_data; + + if (proto != DSA_TAG_PROTO_KSZ9893) + return -EPROTONOSUPPORT; + + tagger_data = ksz_tagger_data(ds); + tagger_data->xmit_work_fn = ksz_port_deferred_xmit; + + return 0; +} + static enum dsa_tag_protocol ksz87xx_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp) @@ -2114,6 +2129,15 @@ static enum dsa_tag_protocol ksz87xx_get_tag_protocol(struct dsa_switch *ds, return DSA_TAG_PROTO_KSZ8795; } +static int ksz87xx_connect_tag_protocol(struct dsa_switch *ds, + enum dsa_tag_protocol proto) +{ + if (proto != DSA_TAG_PROTO_KSZ8795) + return -EPROTONOSUPPORT; + + return 0; +} + static enum dsa_tag_protocol ksz88xx_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp) @@ -2126,6 +2150,27 @@ static enum dsa_tag_protocol ksz88xx_get_tag_protocol(struct dsa_switch *ds, return DSA_TAG_PROTO_KSZ9893; } +static int ksz88xx_connect_tag_protocol(struct dsa_switch *ds, + enum dsa_tag_protocol proto) +{ + struct ksz_tagger_data *tagger_data; + + if (ksz_is_8895_family(ds->priv)) { /* KSZ8864, KSZ8895 */ + if (proto != DSA_TAG_PROTO_KSZ8795) + return -EPROTONOSUPPORT; + + return 0; + } + + if (proto != DSA_TAG_PROTO_KSZ9893) + return -EPROTONOSUPPORT; + + tagger_data = ksz_tagger_data(ds); + tagger_data->xmit_work_fn = ksz_port_deferred_xmit; + + return 0; +} + static void ksz88x3_phylink_mac_config(struct phylink_config *config, unsigned int mode, const struct phylink_link_state *state) @@ -2256,7 +2301,7 @@ const struct ksz_dev_ops ksz88xx_dev_ops = { const struct dsa_switch_ops ksz8463_switch_ops = { .get_tag_protocol = ksz8463_get_tag_protocol, - .connect_tag_protocol = ksz_connect_tag_protocol, + .connect_tag_protocol = ksz8463_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, .teardown = ksz_teardown, @@ -2317,7 +2362,7 @@ const struct dsa_switch_ops ksz8463_switch_ops = { const struct dsa_switch_ops ksz87xx_switch_ops = { .get_tag_protocol = ksz87xx_get_tag_protocol, - .connect_tag_protocol = ksz_connect_tag_protocol, + .connect_tag_protocol = ksz87xx_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, .teardown = ksz_teardown, @@ -2378,7 +2423,7 @@ const struct dsa_switch_ops ksz87xx_switch_ops = { const struct dsa_switch_ops ksz88xx_switch_ops = { .get_tag_protocol = ksz88xx_get_tag_protocol, - .connect_tag_protocol = ksz_connect_tag_protocol, + .connect_tag_protocol = ksz88xx_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, .teardown = ksz_teardown, diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 9bac95bb079f..ac2c63fe0588 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -5,6 +5,7 @@ * Copyright (C) 2017-2025 Microchip Technology Inc. */ +#include #include #include #include @@ -1624,6 +1625,20 @@ static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds, return DSA_TAG_PROTO_KSZ9477; } +static int ksz9477_connect_tag_protocol(struct dsa_switch *ds, + enum dsa_tag_protocol proto) +{ + struct ksz_tagger_data *tagger_data; + + if (proto != DSA_TAG_PROTO_KSZ9893 && proto != DSA_TAG_PROTO_KSZ9477) + return -EPROTONOSUPPORT; + + tagger_data = ksz_tagger_data(ds); + tagger_data->xmit_work_fn = ksz_port_deferred_xmit; + + return 0; +} + static void ksz9477_set_gbit(struct ksz_device *dev, int port, bool gbit) { const u8 *bitval = dev->info->xmii_ctrl1; @@ -1790,7 +1805,7 @@ const struct ksz_dev_ops ksz9477_dev_ops = { const struct dsa_switch_ops ksz9477_switch_ops = { .get_tag_protocol = ksz9477_get_tag_protocol, - .connect_tag_protocol = ksz_connect_tag_protocol, + .connect_tag_protocol = ksz9477_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, .teardown = ksz_teardown, diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 1be055d3f199..426414a21845 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -3304,25 +3304,6 @@ int ksz_port_bridge_flags(struct dsa_switch *ds, int port, return 0; } -int ksz_connect_tag_protocol(struct dsa_switch *ds, - enum dsa_tag_protocol proto) -{ - struct ksz_tagger_data *tagger_data; - - switch (proto) { - case DSA_TAG_PROTO_KSZ8795: - return 0; - case DSA_TAG_PROTO_KSZ9893: - case DSA_TAG_PROTO_KSZ9477: - case DSA_TAG_PROTO_LAN937X: - tagger_data = ksz_tagger_data(ds); - tagger_data->xmit_work_fn = ksz_port_deferred_xmit; - return 0; - default: - return -EPROTONOSUPPORT; - } -} - int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag, struct netlink_ext_ack *extack) { diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 39486b5571bd..3dde7e771727 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -473,8 +473,6 @@ void ksz_teardown(struct dsa_switch *ds); int ksz_port_setup(struct dsa_switch *ds, int port); void ksz_port_teardown(struct dsa_switch *ds, int port); -int ksz_connect_tag_protocol(struct dsa_switch *ds, - enum dsa_tag_protocol proto); void ksz_init_mib_timer(struct ksz_device *dev); bool ksz_is_port_mac_global_usable(struct dsa_switch *ds, int port); void ksz_r_mib_stats64(struct ksz_device *dev, int port); diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index c39be6eb5012..e522990cce22 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -2,6 +2,7 @@ /* Microchip LAN937X switch driver main logic * Copyright (C) 2019-2024 Microchip Technology Inc. */ +#include #include #include #include @@ -674,6 +675,20 @@ static enum dsa_tag_protocol lan937x_get_tag_protocol(struct dsa_switch *ds, return DSA_TAG_PROTO_LAN937X; } +static int lan937x_connect_tag_protocol(struct dsa_switch *ds, + enum dsa_tag_protocol proto) +{ + struct ksz_tagger_data *tagger_data; + + if (proto != DSA_TAG_PROTO_LAN937X) + return -EPROTONOSUPPORT; + + tagger_data = ksz_tagger_data(ds); + tagger_data->xmit_work_fn = ksz_port_deferred_xmit; + + return 0; +} + const struct phylink_mac_ops lan937x_phylink_mac_ops = { .mac_config = ksz_phylink_mac_config, .mac_link_down = ksz_phylink_mac_link_down, @@ -722,7 +737,7 @@ const struct ksz_dev_ops lan937x_dev_ops = { const struct dsa_switch_ops lan937x_switch_ops = { .get_tag_protocol = lan937x_get_tag_protocol, - .connect_tag_protocol = ksz_connect_tag_protocol, + .connect_tag_protocol = lan937x_connect_tag_protocol, .get_phy_flags = ksz_get_phy_flags, .setup = ksz_setup, .teardown = ksz_teardown,