7c9ab16d4af989b2b9f3d15fa44651d736e79dbe
[openwrt/staging/wigyori.git] /
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
5 phylink mac ops
6
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.
13
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>
19 ---
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(-)
24
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;
29
30 /*
31 + * Allow a DSA switch driver to override the phylink MAC ops
32 + */
33 + const struct phylink_mac_ops *phylink_mac_ops;
34 +
35 + /*
36 * Slave mii_bus and devices for the individual ports.
37 */
38 u32 phys_mii_mask;
39 --- a/net/dsa/dsa.c
40 +++ b/net/dsa/dsa.c
41 @@ -1510,6 +1510,17 @@ static int dsa_switch_probe(struct dsa_s
42 if (!ds->num_ports)
43 return -EINVAL;
44
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)
53 + return -EINVAL;
54 + }
55 +
56 if (np) {
57 err = dsa_switch_parse_of(ds, np);
58 if (err)
59 --- a/net/dsa/port.c
60 +++ b/net/dsa/port.c
61 @@ -1677,6 +1677,7 @@ static const struct phylink_mac_ops dsa_
62
63 int dsa_port_phylink_create(struct dsa_port *dp)
64 {
65 + const struct phylink_mac_ops *mac_ops;
66 struct dsa_switch *ds = dp->ds;
67 phy_interface_t mode;
68 struct phylink *pl;
69 @@ -1700,8 +1701,12 @@ int dsa_port_phylink_create(struct dsa_p
70 }
71 }
72
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;
78 +
79 + pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
80 + mac_ops);
81 if (IS_ERR(pl)) {
82 pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
83 return 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);
86 }
87
88 +static void dsa_shared_port_link_down(struct dsa_port *dp)
89 +{
90 + struct dsa_switch *ds = dp->ds;
91 +
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);
98 +}
99 +
100 int dsa_shared_port_link_register_of(struct dsa_port *dp)
101 {
102 struct dsa_switch *ds = dp->ds;
103 bool missing_link_description;
104 bool missing_phy_mode;
105 - int port = dp->index;
106
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);
112 } else {
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);
117
118 return dsa_shared_port_phylink_register(dp);
119 }