* [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks
@ 2026-05-26 9:47 Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 1/9] net: dsa: microchip: remove useless common cls_flower_{add/del} operations Bastien Curutchet (Schneider Electric)
` (8 more replies)
0 siblings, 9 replies; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric),
Vladimir Oltean
Hi all,
This series continues the rework of the KSZ driver initiated by two previous
series (see [1] & [2]).
The KSZ driver handles more than 20 switches split in several families.
This was previously handled through a common set of dsa_switch_ops
operations that used device-specific ksz_dev_ops callbacks. The two
previous series have split this common struct dsa_switch_ops into 5
to connect the ksz_dev_ops's implentations directly to the new
dsa_swicth ops.
This series continues in the same vein and removes the dsa_switch_ops
operations that aren't used.
On top of this on-going rework I added PTP and periodic output support for
the KSZ8463 (which was my first goal). There are still more than 20 patches
left for all this so this series will be followed by three others and if you
want to see the full picture we can check my github ([3]).
FYI, I only have a KSZ8463 so, unfortunately, I can't test other switches.
The next series is going to move out of ksz_common.c the last remaining
functions that aren't truly common to all KSZ switches. The series after
that will add PTP support for the KSZ8463 and the final one will add
periodic output support for the KSZ8463.
[1]: https://lore.kernel.org/r/20260505-clean-ksz-driver-v1-0-05d70fa42461@bootlin.com
[2]: https://lore.kernel.org/r/20260521-clean-ksz-2nd-series-v3-0-75c38971c19a@bootlin.com
[3]: https://github.com/bastien-curutchet/linux/tree/ksz_rework
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
Bastien Curutchet (Schneider Electric) (8):
net: dsa: microchip: remove useless common cls_flower_{add/del} operations
net: dsa: microchip: implement get_phy_flags only if needed
net: dsa: microchip: remove setup_rgmii_delay() KSZ operation
net: dsa: microchip: implement .support_eee() only if needed
net: dsa: microchip: implement .{get/set}_wol only if needed
net: dsa: microchip: implement port_hsr_join for KSZ9477 only
net: dsa: microchip: implement lan937x-specific MDIO registration
net: dsa: microchip: implement port_teardown only if needed
Vladimir Oltean (1):
net: dsa: microchip: remove VLAN operations for ksz8463
drivers/net/dsa/microchip/ksz8.c | 53 +++----
drivers/net/dsa/microchip/ksz9477.c | 129 ++++++++++++++--
drivers/net/dsa/microchip/ksz9477.h | 2 -
drivers/net/dsa/microchip/ksz_common.c | 248 ++-----------------------------
drivers/net/dsa/microchip/ksz_common.h | 56 +------
drivers/net/dsa/microchip/lan937x_main.c | 137 +++++++++++++++--
6 files changed, 283 insertions(+), 342 deletions(-)
---
base-commit: c0aa5f13826dcb035bec3d6b252e6b2020fa5f88
change-id: 20260525-clean-ksz-3rd-5a190d7c63fa
Best regards,
--
Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 1/9] net: dsa: microchip: remove useless common cls_flower_{add/del} operations
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
@ 2026-05-26 9:47 ` Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 2/9] net: dsa: microchip: remove VLAN operations for ksz8463 Bastien Curutchet
` (7 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric)
All the KSZ switches share a common implementation of the
cls_flower_{add/del} operations. These common implementations return
ksz9477-specific implementations for the KSZ9477 family and -EOPNOTSUPP
for the others. -EOPNOTSUPP is already returned by the DSA core when
the operation isn't implemented.
Remove the common implementations.
Directly link the ksz9477_cls_flower_{add/del}() to the KSZ9477 callback.
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz8.c | 6 -----
drivers/net/dsa/microchip/ksz9477.c | 4 +--
drivers/net/dsa/microchip/ksz_common.c | 42 --------------------------------
drivers/net/dsa/microchip/ksz_common.h | 4 ---
drivers/net/dsa/microchip/lan937x_main.c | 2 --
5 files changed, 2 insertions(+), 56 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index 0f84b2e7d25d..db08874eb025 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -2462,8 +2462,6 @@ const struct dsa_switch_ops ksz8463_switch_ops = {
.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,
@@ -2522,8 +2520,6 @@ const struct dsa_switch_ops ksz87xx_switch_ops = {
.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,
@@ -2582,8 +2578,6 @@ const struct dsa_switch_ops ksz88xx_switch_ops = {
.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,
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index c1395322e54b..c18bad08a508 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -1996,8 +1996,8 @@ const struct dsa_switch_ops ksz9477_switch_ops = {
.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,
+ .cls_flower_add = ksz9477_cls_flower_add,
+ .cls_flower_del = ksz9477_cls_flower_del,
.port_setup_tc = ksz_setup_tc,
.support_eee = ksz_support_eee,
.set_mac_eee = ksz_set_mac_eee,
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 57c8abfe0147..81d3ec88e436 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3373,48 +3373,6 @@ static int ksz_switch_detect(struct ksz_device *dev)
return 0;
}
-int ksz_cls_flower_add(struct dsa_switch *ds, int port,
- struct flow_cls_offload *cls, bool ingress)
-{
- struct ksz_device *dev = ds->priv;
-
- switch (dev->chip_id) {
- case KSZ8563_CHIP_ID:
- case KSZ8567_CHIP_ID:
- case KSZ9477_CHIP_ID:
- case KSZ9563_CHIP_ID:
- case KSZ9567_CHIP_ID:
- case KSZ9893_CHIP_ID:
- case KSZ9896_CHIP_ID:
- case KSZ9897_CHIP_ID:
- case LAN9646_CHIP_ID:
- return ksz9477_cls_flower_add(ds, port, cls, ingress);
- }
-
- return -EOPNOTSUPP;
-}
-
-int ksz_cls_flower_del(struct dsa_switch *ds, int port,
- struct flow_cls_offload *cls, bool ingress)
-{
- struct ksz_device *dev = ds->priv;
-
- switch (dev->chip_id) {
- case KSZ8563_CHIP_ID:
- case KSZ8567_CHIP_ID:
- case KSZ9477_CHIP_ID:
- case KSZ9563_CHIP_ID:
- case KSZ9567_CHIP_ID:
- case KSZ9893_CHIP_ID:
- case KSZ9896_CHIP_ID:
- case KSZ9897_CHIP_ID:
- case LAN9646_CHIP_ID:
- return ksz9477_cls_flower_del(ds, port, cls, ingress);
- }
-
- return -EOPNOTSUPP;
-}
-
/* Bandwidth is calculated by idle slope/transmission speed. Then the Bandwidth
* is converted to Hex-decimal using the successive multiplication method. On
* every step, integer part is taken and decimal part is carry forwarded.
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index b67038cf1bd0..da62c1658aa8 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -483,10 +483,6 @@ 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);
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index 536153886f7b..731737fd58d1 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -890,8 +890,6 @@ const struct dsa_switch_ops lan937x_switch_ops = {
.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,
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 2/9] net: dsa: microchip: remove VLAN operations for ksz8463
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 1/9] net: dsa: microchip: remove useless common cls_flower_{add/del} operations Bastien Curutchet (Schneider Electric)
@ 2026-05-26 9:47 ` Bastien Curutchet
2026-05-26 9:47 ` [PATCH net-next 3/9] net: dsa: microchip: implement get_phy_flags only if needed Bastien Curutchet (Schneider Electric)
` (6 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric),
Vladimir Oltean
From: Vladimir Oltean <vladimir.oltean@nxp.com>
KSZ8463 uses the common KSZ8 implementation for its VLAN operations.
This implementation returns -ENOTSUPP for the KSZ8463 case, which is
pointless.
Remove the VLAN operations from the ksz8463_switch_ops so the core can
directly return -ENOTSUPP.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz8.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index db08874eb025..93e0b3f60448 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -1477,7 +1477,7 @@ static int ksz8_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag,
{
struct ksz_device *dev = ds->priv;
- if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev))
+ if (ksz_is_ksz88x3(dev))
return -ENOTSUPP;
/* Discard packets with VID not enabled on the switch */
@@ -1514,7 +1514,7 @@ static int ksz8_port_vlan_add(struct dsa_switch *ds, int port,
u16 data, new_pvid = 0;
u8 fid, member, valid;
- if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev))
+ if (ksz_is_ksz88x3(dev))
return -ENOTSUPP;
/* If a VLAN is added with untagged flag different from the
@@ -1584,7 +1584,7 @@ static int ksz8_port_vlan_del(struct dsa_switch *ds, int port,
u8 fid, member, valid;
u16 data, pvid;
- if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev))
+ if (ksz_is_ksz88x3(dev))
return -ENOTSUPP;
ksz_pread16(dev, port, REG_PORT_CTRL_VID, &pvid);
@@ -2439,9 +2439,6 @@ const struct dsa_switch_ops ksz8463_switch_ops = {
.port_pre_bridge_flags = ksz_port_pre_bridge_flags,
.port_bridge_flags = ksz_port_bridge_flags,
.port_fast_age = ksz8_flush_dyn_mac_table,
- .port_vlan_filtering = ksz8_port_vlan_filtering,
- .port_vlan_add = ksz8_port_vlan_add,
- .port_vlan_del = ksz8_port_vlan_del,
.port_fdb_dump = ksz8_fdb_dump,
.port_fdb_add = ksz8_fdb_add,
.port_fdb_del = ksz8_fdb_del,
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 3/9] net: dsa: microchip: implement get_phy_flags only if needed
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 1/9] net: dsa: microchip: remove useless common cls_flower_{add/del} operations Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 2/9] net: dsa: microchip: remove VLAN operations for ksz8463 Bastien Curutchet
@ 2026-05-26 9:47 ` Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 4/9] net: dsa: microchip: remove setup_rgmii_delay() KSZ operation Bastien Curutchet (Schneider Electric)
` (5 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric)
The common ksz_get_phy_flags() is used by all the switches to implement
the optional .get_phy_flags DSA operation. It always returns 0 except
for KSZ88X3 switches where an errata has to be handled.
Make ksz_get_phy_flags() ksz88xx-specific.
Remove the get_phy_flags implementation for the switches that don't need
it.
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz8.c | 22 +++++++++++++++++++---
drivers/net/dsa/microchip/ksz9477.c | 1 -
drivers/net/dsa/microchip/ksz_common.c | 18 ------------------
drivers/net/dsa/microchip/ksz_common.h | 2 --
drivers/net/dsa/microchip/lan937x_main.c | 1 -
5 files changed, 19 insertions(+), 25 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index 93e0b3f60448..98cf7239057d 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -2272,6 +2272,24 @@ static int ksz8463_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val
return 0;
}
+static u32 ksz88xx_get_phy_flags(struct dsa_switch *ds, int port)
+{
+ struct ksz_device *dev = ds->priv;
+
+ switch (dev->chip_id) {
+ case KSZ88X3_CHIP_ID:
+ /* Silicon Errata Sheet (DS80000830A):
+ * Port 1 does not work with LinkMD Cable-Testing.
+ * Port 1 does not respond to received PAUSE control frames.
+ */
+ if (!port)
+ return MICREL_KSZ8_P1_ERRATA;
+ break;
+ }
+
+ return 0;
+}
+
static int ksz8_switch_init(struct ksz_device *dev)
{
dev->cpu_port = fls(dev->info->cpu_ports) - 1;
@@ -2419,7 +2437,6 @@ 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 = ksz8463_connect_tag_protocol,
- .get_phy_flags = ksz_get_phy_flags,
.setup = ksz8_setup,
.teardown = ksz_teardown,
.phy_read = ksz8463_phy_read16,
@@ -2474,7 +2491,6 @@ 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 = ksz87xx_connect_tag_protocol,
- .get_phy_flags = ksz_get_phy_flags,
.setup = ksz8_setup,
.teardown = ksz_teardown,
.phy_read = ksz8_phy_read16,
@@ -2532,7 +2548,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 = ksz88xx_connect_tag_protocol,
- .get_phy_flags = ksz_get_phy_flags,
+ .get_phy_flags = ksz88xx_get_phy_flags,
.setup = ksz8_setup,
.teardown = ksz_teardown,
.phy_read = ksz8_phy_read16,
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index c18bad08a508..a39541d29ad5 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -1952,7 +1952,6 @@ 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 = ksz9477_connect_tag_protocol,
- .get_phy_flags = ksz_get_phy_flags,
.setup = ksz9477_setup,
.teardown = ksz_teardown,
.phy_read = ksz9477_phy_read16,
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 81d3ec88e436..5fb151fbf4f3 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -2838,24 +2838,6 @@ void ksz_init_mib_timer(struct ksz_device *dev)
}
}
-u32 ksz_get_phy_flags(struct dsa_switch *ds, int port)
-{
- struct ksz_device *dev = ds->priv;
-
- switch (dev->chip_id) {
- case KSZ88X3_CHIP_ID:
- /* Silicon Errata Sheet (DS80000830A):
- * Port 1 does not work with LinkMD Cable-Testing.
- * Port 1 does not respond to received PAUSE control frames.
- */
- if (!port)
- return MICREL_KSZ8_P1_ERRATA;
- break;
- }
-
- return 0;
-}
-
void ksz_phylink_mac_link_down(struct phylink_config *config,
unsigned int mode,
phy_interface_t interface)
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index da62c1658aa8..804912fdd2db 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -440,8 +440,6 @@ 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);
-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);
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index 731737fd58d1..57e289637193 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -846,7 +846,6 @@ 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 = lan937x_connect_tag_protocol,
- .get_phy_flags = ksz_get_phy_flags,
.setup = lan937x_setup,
.teardown = ksz_teardown,
.phy_read = lan937x_phy_read16,
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 4/9] net: dsa: microchip: remove setup_rgmii_delay() KSZ operation
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
` (2 preceding siblings ...)
2026-05-26 9:47 ` [PATCH net-next 3/9] net: dsa: microchip: implement get_phy_flags only if needed Bastien Curutchet (Schneider Electric)
@ 2026-05-26 9:47 ` Bastien Curutchet (Schneider Electric)
2026-06-01 8:49 ` Paolo Abeni
2026-05-26 9:47 ` [PATCH net-next 5/9] net: dsa: microchip: implement .support_eee() only if needed Bastien Curutchet (Schneider Electric)
` (4 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric)
setup_rgmii_delay() operation is only used once during the common phylink
MAC configuration. Only the lan937x switch implements this
setup_rgmii_delay().
Remove the setup_rgmii_delay operation from ksz_dev_ops.
Implement a lan937x-specific phylink MAC configuration that does this
RGMII delay setup.
Export ksz_set_xmii since it's needed by the lan937x implementation.
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz_common.c | 6 +-----
drivers/net/dsa/microchip/ksz_common.h | 2 +-
drivers/net/dsa/microchip/lan937x_main.c | 29 +++++++++++++++++++++++++++--
3 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 5fb151fbf4f3..d6511fcebcf2 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3127,8 +3127,7 @@ int ksz_set_mac_eee(struct dsa_switch *ds, int port,
return 0;
}
-static void ksz_set_xmii(struct ksz_device *dev, int port,
- phy_interface_t interface)
+void ksz_set_xmii(struct ksz_device *dev, int port, phy_interface_t interface)
{
const u8 *bitval = dev->info->xmii_ctrl1;
struct ksz_port *p = &dev->ports[port];
@@ -3233,9 +3232,6 @@ void ksz_phylink_mac_config(struct phylink_config *config,
}
ksz_set_xmii(dev, port, state->interface);
-
- if (dev->dev_ops->setup_rgmii_delay)
- dev->dev_ops->setup_rgmii_delay(dev, port);
}
bool ksz_get_gbit(struct ksz_device *dev, int port)
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 804912fdd2db..ab08c98ed257 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -410,7 +410,6 @@ struct ksz_dev_ops {
u8 data);
void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze);
void (*port_init_cnt)(struct ksz_device *dev, int port);
- void (*setup_rgmii_delay)(struct ksz_device *dev, int port);
int (*tc_cbs_set_cinc)(struct ksz_device *dev, int port, u32 val);
int (*init)(struct ksz_device *dev);
};
@@ -468,6 +467,7 @@ void ksz_phylink_get_caps(struct dsa_switch *ds, 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_set_xmii(struct ksz_device *dev, int port, phy_interface_t interface);
void ksz_phylink_mac_config(struct phylink_config *config,
unsigned int mode,
const struct phylink_link_state *state);
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index 57e289637193..f8f220242f7a 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -643,6 +643,32 @@ static void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port)
}
}
+static void lan937x_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;
+ int port = dp->index;
+
+ /* Internal PHYs */
+ if (dev->info->internal_phy[port])
+ return;
+
+ /* No need to configure XMII control register when using SGMII. */
+ if (ksz_is_sgmii_port(dev, port))
+ return;
+
+ if (phylink_autoneg_inband(mode)) {
+ dev_err(dev->dev, "In-band AN not supported!\n");
+ return;
+ }
+
+ ksz_set_xmii(dev, port, state->interface);
+
+ lan937x_setup_rgmii_delay(dev, port);
+}
+
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);
@@ -821,7 +847,7 @@ static int lan937x_connect_tag_protocol(struct dsa_switch *ds,
}
const struct phylink_mac_ops lan937x_phylink_mac_ops = {
- .mac_config = ksz_phylink_mac_config,
+ .mac_config = lan937x_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,
@@ -838,7 +864,6 @@ const struct ksz_dev_ops lan937x_dev_ops = {
.r_mib_stat64 = ksz_r_mib_stats64,
.freeze_mib = ksz9477_freeze_mib,
.port_init_cnt = ksz9477_port_init_cnt,
- .setup_rgmii_delay = lan937x_setup_rgmii_delay,
.tc_cbs_set_cinc = lan937x_tc_cbs_set_cinc,
.init = lan937x_switch_init,
};
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 5/9] net: dsa: microchip: implement .support_eee() only if needed
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
` (3 preceding siblings ...)
2026-05-26 9:47 ` [PATCH net-next 4/9] net: dsa: microchip: remove setup_rgmii_delay() KSZ operation Bastien Curutchet (Schneider Electric)
@ 2026-05-26 9:47 ` Bastien Curutchet (Schneider Electric)
2026-06-01 8:55 ` Paolo Abeni
2026-05-26 9:47 ` [PATCH net-next 6/9] net: dsa: microchip: implement .{get/set}_wol " Bastien Curutchet (Schneider Electric)
` (3 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric)
The .support_eee() operation is optional. Yet, it is implemented by the
KSZ switches through a common functon that reports false for every chip
except for KSZ8563, KSZ9563 and KSZ9893 from the KSZ9477 family.
Remove the implementation from the switches that don't support EEE.
Implement instead a ksz9477-specific suppor_eee for these three supported
switches.
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz8.c | 3 --
drivers/net/dsa/microchip/ksz9477.c | 50 +++++++++++++++++++++++++++-
drivers/net/dsa/microchip/ksz_common.c | 57 --------------------------------
drivers/net/dsa/microchip/ksz_common.h | 1 -
drivers/net/dsa/microchip/lan937x_main.c | 1 -
5 files changed, 49 insertions(+), 63 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index 98cf7239057d..f297aa03f42a 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -2477,7 +2477,6 @@ const struct dsa_switch_ops ksz8463_switch_ops = {
.port_txtstamp = ksz_port_txtstamp,
.port_rxtstamp = ksz_port_rxtstamp,
.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,
@@ -2534,7 +2533,6 @@ const struct dsa_switch_ops ksz87xx_switch_ops = {
.port_txtstamp = ksz_port_txtstamp,
.port_rxtstamp = ksz_port_rxtstamp,
.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,
@@ -2592,7 +2590,6 @@ const struct dsa_switch_ops ksz88xx_switch_ops = {
.port_txtstamp = ksz_port_txtstamp,
.port_rxtstamp = ksz_port_rxtstamp,
.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,
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index a39541d29ad5..e0b3724a7558 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -1909,6 +1909,54 @@ void ksz9477_phylink_mac_link_up(struct phylink_config *config,
ksz9477_duplex_flowctrl(dev, port, duplex, tx_pause, rx_pause);
}
+/**
+ * ksz9477_support_eee - Determine Energy Efficient Ethernet (EEE) support for a
+ * port
+ * @ds: Pointer to the DSA switch structure
+ * @port: Port number to check
+ *
+ * This function also documents devices where EEE was initially advertised but
+ * later withdrawn due to reliability issues, as described in official errata
+ * documents. These devices are explicitly listed to record known limitations,
+ * even if there is no technical necessity for runtime checks.
+ *
+ * Returns: true if the internal PHY on the given port supports fully
+ * operational EEE, false otherwise.
+ */
+static bool ksz9477_support_eee(struct dsa_switch *ds, int port)
+{
+ struct ksz_device *dev = ds->priv;
+
+ if (!dev->info->internal_phy[port])
+ return false;
+
+ switch (dev->chip_id) {
+ case KSZ8563_CHIP_ID:
+ case KSZ9563_CHIP_ID:
+ case KSZ9893_CHIP_ID:
+ return true;
+ default:
+ /* KSZ8567R Errata DS80000752C Module 4 */
+ /* KSZ9477S Errata DS80000754A Module 4 */
+ /* KSZ9567S Errata DS80000756A Module 4 */
+ /* KSZ9896C Errata DS80000757A Module 3 */
+ /* KSZ9897R Errata DS80000758C Module 4 */
+ /* Energy Efficient Ethernet (EEE) feature select must be
+ * manually disabled
+ * The EEE feature is enabled by default, but it is not fully
+ * operational. It must be manually disabled through register
+ * controls. If not disabled, the PHY ports can auto-negotiate
+ * to enable EEE, and this feature can cause link drops when
+ * linked to another device supporting EEE.
+ *
+ * The same item appears in the errata for all switches above.
+ */
+ break;
+ }
+
+ return false;
+}
+
static struct phylink_pcs *
ksz9477_phylink_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
@@ -1998,7 +2046,7 @@ const struct dsa_switch_ops ksz9477_switch_ops = {
.cls_flower_add = ksz9477_cls_flower_add,
.cls_flower_del = ksz9477_cls_flower_del,
.port_setup_tc = ksz_setup_tc,
- .support_eee = ksz_support_eee,
+ .support_eee = ksz9477_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,
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index d6511fcebcf2..475886b8c255 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3052,63 +3052,6 @@ int ksz_max_mtu(struct dsa_switch *ds, int port)
return -EOPNOTSUPP;
}
-/**
- * ksz_support_eee - Determine Energy Efficient Ethernet (EEE) support for a
- * port
- * @ds: Pointer to the DSA switch structure
- * @port: Port number to check
- *
- * This function also documents devices where EEE was initially advertised but
- * later withdrawn due to reliability issues, as described in official errata
- * documents. These devices are explicitly listed to record known limitations,
- * even if there is no technical necessity for runtime checks.
- *
- * Returns: true if the internal PHY on the given port supports fully
- * operational EEE, false otherwise.
- */
-bool ksz_support_eee(struct dsa_switch *ds, int port)
-{
- struct ksz_device *dev = ds->priv;
-
- if (!dev->info->internal_phy[port])
- return false;
-
- switch (dev->chip_id) {
- case KSZ8563_CHIP_ID:
- case KSZ9563_CHIP_ID:
- case KSZ9893_CHIP_ID:
- return true;
- case KSZ8567_CHIP_ID:
- /* KSZ8567R Errata DS80000752C Module 4 */
- case KSZ8765_CHIP_ID:
- case KSZ8794_CHIP_ID:
- case KSZ8795_CHIP_ID:
- /* KSZ879x/KSZ877x/KSZ876x Errata DS80000687C Module 2 */
- case KSZ9477_CHIP_ID:
- /* KSZ9477S Errata DS80000754A Module 4 */
- case KSZ9567_CHIP_ID:
- /* KSZ9567S Errata DS80000756A Module 4 */
- case KSZ9896_CHIP_ID:
- /* KSZ9896C Errata DS80000757A Module 3 */
- case KSZ9897_CHIP_ID:
- case LAN9646_CHIP_ID:
- /* KSZ9897R Errata DS80000758C Module 4 */
- /* Energy Efficient Ethernet (EEE) feature select must be
- * manually disabled
- * The EEE feature is enabled by default, but it is not fully
- * operational. It must be manually disabled through register
- * controls. If not disabled, the PHY ports can auto-negotiate
- * to enable EEE, and this feature can cause link drops when
- * linked to another device supporting EEE.
- *
- * The same item appears in the errata for all switches above.
- */
- break;
- }
-
- return false;
-}
-
int ksz_set_mac_eee(struct dsa_switch *ds, int port,
struct ethtool_keee *e)
{
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index ab08c98ed257..33cb2c44004b 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -477,7 +477,6 @@ void ksz_phylink_mac_link_down(struct phylink_config *config,
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);
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index f8f220242f7a..4cbbcf7993c9 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -915,7 +915,6 @@ const struct dsa_switch_ops lan937x_switch_ops = {
.port_txtstamp = ksz_port_txtstamp,
.port_rxtstamp = ksz_port_rxtstamp,
.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,
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 6/9] net: dsa: microchip: implement .{get/set}_wol only if needed
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
` (4 preceding siblings ...)
2026-05-26 9:47 ` [PATCH net-next 5/9] net: dsa: microchip: implement .support_eee() only if needed Bastien Curutchet (Schneider Electric)
@ 2026-05-26 9:47 ` Bastien Curutchet (Schneider Electric)
2026-06-01 8:59 ` Paolo Abeni
2026-05-26 9:47 ` [PATCH net-next 7/9] net: dsa: microchip: implement port_hsr_join for KSZ9477 only Bastien Curutchet (Schneider Electric)
` (2 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric)
All the KSZ switches use common {get/set}_wol operations while only the
ksz9477 and the ksz87xx families really support it. These operations are
optional so there is no point implementing them to return -EOPNOTSUPP.
Remove the {get/set}_wol callbacks from the switch operations for the
ksz88xx, the ksz8463 and the lan937x families.
Remove the family check from the common {get/set}_wol implementation.
Note that is_ksz9477() is only true for the KSZ9477 so this change will
also add WoL support for the other switches using the
ksz9477_switch_ops. I checked their datasheet, they implement the same
PME_WOL registers, at the same addresses, so this should go fine.
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz8.c | 4 ----
drivers/net/dsa/microchip/ksz_common.c | 9 ++-------
drivers/net/dsa/microchip/lan937x_main.c | 2 --
3 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index f297aa03f42a..38549dfdce7c 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -2467,8 +2467,6 @@ const struct dsa_switch_ops ksz8463_switch_ops = {
.get_pause_stats = ksz_get_pause_stats,
.port_change_mtu = ksz8_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,
@@ -2580,8 +2578,6 @@ const struct dsa_switch_ops ksz88xx_switch_ops = {
.get_pause_stats = ksz_get_pause_stats,
.port_change_mtu = ksz8_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,
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 475886b8c255..2d0150b37a40 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3745,9 +3745,6 @@ void ksz_get_wol(struct dsa_switch *ds, int port,
u8 pme_ctrl;
int ret;
- if (!is_ksz9477(dev) && !ksz_is_ksz87xx(dev))
- return;
-
if (!dev->wakeup_source)
return;
@@ -3798,9 +3795,6 @@ int ksz_set_wol(struct dsa_switch *ds, int port,
if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
return -EINVAL;
- if (!is_ksz9477(dev) && !ksz_is_ksz87xx(dev))
- return -EOPNOTSUPP;
-
if (!dev->wakeup_source)
return -EOPNOTSUPP;
@@ -3913,7 +3907,8 @@ int ksz_port_set_mac_address(struct dsa_switch *ds, int port,
*/
wol.wolopts = 0;
- ksz_get_wol(ds, dp->index, &wol);
+ if (ds->ops->get_wol)
+ ds->ops->get_wol(ds, dp->index, &wol);
if (wol.wolopts & WAKE_MAGIC) {
dev_err(ds->dev,
"Cannot change MAC address on port %d with active Wake on Magic Packet\n",
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index 4cbbcf7993c9..5e55f92fb0d4 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -905,8 +905,6 @@ const struct dsa_switch_ops lan937x_switch_ops = {
.get_pause_stats = ksz_get_pause_stats,
.port_change_mtu = lan937x_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,
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 7/9] net: dsa: microchip: implement port_hsr_join for KSZ9477 only
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
` (5 preceding siblings ...)
2026-05-26 9:47 ` [PATCH net-next 6/9] net: dsa: microchip: implement .{get/set}_wol " Bastien Curutchet (Schneider Electric)
@ 2026-05-26 9:47 ` Bastien Curutchet (Schneider Electric)
2026-06-01 9:03 ` Paolo Abeni
2026-05-26 9:47 ` [PATCH net-next 8/9] net: dsa: microchip: implement lan937x-specific MDIO registration Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 9/9] net: dsa: microchip: implement port_teardown only if needed Bastien Curutchet (Schneider Electric)
8 siblings, 1 reply; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric)
All switches implement the optional .port_hsr_join operation while only
the KSZ9477 truly supports it.
Remove the common port_hsr_join implementation.
Replace it with a specific implementation for the KSZ9477 case.
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz8.c | 6 ---
drivers/net/dsa/microchip/ksz9477.c | 64 ++++++++++++++++++++++++++++--
drivers/net/dsa/microchip/ksz9477.h | 2 -
drivers/net/dsa/microchip/ksz_common.c | 67 --------------------------------
drivers/net/dsa/microchip/ksz_common.h | 4 --
drivers/net/dsa/microchip/lan937x_main.c | 2 -
6 files changed, 60 insertions(+), 85 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index 38549dfdce7c..bea66183238e 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -2448,8 +2448,6 @@ const struct dsa_switch_ops ksz8463_switch_ops = {
.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,
@@ -2499,8 +2497,6 @@ const struct dsa_switch_ops ksz87xx_switch_ops = {
.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,
@@ -2556,8 +2552,6 @@ const struct dsa_switch_ops ksz88xx_switch_ops = {
.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,
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index e0b3724a7558..d7903814a2a5 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -12,6 +12,7 @@
#include <linux/platform_data/microchip-ksz.h>
#include <linux/phy.h>
#include <linux/if_bridge.h>
+#include <linux/if_hsr.h>
#include <linux/if_vlan.h>
#include <net/dsa.h>
#include <net/switchdev.h>
@@ -1707,12 +1708,51 @@ static int ksz9477_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val)
*/
#define KSZ9477_SUPPORTED_HSR_FEATURES (NETIF_F_HW_HSR_DUP | NETIF_F_HW_HSR_FWD)
-void ksz9477_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr)
+static int ksz9477_hsr_join(struct dsa_switch *ds, int port,
+ struct net_device *hsr,
+ struct netlink_ext_ack *extack)
{
struct ksz_device *dev = ds->priv;
struct net_device *user;
struct dsa_port *hsr_dp;
u8 data, hsr_ports = 0;
+ enum hsr_version ver;
+ int ret;
+
+ ret = hsr_get_version(hsr, &ver);
+ if (ret)
+ return ret;
+
+ if (dev->chip_id != KSZ9477_CHIP_ID) {
+ NL_SET_ERR_MSG_MOD(extack, "Chip does not support HSR offload");
+ return -EOPNOTSUPP;
+ }
+
+ /* KSZ9477 can support HW offloading of only 1 HSR device */
+ if (dev->hsr_dev && hsr != dev->hsr_dev) {
+ NL_SET_ERR_MSG_MOD(extack, "Offload supported for a single HSR");
+ return -EOPNOTSUPP;
+ }
+
+ /* KSZ9477 only supports HSR v0 and v1 */
+ if (!(ver == HSR_V0 || ver == HSR_V1)) {
+ NL_SET_ERR_MSG_MOD(extack, "Only HSR v0 and v1 supported");
+ return -EOPNOTSUPP;
+ }
+
+ /* KSZ9477 can only perform HSR offloading for up to two ports */
+ if (hweight8(dev->hsr_ports) >= 2) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Cannot offload more than two ports - using software HSR");
+ return -EOPNOTSUPP;
+ }
+
+ /* Self MAC address filtering, to avoid frames traversing
+ * the HSR ring more than once.
+ */
+ ret = ksz_switch_macaddr_get(ds, port, extack);
+ if (ret)
+ return ret;
/* Program which port(s) shall support HSR */
ksz_rmw32(dev, REG_HSR_PORT_MAP__4, BIT(port), BIT(port));
@@ -1744,12 +1784,20 @@ void ksz9477_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr)
/* Setup HW supported features for lan HSR ports */
user = dsa_to_port(ds, port)->user;
user->features |= KSZ9477_SUPPORTED_HSR_FEATURES;
+
+ dev->hsr_dev = hsr;
+ dev->hsr_ports |= BIT(port);
+
+ return 0;
}
-void ksz9477_hsr_leave(struct dsa_switch *ds, int port, struct net_device *hsr)
+static int ksz9477_hsr_leave(struct dsa_switch *ds, int port,
+ struct net_device *hsr)
{
struct ksz_device *dev = ds->priv;
+ WARN_ON(dev->chip_id != KSZ9477_CHIP_ID);
+
/* Clear port HSR support */
ksz_rmw32(dev, REG_HSR_PORT_MAP__4, BIT(port), 0);
@@ -1758,6 +1806,14 @@ void ksz9477_hsr_leave(struct dsa_switch *ds, int port, struct net_device *hsr)
/* Disable per port self-address filtering */
ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL, PORT_SRC_ADDR_FILTER, false);
+
+ dev->hsr_ports &= ~BIT(port);
+ if (!dev->hsr_ports)
+ dev->hsr_dev = NULL;
+
+ ksz_switch_macaddr_put(ds);
+
+ return 0;
}
static int ksz9477_switch_init(struct ksz_device *dev)
@@ -2012,8 +2068,8 @@ const struct dsa_switch_ops ksz9477_switch_ops = {
.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_hsr_join = ksz9477_hsr_join,
+ .port_hsr_leave = ksz9477_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,
diff --git a/drivers/net/dsa/microchip/ksz9477.h b/drivers/net/dsa/microchip/ksz9477.h
index 599db0a6ba2e..92a1d889224d 100644
--- a/drivers/net/dsa/microchip/ksz9477.h
+++ b/drivers/net/dsa/microchip/ksz9477.h
@@ -45,8 +45,6 @@ int ksz9477_mdb_del(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb, struct dsa_db db);
int ksz9477_enable_stp_addr(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);
int ksz9477_port_acl_init(struct ksz_device *dev, int port);
void ksz9477_port_acl_free(struct ksz_device *dev, int port);
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 2d0150b37a40..404399737cea 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -16,7 +16,6 @@
#include <linux/etherdevice.h>
#include <linux/if_bridge.h>
#include <linux/if_vlan.h>
-#include <linux/if_hsr.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
@@ -4043,72 +4042,6 @@ void ksz_switch_macaddr_put(struct dsa_switch *ds)
kfree(switch_macaddr);
}
-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;
- int ret;
-
- ret = hsr_get_version(hsr, &ver);
- if (ret)
- return ret;
-
- if (dev->chip_id != KSZ9477_CHIP_ID) {
- NL_SET_ERR_MSG_MOD(extack, "Chip does not support HSR offload");
- return -EOPNOTSUPP;
- }
-
- /* KSZ9477 can support HW offloading of only 1 HSR device */
- if (dev->hsr_dev && hsr != dev->hsr_dev) {
- NL_SET_ERR_MSG_MOD(extack, "Offload supported for a single HSR");
- return -EOPNOTSUPP;
- }
-
- /* KSZ9477 only supports HSR v0 and v1 */
- if (!(ver == HSR_V0 || ver == HSR_V1)) {
- NL_SET_ERR_MSG_MOD(extack, "Only HSR v0 and v1 supported");
- return -EOPNOTSUPP;
- }
-
- /* KSZ9477 can only perform HSR offloading for up to two ports */
- if (hweight8(dev->hsr_ports) >= 2) {
- NL_SET_ERR_MSG_MOD(extack,
- "Cannot offload more than two ports - using software HSR");
- return -EOPNOTSUPP;
- }
-
- /* Self MAC address filtering, to avoid frames traversing
- * the HSR ring more than once.
- */
- ret = ksz_switch_macaddr_get(ds, port, extack);
- if (ret)
- return ret;
-
- ksz9477_hsr_join(ds, port, hsr);
- dev->hsr_dev = hsr;
- dev->hsr_ports |= BIT(port);
-
- return 0;
-}
-
-int ksz_hsr_leave(struct dsa_switch *ds, int port,
- struct net_device *hsr)
-{
- struct ksz_device *dev = ds->priv;
-
- WARN_ON(dev->chip_id != KSZ9477_CHIP_ID);
-
- ksz9477_hsr_leave(ds, port, hsr);
- dev->hsr_ports &= ~BIT(port);
- if (!dev->hsr_ports)
- dev->hsr_dev = NULL;
-
- ksz_switch_macaddr_put(ds);
-
- return 0;
-}
-
int ksz_suspend(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 33cb2c44004b..c8f9ac6c3a38 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -489,10 +489,6 @@ 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);
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index 5e55f92fb0d4..742b919ae4df 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -883,8 +883,6 @@ const struct dsa_switch_ops lan937x_switch_ops = {
.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,
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 8/9] net: dsa: microchip: implement lan937x-specific MDIO registration
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
` (6 preceding siblings ...)
2026-05-26 9:47 ` [PATCH net-next 7/9] net: dsa: microchip: implement port_hsr_join for KSZ9477 only Bastien Curutchet (Schneider Electric)
@ 2026-05-26 9:47 ` Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 9/9] net: dsa: microchip: implement port_teardown only if needed Bastien Curutchet (Schneider Electric)
8 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric)
All the switches use a common mdio_register() function that uses two
ksz_dev_ops callbacks (.mdio_bus_preinit() and .create_phy_addr_map())
to handle the lan937x specific case. These two callbacks are used only
at this place in the code.
Implement a new lan937x-specific MDIO registration functions that uses
these two lan937x-specific functions. The lan937x bindings don't
have any 'interrupts' property so this lan937x_mdio_register() doesn't
call ksz_irq_phy_setup().
Expose the common ksz_*_mdio_{read/write} functions so they can be used
in lan937x.c
Remove the callbacks from ksz_dev_ops.
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz_common.c | 30 +++-------
drivers/net/dsa/microchip/ksz_common.h | 42 ++------------
drivers/net/dsa/microchip/lan937x_main.c | 99 +++++++++++++++++++++++++++++++-
3 files changed, 110 insertions(+), 61 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 404399737cea..708dddf2c6cf 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -2256,7 +2256,7 @@ static void ksz_update_port_member(struct ksz_device *dev, int port)
dev->dev_ops->cfg_port_member(dev, port, port_member | cpu_port);
}
-static int ksz_sw_mdio_read(struct mii_bus *bus, int addr, int regnum)
+int ksz_sw_mdio_read(struct mii_bus *bus, int addr, int regnum)
{
struct ksz_device *dev = bus->priv;
struct dsa_switch *ds = dev->ds;
@@ -2264,8 +2264,7 @@ static int ksz_sw_mdio_read(struct mii_bus *bus, int addr, int regnum)
return ds->ops->phy_read(ds, addr, regnum);
}
-static int ksz_sw_mdio_write(struct mii_bus *bus, int addr, int regnum,
- u16 val)
+int ksz_sw_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
{
struct ksz_device *dev = bus->priv;
struct dsa_switch *ds = dev->ds;
@@ -2286,7 +2285,7 @@ static int ksz_sw_mdio_write(struct mii_bus *bus, int addr, int regnum,
*
* Return: Value of the PHY register, or a negative error code on failure.
*/
-static int ksz_parent_mdio_read(struct mii_bus *bus, int addr, int regnum)
+int ksz_parent_mdio_read(struct mii_bus *bus, int addr, int regnum)
{
struct ksz_device *dev = bus->priv;
@@ -2306,8 +2305,7 @@ static int ksz_parent_mdio_read(struct mii_bus *bus, int addr, int regnum)
*
* Return: 0 on success, or a negative error code on failure.
*/
-static int ksz_parent_mdio_write(struct mii_bus *bus, int addr, int regnum,
- u16 val)
+int ksz_parent_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
{
struct ksz_device *dev = bus->priv;
@@ -2415,8 +2413,8 @@ static void ksz_irq_phy_free(struct ksz_device *dev)
*
* Return: 0 on success, or a negative error code on failure.
*/
-static int ksz_parse_dt_phy_config(struct ksz_device *dev, struct mii_bus *bus,
- struct device_node *mdio_np)
+int ksz_parse_dt_phy_config(struct ksz_device *dev, struct mii_bus *bus,
+ struct device_node *mdio_np)
{
struct device_node *phy_node, *phy_parent_node;
bool phys_are_valid = true;
@@ -2519,20 +2517,8 @@ int ksz_mdio_register(struct ksz_device *dev)
goto put_mdio_node;
}
- if (dev->dev_ops->mdio_bus_preinit) {
- ret = dev->dev_ops->mdio_bus_preinit(dev, !!parent_bus);
- if (ret)
- goto put_mdio_node;
- }
-
- if (dev->dev_ops->create_phy_addr_map) {
- ret = dev->dev_ops->create_phy_addr_map(dev, !!parent_bus);
- if (ret)
- goto put_mdio_node;
- } else {
- for (i = 0; i < dev->info->port_cnt; i++)
- dev->phy_addr_map[i] = i;
- }
+ for (i = 0; i < dev->info->port_cnt; i++)
+ dev->phy_addr_map[i] = i;
bus->priv = dev;
if (parent_bus) {
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index c8f9ac6c3a38..a7fc23ced38c 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -362,42 +362,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);
- /**
- * @mdio_bus_preinit: Function pointer to pre-initialize the MDIO bus
- * for accessing PHYs.
- * @dev: Pointer to device structure.
- * @side_mdio: Boolean indicating if the PHYs are accessed over a side
- * MDIO bus.
- *
- * This function pointer is used to configure the MDIO bus for PHY
- * access before initiating regular PHY operations. It enables either
- * SPI/I2C or side MDIO access modes by unlocking necessary registers
- * and setting up access permissions for the selected mode.
- *
- * Return:
- * - 0 on success.
- * - Negative error code on failure.
- */
- int (*mdio_bus_preinit)(struct ksz_device *dev, bool side_mdio);
-
- /**
- * @create_phy_addr_map: Function pointer to create a port-to-PHY
- * address map.
- * @dev: Pointer to device structure.
- * @side_mdio: Boolean indicating if the PHYs are accessed over a side
- * MDIO bus.
- *
- * This function pointer is responsible for mapping switch ports to PHY
- * addresses according to the configured access mode (SPI or side MDIO)
- * and the device’s strap configuration. The mapping setup may vary
- * depending on the chip variant and configuration. Ensures the correct
- * address mapping for PHY communication.
- *
- * Return:
- * - 0 on success.
- * - Negative error code on failure (e.g., invalid configuration).
- */
- int (*create_phy_addr_map)(struct ksz_device *dev, bool side_mdio);
void (*r_mib_cnt)(struct ksz_device *dev, int port, u16 addr,
u64 *cnt);
void (*r_mib_pkt)(struct ksz_device *dev, int port, u16 addr,
@@ -493,6 +457,12 @@ int ksz_port_set_mac_address(struct dsa_switch *ds, int port,
int ksz_suspend(struct dsa_switch *ds);
int ksz_resume(struct dsa_switch *ds);
+int ksz_parse_dt_phy_config(struct ksz_device *dev, struct mii_bus *bus,
+ struct device_node *mdio_np);
+int ksz_sw_mdio_read(struct mii_bus *bus, int addr, int regnum);
+int ksz_sw_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val);
+int ksz_parent_mdio_read(struct mii_bus *bus, int addr, int regnum);
+int ksz_parent_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val);
int ksz_mdio_register(struct ksz_device *dev);
int ksz_pirq_setup(struct ksz_device *dev, u8 p);
int ksz_girq_setup(struct ksz_device *dev);
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index 742b919ae4df..73ad99dac72d 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/iopoll.h>
#include <linux/phy.h>
+#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/if_bridge.h>
#include <linux/if_vlan.h>
@@ -681,6 +682,100 @@ static int lan937x_switch_init(struct ksz_device *dev)
return 0;
}
+/**
+ * lan937x_mdio_register - Register and configure the MDIO bus for the LAN937x.
+ * @dev: Pointer to the KSZ device structure.
+ *
+ * This function sets up and registers an MDIO bus for a LAN937x switch,
+ * allowing access to its internal PHYs. If the device supports side MDIO,
+ * the function will configure the external MDIO controller specified by the
+ * "mdio-parent-bus" device tree property to directly manage internal PHYs.
+ * Otherwise, SPI or I2C access is set up for PHY access.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+static int lan937x_mdio_register(struct ksz_device *dev)
+{
+ struct device_node *parent_bus_node;
+ struct mii_bus *parent_bus = NULL;
+ struct dsa_switch *ds = dev->ds;
+ struct device_node *mdio_np;
+ struct mii_bus *bus;
+ int ret;
+
+ mdio_np = of_get_child_by_name(dev->dev->of_node, "mdio");
+ if (!mdio_np)
+ return 0;
+
+ parent_bus_node = of_parse_phandle(mdio_np, "mdio-parent-bus", 0);
+ if (parent_bus_node && !dev->info->phy_side_mdio_supported) {
+ dev_err(dev->dev, "Side MDIO bus is not supported for this HW, ignoring 'mdio-parent-bus' property.\n");
+ ret = -EINVAL;
+
+ goto put_mdio_node;
+ } else if (parent_bus_node) {
+ parent_bus = of_mdio_find_bus(parent_bus_node);
+ if (!parent_bus) {
+ ret = -EPROBE_DEFER;
+
+ goto put_mdio_node;
+ }
+
+ dev->parent_mdio_bus = parent_bus;
+ }
+
+ bus = devm_mdiobus_alloc(ds->dev);
+ if (!bus) {
+ ret = -ENOMEM;
+ goto put_mdio_node;
+ }
+
+ ret = lan937x_mdio_bus_preinit(dev, !!parent_bus);
+ if (ret)
+ goto put_mdio_node;
+
+ ret = lan937x_create_phy_addr_map(dev, !!parent_bus);
+ if (ret)
+ goto put_mdio_node;
+
+ bus->priv = dev;
+ if (parent_bus) {
+ bus->read = ksz_parent_mdio_read;
+ bus->write = ksz_parent_mdio_write;
+ bus->name = "KSZ side MDIO";
+ snprintf(bus->id, MII_BUS_ID_SIZE, "ksz-side-mdio-%d",
+ ds->index);
+ } else {
+ bus->read = ksz_sw_mdio_read;
+ bus->write = ksz_sw_mdio_write;
+ bus->name = "ksz user smi";
+ if (ds->dst->index != 0)
+ snprintf(bus->id, MII_BUS_ID_SIZE, "SMI-%d-%d", ds->dst->index, ds->index);
+ else
+ snprintf(bus->id, MII_BUS_ID_SIZE, "SMI-%d", ds->index);
+ }
+
+ ret = ksz_parse_dt_phy_config(dev, bus, mdio_np);
+ if (ret)
+ goto put_mdio_node;
+
+ ds->phys_mii_mask = bus->phy_mask;
+ bus->parent = ds->dev;
+
+ ds->user_mii_bus = bus;
+
+ ret = devm_of_mdiobus_register(ds->dev, bus, mdio_np);
+ if (ret)
+ dev_err(ds->dev, "unable to register MDIO bus %s\n",
+ bus->id);
+
+put_mdio_node:
+ of_node_put(mdio_np);
+ of_node_put(parent_bus_node);
+
+ return ret;
+}
+
static int lan937x_setup(struct dsa_switch *ds)
{
struct ksz_device *dev = ds->priv;
@@ -794,7 +889,7 @@ static int lan937x_setup(struct dsa_switch *ds)
goto port_release;
}
- ret = ksz_mdio_register(dev);
+ ret = lan937x_mdio_register(dev);
if (ret < 0) {
dev_err(dev->dev, "failed to register the mdio");
goto out_ptp_clock_unregister;
@@ -857,8 +952,6 @@ const struct phylink_mac_ops lan937x_phylink_mac_ops = {
const struct ksz_dev_ops lan937x_dev_ops = {
.get_port_addr = ksz9477_get_port_addr,
.cfg_port_member = ksz9477_cfg_port_member,
- .mdio_bus_preinit = lan937x_mdio_bus_preinit,
- .create_phy_addr_map = lan937x_create_phy_addr_map,
.r_mib_cnt = ksz9477_r_mib_cnt,
.r_mib_pkt = ksz9477_r_mib_pkt,
.r_mib_stat64 = ksz_r_mib_stats64,
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 9/9] net: dsa: microchip: implement port_teardown only if needed
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
` (7 preceding siblings ...)
2026-05-26 9:47 ` [PATCH net-next 8/9] net: dsa: microchip: implement lan937x-specific MDIO registration Bastien Curutchet (Schneider Electric)
@ 2026-05-26 9:47 ` Bastien Curutchet (Schneider Electric)
8 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet (Schneider Electric) @ 2026-05-26 9:47 UTC (permalink / raw)
To: Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel,
Bastien Curutchet (Schneider Electric)
The port_teardown() operation is optional. Yet, it is implemented by all
the KSZ switches through a common function that doesn't do anything for
the switches that aren't part of the ksz9477 family
Remove the implementation from the switches that don't need it.
Implement instead a ksz9477-specific port_teardown.
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
drivers/net/dsa/microchip/ksz8.c | 3 ---
drivers/net/dsa/microchip/ksz9477.c | 10 +++++++++-
drivers/net/dsa/microchip/ksz_common.c | 19 -------------------
drivers/net/dsa/microchip/ksz_common.h | 1 -
drivers/net/dsa/microchip/lan937x_main.c | 1 -
5 files changed, 9 insertions(+), 25 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index bea66183238e..e5d4ade0b29a 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -2450,7 +2450,6 @@ const struct dsa_switch_ops ksz8463_switch_ops = {
.port_bridge_leave = ksz_port_bridge_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 = ksz8_flush_dyn_mac_table,
@@ -2499,7 +2498,6 @@ const struct dsa_switch_ops ksz87xx_switch_ops = {
.port_bridge_leave = ksz_port_bridge_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 = ksz8_flush_dyn_mac_table,
@@ -2554,7 +2552,6 @@ const struct dsa_switch_ops ksz88xx_switch_ops = {
.port_bridge_leave = ksz_port_bridge_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 = ksz8_flush_dyn_mac_table,
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index d7903814a2a5..c2220afd7466 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -1940,6 +1940,14 @@ static void ksz9477_duplex_flowctrl(struct ksz_device *dev, int port, int duplex
ksz_prmw8(dev, port, regs[P_XMII_CTRL_0], mask, val);
}
+static void ksz9477_port_teardown(struct dsa_switch *ds, int port)
+{
+ struct ksz_device *dev = ds->priv;
+
+ if (dsa_is_user_port(ds, port))
+ ksz9477_port_acl_free(dev, port);
+}
+
void ksz9477_phylink_mac_link_up(struct phylink_config *config,
struct phy_device *phydev,
unsigned int mode,
@@ -2072,7 +2080,7 @@ const struct dsa_switch_ops ksz9477_switch_ops = {
.port_hsr_leave = ksz9477_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_teardown = ksz9477_port_teardown,
.port_pre_bridge_flags = ksz_port_pre_bridge_flags,
.port_bridge_flags = ksz_port_bridge_flags,
.port_fast_age = ksz9477_flush_dyn_mac_table,
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 708dddf2c6cf..3f5b1c4e7169 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -2953,25 +2953,6 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
ksz_update_port_member(dev, port);
}
-void ksz_port_teardown(struct dsa_switch *ds, int port)
-{
- struct ksz_device *dev = ds->priv;
-
- switch (dev->chip_id) {
- case KSZ8563_CHIP_ID:
- case KSZ8567_CHIP_ID:
- case KSZ9477_CHIP_ID:
- case KSZ9563_CHIP_ID:
- case KSZ9567_CHIP_ID:
- case KSZ9893_CHIP_ID:
- case KSZ9896_CHIP_ID:
- case KSZ9897_CHIP_ID:
- case LAN9646_CHIP_ID:
- if (dsa_is_user_port(ds, port))
- ksz9477_port_acl_free(dev, port);
- }
-}
-
int ksz_port_pre_bridge_flags(struct dsa_switch *ds, int port,
struct switchdev_brport_flags flags,
struct netlink_ext_ack *extack)
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index a7fc23ced38c..80cb4265dbdc 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -387,7 +387,6 @@ int ksz_switch_suspend(struct device *dev);
int ksz_switch_resume(struct device *dev);
void ksz_teardown(struct dsa_switch *ds);
-void ksz_port_teardown(struct dsa_switch *ds, int port);
void ksz_init_mib_timer(struct ksz_device *dev);
bool ksz_is_port_mac_global_usable(struct dsa_switch *ds, int port);
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index 73ad99dac72d..084ee811f6e2 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -978,7 +978,6 @@ const struct dsa_switch_ops lan937x_switch_ops = {
.port_bridge_leave = ksz_port_bridge_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 = ksz9477_flush_dyn_mac_table,
--
2.54.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 4/9] net: dsa: microchip: remove setup_rgmii_delay() KSZ operation
2026-05-26 9:47 ` [PATCH net-next 4/9] net: dsa: microchip: remove setup_rgmii_delay() KSZ operation Bastien Curutchet (Schneider Electric)
@ 2026-06-01 8:49 ` Paolo Abeni
2026-06-02 12:15 ` Bastien Curutchet
0 siblings, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2026-06-01 8:49 UTC (permalink / raw)
To: Bastien Curutchet (Schneider Electric),
Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
> setup_rgmii_delay() operation is only used once during the common phylink
> MAC configuration. Only the lan937x switch implements this
> setup_rgmii_delay().
>
> Remove the setup_rgmii_delay operation from ksz_dev_ops.
> Implement a lan937x-specific phylink MAC configuration that does this
> RGMII delay setup.
> Export ksz_set_xmii since it's needed by the lan937x implementation.
>
> Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
> ---
> drivers/net/dsa/microchip/ksz_common.c | 6 +-----
> drivers/net/dsa/microchip/ksz_common.h | 2 +-
> drivers/net/dsa/microchip/lan937x_main.c | 29 +++++++++++++++++++++++++++--
> 3 files changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
> index 5fb151fbf4f3..d6511fcebcf2 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -3127,8 +3127,7 @@ int ksz_set_mac_eee(struct dsa_switch *ds, int port,
> return 0;
> }
>
> -static void ksz_set_xmii(struct ksz_device *dev, int port,
> - phy_interface_t interface)
> +void ksz_set_xmii(struct ksz_device *dev, int port, phy_interface_t interface)
> {
> const u8 *bitval = dev->info->xmii_ctrl1;
> struct ksz_port *p = &dev->ports[port];
> @@ -3233,9 +3232,6 @@ void ksz_phylink_mac_config(struct phylink_config *config,
> }
>
> ksz_set_xmii(dev, port, state->interface);
> -
> - if (dev->dev_ops->setup_rgmii_delay)
> - dev->dev_ops->setup_rgmii_delay(dev, port);
> }
>
> bool ksz_get_gbit(struct ksz_device *dev, int port)
> diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
> index 804912fdd2db..ab08c98ed257 100644
> --- a/drivers/net/dsa/microchip/ksz_common.h
> +++ b/drivers/net/dsa/microchip/ksz_common.h
> @@ -410,7 +410,6 @@ struct ksz_dev_ops {
> u8 data);
> void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze);
> void (*port_init_cnt)(struct ksz_device *dev, int port);
> - void (*setup_rgmii_delay)(struct ksz_device *dev, int port);
> int (*tc_cbs_set_cinc)(struct ksz_device *dev, int port, u32 val);
> int (*init)(struct ksz_device *dev);
> };
> @@ -468,6 +467,7 @@ void ksz_phylink_get_caps(struct dsa_switch *ds, 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_set_xmii(struct ksz_device *dev, int port, phy_interface_t interface);
> void ksz_phylink_mac_config(struct phylink_config *config,
> unsigned int mode,
> const struct phylink_link_state *state);
> diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
> index 57e289637193..f8f220242f7a 100644
> --- a/drivers/net/dsa/microchip/lan937x_main.c
> +++ b/drivers/net/dsa/microchip/lan937x_main.c
> @@ -643,6 +643,32 @@ static void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port)
> }
> }
>
> +static void lan937x_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;
> + int port = dp->index;
> +
> + /* Internal PHYs */
> + if (dev->info->internal_phy[port])
> + return;
> +
> + /* No need to configure XMII control register when using SGMII. */
> + if (ksz_is_sgmii_port(dev, port))
> + return;
> +
> + if (phylink_autoneg_inband(mode)) {
> + dev_err(dev->dev, "In-band AN not supported!\n");
> + return;
> + }
> +
> + ksz_set_xmii(dev, port, state->interface);
> +
> + lan937x_setup_rgmii_delay(dev, port);
I think you can avoid some code duplication with something alike the
following:
- factor out of ksz_phylink_mac_config() a __ksz_phylink_mac_config(),
helper, with the latter doing all the work and returning true when
actually calling ksz_set_xmii()
- implement lan937x_phylink_mac_config() on top of
__ksz_phylink_mac_config():
if (__ksz_phylink_mac_config())
lan937x_setup_rgmii_delay(dev, port);
/P
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 5/9] net: dsa: microchip: implement .support_eee() only if needed
2026-05-26 9:47 ` [PATCH net-next 5/9] net: dsa: microchip: implement .support_eee() only if needed Bastien Curutchet (Schneider Electric)
@ 2026-06-01 8:55 ` Paolo Abeni
2026-06-02 12:21 ` Bastien Curutchet
0 siblings, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2026-06-01 8:55 UTC (permalink / raw)
To: Bastien Curutchet (Schneider Electric),
Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
> diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
> index a39541d29ad5..e0b3724a7558 100644
> --- a/drivers/net/dsa/microchip/ksz9477.c
> +++ b/drivers/net/dsa/microchip/ksz9477.c
> @@ -1909,6 +1909,54 @@ void ksz9477_phylink_mac_link_up(struct phylink_config *config,
> ksz9477_duplex_flowctrl(dev, port, duplex, tx_pause, rx_pause);
> }
>
> +/**
> + * ksz9477_support_eee - Determine Energy Efficient Ethernet (EEE) support for a
> + * port
> + * @ds: Pointer to the DSA switch structure
> + * @port: Port number to check
> + *
> + * This function also documents devices where EEE was initially advertised but
> + * later withdrawn due to reliability issues, as described in official errata
> + * documents. These devices are explicitly listed to record known limitations,
> + * even if there is no technical necessity for runtime checks.
> + *
> + * Returns: true if the internal PHY on the given port supports fully
> + * operational EEE, false otherwise.
> + */
> +static bool ksz9477_support_eee(struct dsa_switch *ds, int port)
> +{
> + struct ksz_device *dev = ds->priv;
> +
> + if (!dev->info->internal_phy[port])
> + return false;
> +
> + switch (dev->chip_id) {
> + case KSZ8563_CHIP_ID:
> + case KSZ9563_CHIP_ID:
> + case KSZ9893_CHIP_ID:
> + return true;
> + default:
> + /* KSZ8567R Errata DS80000752C Module 4 */
> + /* KSZ9477S Errata DS80000754A Module 4 */
> + /* KSZ9567S Errata DS80000756A Module 4 */
> + /* KSZ9896C Errata DS80000757A Module 3 */
> + /* KSZ9897R Errata DS80000758C Module 4 */
Sashiko noted that errata:
/* KSZ879x/KSZ877x/KSZ876x Errata DS80000687C Module 2 */
has been lost above.
> diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
> index f8f220242f7a..4cbbcf7993c9 100644
> --- a/drivers/net/dsa/microchip/lan937x_main.c
> +++ b/drivers/net/dsa/microchip/lan937x_main.c
> @@ -915,7 +915,6 @@ const struct dsa_switch_ops lan937x_switch_ops = {
> .port_txtstamp = ksz_port_txtstamp,
> .port_rxtstamp = ksz_port_rxtstamp,
> .port_setup_tc = ksz_setup_tc,
> - .support_eee = ksz_support_eee,
> .set_mac_eee = ksz_set_mac_eee,
Sashiko noted that `set_mac_eee` usage is gated by `support_eee` presence,
you may want to remove even the set callback.
/P
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 6/9] net: dsa: microchip: implement .{get/set}_wol only if needed
2026-05-26 9:47 ` [PATCH net-next 6/9] net: dsa: microchip: implement .{get/set}_wol " Bastien Curutchet (Schneider Electric)
@ 2026-06-01 8:59 ` Paolo Abeni
2026-06-02 12:34 ` Bastien Curutchet
0 siblings, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2026-06-01 8:59 UTC (permalink / raw)
To: Bastien Curutchet (Schneider Electric),
Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
> @@ -3798,9 +3795,6 @@ int ksz_set_wol(struct dsa_switch *ds, int port,
> if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
> return -EINVAL;
>
> - if (!is_ksz9477(dev) && !ksz_is_ksz87xx(dev))
> - return -EOPNOTSUPP;
Sashiko noted there is still a ksz_is_ksz87xx(dev) check in
ksz_wol_pre_shutdown() which would probably keep WoL broken for the
newly enabled switches.
/P
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 7/9] net: dsa: microchip: implement port_hsr_join for KSZ9477 only
2026-05-26 9:47 ` [PATCH net-next 7/9] net: dsa: microchip: implement port_hsr_join for KSZ9477 only Bastien Curutchet (Schneider Electric)
@ 2026-06-01 9:03 ` Paolo Abeni
2026-06-02 12:35 ` Bastien Curutchet
0 siblings, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2026-06-01 9:03 UTC (permalink / raw)
To: Bastien Curutchet (Schneider Electric),
Woojung Huh, UNGLinuxDriver, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
> @@ -1744,12 +1784,20 @@ void ksz9477_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr)
> /* Setup HW supported features for lan HSR ports */
> user = dsa_to_port(ds, port)->user;
> user->features |= KSZ9477_SUPPORTED_HSR_FEATURES;
> +
> + dev->hsr_dev = hsr;
> + dev->hsr_ports |= BIT(port);
> +
> + return 0;
> }
>
> -void ksz9477_hsr_leave(struct dsa_switch *ds, int port, struct net_device *hsr)
> +static int ksz9477_hsr_leave(struct dsa_switch *ds, int port,
> + struct net_device *hsr)
> {
> struct ksz_device *dev = ds->priv;
>
> + WARN_ON(dev->chip_id != KSZ9477_CHIP_ID);
Since the new op is used only by the relevant switch version, I think
you could/should remove the above warning.
/P
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 4/9] net: dsa: microchip: remove setup_rgmii_delay() KSZ operation
2026-06-01 8:49 ` Paolo Abeni
@ 2026-06-02 12:15 ` Bastien Curutchet
0 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet @ 2026-06-02 12:15 UTC (permalink / raw)
To: Paolo Abeni, Woojung Huh, UNGLinuxDriver, Andrew Lunn,
Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
Hi Paolo,
On 6/1/26 10:49 AM, Paolo Abeni wrote:
> On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
>> setup_rgmii_delay() operation is only used once during the common phylink
>> MAC configuration. Only the lan937x switch implements this
>> setup_rgmii_delay().
>>
>> Remove the setup_rgmii_delay operation from ksz_dev_ops.
>> Implement a lan937x-specific phylink MAC configuration that does this
>> RGMII delay setup.
>> Export ksz_set_xmii since it's needed by the lan937x implementation.
>>
>> Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
>> ---
>> drivers/net/dsa/microchip/ksz_common.c | 6 +-----
>> drivers/net/dsa/microchip/ksz_common.h | 2 +-
>> drivers/net/dsa/microchip/lan937x_main.c | 29 +++++++++++++++++++++++++++--
>> 3 files changed, 29 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
>> index 5fb151fbf4f3..d6511fcebcf2 100644
>> --- a/drivers/net/dsa/microchip/ksz_common.c
>> +++ b/drivers/net/dsa/microchip/ksz_common.c
>> @@ -3127,8 +3127,7 @@ int ksz_set_mac_eee(struct dsa_switch *ds, int port,
>> return 0;
>> }
>>
>> -static void ksz_set_xmii(struct ksz_device *dev, int port,
>> - phy_interface_t interface)
>> +void ksz_set_xmii(struct ksz_device *dev, int port, phy_interface_t interface)
>> {
>> const u8 *bitval = dev->info->xmii_ctrl1;
>> struct ksz_port *p = &dev->ports[port];
>> @@ -3233,9 +3232,6 @@ void ksz_phylink_mac_config(struct phylink_config *config,
>> }
>>
>> ksz_set_xmii(dev, port, state->interface);
>> -
>> - if (dev->dev_ops->setup_rgmii_delay)
>> - dev->dev_ops->setup_rgmii_delay(dev, port);
>> }
>>
>> bool ksz_get_gbit(struct ksz_device *dev, int port)
>> diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
>> index 804912fdd2db..ab08c98ed257 100644
>> --- a/drivers/net/dsa/microchip/ksz_common.h
>> +++ b/drivers/net/dsa/microchip/ksz_common.h
>> @@ -410,7 +410,6 @@ struct ksz_dev_ops {
>> u8 data);
>> void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze);
>> void (*port_init_cnt)(struct ksz_device *dev, int port);
>> - void (*setup_rgmii_delay)(struct ksz_device *dev, int port);
>> int (*tc_cbs_set_cinc)(struct ksz_device *dev, int port, u32 val);
>> int (*init)(struct ksz_device *dev);
>> };
>> @@ -468,6 +467,7 @@ void ksz_phylink_get_caps(struct dsa_switch *ds, 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_set_xmii(struct ksz_device *dev, int port, phy_interface_t interface);
>> void ksz_phylink_mac_config(struct phylink_config *config,
>> unsigned int mode,
>> const struct phylink_link_state *state);
>> diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
>> index 57e289637193..f8f220242f7a 100644
>> --- a/drivers/net/dsa/microchip/lan937x_main.c
>> +++ b/drivers/net/dsa/microchip/lan937x_main.c
>> @@ -643,6 +643,32 @@ static void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port)
>> }
>> }
>>
>> +static void lan937x_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;
>> + int port = dp->index;
>> +
>> + /* Internal PHYs */
>> + if (dev->info->internal_phy[port])
>> + return;
>> +
>> + /* No need to configure XMII control register when using SGMII. */
>> + if (ksz_is_sgmii_port(dev, port))
>> + return;
>> +
>> + if (phylink_autoneg_inband(mode)) {
>> + dev_err(dev->dev, "In-band AN not supported!\n");
>> + return;
>> + }
>> +
>> + ksz_set_xmii(dev, port, state->interface);
>> +
>> + lan937x_setup_rgmii_delay(dev, port);
>
> I think you can avoid some code duplication with something alike the
> following:
>
> - factor out of ksz_phylink_mac_config() a __ksz_phylink_mac_config(),
> helper, with the latter doing all the work and returning true when
> actually calling ksz_set_xmii()
>
> - implement lan937x_phylink_mac_config() on top of
> __ksz_phylink_mac_config():
>
> if (__ksz_phylink_mac_config())
> lan937x_setup_rgmii_delay(dev, port);
>
Indeed, I'll do it in next iteration, thank you.
Best regards,
Bastien
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 5/9] net: dsa: microchip: implement .support_eee() only if needed
2026-06-01 8:55 ` Paolo Abeni
@ 2026-06-02 12:21 ` Bastien Curutchet
0 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet @ 2026-06-02 12:21 UTC (permalink / raw)
To: Paolo Abeni, Woojung Huh, UNGLinuxDriver, Andrew Lunn,
Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
Hi Paolo,
On 6/1/26 10:55 AM, Paolo Abeni wrote:
> On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
>> diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
>> index a39541d29ad5..e0b3724a7558 100644
>> --- a/drivers/net/dsa/microchip/ksz9477.c
>> +++ b/drivers/net/dsa/microchip/ksz9477.c
>> @@ -1909,6 +1909,54 @@ void ksz9477_phylink_mac_link_up(struct phylink_config *config,
>> ksz9477_duplex_flowctrl(dev, port, duplex, tx_pause, rx_pause);
>> }
>>
>> +/**
>> + * ksz9477_support_eee - Determine Energy Efficient Ethernet (EEE) support for a
>> + * port
>> + * @ds: Pointer to the DSA switch structure
>> + * @port: Port number to check
>> + *
>> + * This function also documents devices where EEE was initially advertised but
>> + * later withdrawn due to reliability issues, as described in official errata
>> + * documents. These devices are explicitly listed to record known limitations,
>> + * even if there is no technical necessity for runtime checks.
>> + *
>> + * Returns: true if the internal PHY on the given port supports fully
>> + * operational EEE, false otherwise.
>> + */
>> +static bool ksz9477_support_eee(struct dsa_switch *ds, int port)
>> +{
>> + struct ksz_device *dev = ds->priv;
>> +
>> + if (!dev->info->internal_phy[port])
>> + return false;
>> +
>> + switch (dev->chip_id) {
>> + case KSZ8563_CHIP_ID:
>> + case KSZ9563_CHIP_ID:
>> + case KSZ9893_CHIP_ID:
>> + return true;
>> + default:
>> + /* KSZ8567R Errata DS80000752C Module 4 */
>> + /* KSZ9477S Errata DS80000754A Module 4 */
>> + /* KSZ9567S Errata DS80000756A Module 4 */
>> + /* KSZ9896C Errata DS80000757A Module 3 */
>> + /* KSZ9897R Errata DS80000758C Module 4 */
>
> Sashiko noted that errata:
>
> /* KSZ879x/KSZ877x/KSZ876x Errata DS80000687C Module 2 */
>
> has been lost above.
Yes that was more or less intended because KSZ879x/KSZ877x/KSZ876x don't
belong to the KSZ9477 family. I haven't found a relevant place to move
this comment as .support_eee() is removed from ksz8.c, maybe I should
have mentioned it in the commit log.
>
>> diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
>> index f8f220242f7a..4cbbcf7993c9 100644
>> --- a/drivers/net/dsa/microchip/lan937x_main.c
>> +++ b/drivers/net/dsa/microchip/lan937x_main.c
>> @@ -915,7 +915,6 @@ const struct dsa_switch_ops lan937x_switch_ops = {
>> .port_txtstamp = ksz_port_txtstamp,
>> .port_rxtstamp = ksz_port_rxtstamp,
>> .port_setup_tc = ksz_setup_tc,
>> - .support_eee = ksz_support_eee,
>> .set_mac_eee = ksz_set_mac_eee,
>
> Sashiko noted that `set_mac_eee` usage is gated by `support_eee` presence,
> you may want to remove even the set callback.
>
True, will do.
Best regards,
Bastien
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 6/9] net: dsa: microchip: implement .{get/set}_wol only if needed
2026-06-01 8:59 ` Paolo Abeni
@ 2026-06-02 12:34 ` Bastien Curutchet
0 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet @ 2026-06-02 12:34 UTC (permalink / raw)
To: Paolo Abeni, Woojung Huh, UNGLinuxDriver, Andrew Lunn,
Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
Hi Paolo,
On 6/1/26 10:59 AM, Paolo Abeni wrote:
> On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
>> @@ -3798,9 +3795,6 @@ int ksz_set_wol(struct dsa_switch *ds, int port,
>> if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
>> return -EINVAL;
>>
>> - if (!is_ksz9477(dev) && !ksz_is_ksz87xx(dev))
>> - return -EOPNOTSUPP;
>
> Sashiko noted there is still a ksz_is_ksz87xx(dev) check in
> ksz_wol_pre_shutdown() which would probably keep WoL broken for the
> newly enabled switches.
>
Good catch from Sashiko here. I'm going to replace the is_ksz() checks
in ksz_wol_pre_shutdown() with a if (ds->ops->get_wol &&
ds->ops->set_wol) (as done here in ksz_port_set_mac_address()) to ensure
consistency in the WoL handling.
Best regards,
Bastien
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 7/9] net: dsa: microchip: implement port_hsr_join for KSZ9477 only
2026-06-01 9:03 ` Paolo Abeni
@ 2026-06-02 12:35 ` Bastien Curutchet
2026-06-02 14:06 ` Bastien Curutchet
0 siblings, 1 reply; 19+ messages in thread
From: Bastien Curutchet @ 2026-06-02 12:35 UTC (permalink / raw)
To: Paolo Abeni, Woojung Huh, UNGLinuxDriver, Andrew Lunn,
Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
Hi Paolo,
On 6/1/26 11:03 AM, Paolo Abeni wrote:
> On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
>> @@ -1744,12 +1784,20 @@ void ksz9477_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr)
>> /* Setup HW supported features for lan HSR ports */
>> user = dsa_to_port(ds, port)->user;
>> user->features |= KSZ9477_SUPPORTED_HSR_FEATURES;
>> +
>> + dev->hsr_dev = hsr;
>> + dev->hsr_ports |= BIT(port);
>> +
>> + return 0;
>> }
>>
>> -void ksz9477_hsr_leave(struct dsa_switch *ds, int port, struct net_device *hsr)
>> +static int ksz9477_hsr_leave(struct dsa_switch *ds, int port,
>> + struct net_device *hsr)
>> {
>> struct ksz_device *dev = ds->priv;
>>
>> + WARN_ON(dev->chip_id != KSZ9477_CHIP_ID);
>
> Since the new op is used only by the relevant switch version, I think
> you could/should remove the above warning.
>
Ack, will do.
Best regards,
Bastien
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 7/9] net: dsa: microchip: implement port_hsr_join for KSZ9477 only
2026-06-02 12:35 ` Bastien Curutchet
@ 2026-06-02 14:06 ` Bastien Curutchet
0 siblings, 0 replies; 19+ messages in thread
From: Bastien Curutchet @ 2026-06-02 14:06 UTC (permalink / raw)
To: Paolo Abeni, Woojung Huh, UNGLinuxDriver, Andrew Lunn,
Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
Russell King
Cc: Pascal Eberhard, Miquèl Raynal, Thomas Petazzoni,
Tristram Ha, netdev, linux-kernel
Hi again Paolo,
On 6/2/26 2:35 PM, Bastien Curutchet wrote:
> Hi Paolo,
>
> On 6/1/26 11:03 AM, Paolo Abeni wrote:
>> On 5/26/26 11:47 AM, Bastien Curutchet (Schneider Electric) wrote:
>>> @@ -1744,12 +1784,20 @@ void ksz9477_hsr_join(struct dsa_switch *ds,
>>> int port, struct net_device *hsr)
>>> /* Setup HW supported features for lan HSR ports */
>>> user = dsa_to_port(ds, port)->user;
>>> user->features |= KSZ9477_SUPPORTED_HSR_FEATURES;
>>> +
>>> + dev->hsr_dev = hsr;
>>> + dev->hsr_ports |= BIT(port);
>>> +
>>> + return 0;
>>> }
>>> -void ksz9477_hsr_leave(struct dsa_switch *ds, int port, struct
>>> net_device *hsr)
>>> +static int ksz9477_hsr_leave(struct dsa_switch *ds, int port,
>>> + struct net_device *hsr)
>>> {
>>> struct ksz_device *dev = ds->priv;
>>> + WARN_ON(dev->chip_id != KSZ9477_CHIP_ID);
>>
>> Since the new op is used only by the relevant switch version, I think
>> you could/should remove the above warning.
>>
>
> Ack, will do.
>
I'm having second thoughts now that I'm about to do it.
This HSR feature is only supported by the KSZ9477 itself, not by all the
switches using ksz9477_switch_ops. A check is done against the
KSZ9477_CHIP_ID in ksz9477_hsr_join(). This WARN_ON is kind of symmetric
with the ksz9477_hsr_join()'s check so, IMHO, it makes sense to keep it.
Best regards,
Bastien
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-06-02 14:06 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-26 9:47 [PATCH net-next 0/9] net: dsa: microchip: remove unnecessary dsa_switch_ops callbacks Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 1/9] net: dsa: microchip: remove useless common cls_flower_{add/del} operations Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 2/9] net: dsa: microchip: remove VLAN operations for ksz8463 Bastien Curutchet
2026-05-26 9:47 ` [PATCH net-next 3/9] net: dsa: microchip: implement get_phy_flags only if needed Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 4/9] net: dsa: microchip: remove setup_rgmii_delay() KSZ operation Bastien Curutchet (Schneider Electric)
2026-06-01 8:49 ` Paolo Abeni
2026-06-02 12:15 ` Bastien Curutchet
2026-05-26 9:47 ` [PATCH net-next 5/9] net: dsa: microchip: implement .support_eee() only if needed Bastien Curutchet (Schneider Electric)
2026-06-01 8:55 ` Paolo Abeni
2026-06-02 12:21 ` Bastien Curutchet
2026-05-26 9:47 ` [PATCH net-next 6/9] net: dsa: microchip: implement .{get/set}_wol " Bastien Curutchet (Schneider Electric)
2026-06-01 8:59 ` Paolo Abeni
2026-06-02 12:34 ` Bastien Curutchet
2026-05-26 9:47 ` [PATCH net-next 7/9] net: dsa: microchip: implement port_hsr_join for KSZ9477 only Bastien Curutchet (Schneider Electric)
2026-06-01 9:03 ` Paolo Abeni
2026-06-02 12:35 ` Bastien Curutchet
2026-06-02 14:06 ` Bastien Curutchet
2026-05-26 9:47 ` [PATCH net-next 8/9] net: dsa: microchip: implement lan937x-specific MDIO registration Bastien Curutchet (Schneider Electric)
2026-05-26 9:47 ` [PATCH net-next 9/9] net: dsa: microchip: implement port_teardown only if needed Bastien Curutchet (Schneider Electric)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome