1 From c22d8240fcd73a1c3ec8dcb055bd583fb970c375 Mon Sep 17 00:00:00 2001
2 From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
3 Date: Wed, 10 Apr 2024 20:42:43 +0100
4 Subject: [PATCH 2/2] net: dsa: allow DSA switch drivers to provide their own
7 Rather than having a shim for each and every phylink MAC operation,
8 allow DSA switch drivers to provide their own ops structure. When a
9 DSA driver provides the phylink MAC operations, the shimmed ops must
10 not be provided, so fail an attempt to register a switch with both
11 the phylink_mac_ops in struct dsa_switch and the phylink_mac_*
12 operations populated in dsa_switch_ops populated.
14 Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
15 Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
16 Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
17 Link: https://lore.kernel.org/r/E1rudqF-006K9H-Cc@rmk-PC.armlinux.org.uk
18 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
20 include/net/dsa.h | 5 +++++
21 net/dsa/dsa.c | 11 +++++++++++
22 net/dsa/port.c | 26 ++++++++++++++++++++------
23 3 files changed, 36 insertions(+), 6 deletions(-)
25 --- a/include/net/dsa.h
26 +++ b/include/net/dsa.h
27 @@ -458,6 +458,11 @@ struct dsa_switch {
28 const struct dsa_switch_ops *ops;
31 + * Allow a DSA switch driver to override the phylink MAC ops
33 + const struct phylink_mac_ops *phylink_mac_ops;
36 * Slave mii_bus and devices for the individual ports.
41 @@ -1510,6 +1510,17 @@ static int dsa_switch_probe(struct dsa_s
45 + if (ds->phylink_mac_ops) {
46 + if (ds->ops->phylink_mac_select_pcs ||
47 + ds->ops->phylink_mac_prepare ||
48 + ds->ops->phylink_mac_config ||
49 + ds->ops->phylink_mac_finish ||
50 + ds->ops->phylink_mac_link_down ||
51 + ds->ops->phylink_mac_link_up ||
52 + ds->ops->adjust_link)
57 err = dsa_switch_parse_of(ds, np);
61 @@ -1677,6 +1677,7 @@ static const struct phylink_mac_ops dsa_
63 int dsa_port_phylink_create(struct dsa_port *dp)
65 + const struct phylink_mac_ops *mac_ops;
66 struct dsa_switch *ds = dp->ds;
69 @@ -1700,8 +1701,12 @@ int dsa_port_phylink_create(struct dsa_p
73 - pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
74 - mode, &dsa_port_phylink_mac_ops);
75 + mac_ops = &dsa_port_phylink_mac_ops;
76 + if (ds->phylink_mac_ops)
77 + mac_ops = ds->phylink_mac_ops;
79 + pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
82 pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
84 @@ -1967,12 +1972,23 @@ static void dsa_shared_port_validate_of(
85 dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
88 +static void dsa_shared_port_link_down(struct dsa_port *dp)
90 + struct dsa_switch *ds = dp->ds;
92 + if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
93 + ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
94 + PHY_INTERFACE_MODE_NA);
95 + else if (ds->ops->phylink_mac_link_down)
96 + ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
97 + PHY_INTERFACE_MODE_NA);
100 int dsa_shared_port_link_register_of(struct dsa_port *dp)
102 struct dsa_switch *ds = dp->ds;
103 bool missing_link_description;
104 bool missing_phy_mode;
105 - int port = dp->index;
107 dsa_shared_port_validate_of(dp, &missing_phy_mode,
108 &missing_link_description);
109 @@ -1988,9 +2004,7 @@ int dsa_shared_port_link_register_of(str
110 "Skipping phylink registration for %s port %d\n",
111 dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
113 - if (ds->ops->phylink_mac_link_down)
114 - ds->ops->phylink_mac_link_down(ds, port,
115 - MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
116 + dsa_shared_port_link_down(dp);
118 return dsa_shared_port_phylink_register(dp);