7d68c591996d0e992de81d0e6c3bd9268ccf397c
[openwrt/staging/stintel.git] /
1 From a09d042b086202735c4ed64573cdd79933020001 Mon Sep 17 00:00:00 2001
2 From: Aleksander Jan Bajkowski <olek2@wp.pl>
3 Date: Mon, 22 Mar 2021 21:37:15 +0100
4 Subject: [PATCH] net: dsa: lantiq: allow to use all GPHYs on xRX300 and xRX330
5
6 This patch allows to use all PHYs on GRX300 and GRX330. The ARX300
7 has 3 and the GRX330 has 4 integrated PHYs connected to different
8 ports compared to VRX200. Each integrated PHY can work as single
9 Gigabit Ethernet PHY (GMII) or as double Fast Ethernet PHY (MII).
10
11 Allowed port configurations:
12
13 xRX200:
14 GMAC0: RGMII, MII, REVMII or RMII port
15 GMAC1: RGMII, MII, REVMII or RMII port
16 GMAC2: GPHY0 (GMII)
17 GMAC3: GPHY0 (MII)
18 GMAC4: GPHY1 (GMII)
19 GMAC5: GPHY1 (MII) or RGMII port
20
21 xRX300:
22 GMAC0: RGMII port
23 GMAC1: GPHY2 (GMII)
24 GMAC2: GPHY0 (GMII)
25 GMAC3: GPHY0 (MII)
26 GMAC4: GPHY1 (GMII)
27 GMAC5: GPHY1 (MII) or RGMII port
28
29 xRX330:
30 GMAC0: RGMII, GMII or RMII port
31 GMAC1: GPHY2 (GMII)
32 GMAC2: GPHY0 (GMII)
33 GMAC3: GPHY0 (MII) or GPHY3 (GMII)
34 GMAC4: GPHY1 (GMII)
35 GMAC5: GPHY1 (MII), RGMII or RMII port
36
37 Tested on D-Link DWR966 (xRX330) with OpenWRT.
38
39 Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
40 Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
41 Signed-off-by: David S. Miller <davem@davemloft.net>
42 ---
43 drivers/net/dsa/lantiq_gswip.c | 142 ++++++++++++++++++++++++++-------
44 1 file changed, 113 insertions(+), 29 deletions(-)
45
46 --- a/drivers/net/dsa/lantiq_gswip.c
47 +++ b/drivers/net/dsa/lantiq_gswip.c
48 @@ -1,6 +1,6 @@
49 // SPDX-License-Identifier: GPL-2.0
50 /*
51 - * Lantiq / Intel GSWIP switch driver for VRX200 SoCs
52 + * Lantiq / Intel GSWIP switch driver for VRX200, xRX300 and xRX330 SoCs
53 *
54 * Copyright (C) 2010 Lantiq Deutschland
55 * Copyright (C) 2012 John Crispin <john@phrozen.org>
56 @@ -104,6 +104,7 @@
57 #define GSWIP_MII_CFG_MODE_RMIIP 0x2
58 #define GSWIP_MII_CFG_MODE_RMIIM 0x3
59 #define GSWIP_MII_CFG_MODE_RGMII 0x4
60 +#define GSWIP_MII_CFG_MODE_GMII 0x9
61 #define GSWIP_MII_CFG_MODE_MASK 0xf
62 #define GSWIP_MII_CFG_RATE_M2P5 0x00
63 #define GSWIP_MII_CFG_RATE_M25 0x10
64 @@ -241,6 +242,7 @@
65 struct gswip_hw_info {
66 int max_ports;
67 int cpu_port;
68 + const struct dsa_switch_ops *ops;
69 };
70
71 struct xway_gphy_match_data {
72 @@ -1438,12 +1440,42 @@ static int gswip_port_fdb_dump(struct ds
73 return 0;
74 }
75
76 -static void gswip_phylink_validate(struct dsa_switch *ds, int port,
77 - unsigned long *supported,
78 - struct phylink_link_state *state)
79 +static void gswip_phylink_set_capab(unsigned long *supported,
80 + struct phylink_link_state *state)
81 {
82 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
83
84 + /* Allow all the expected bits */
85 + phylink_set(mask, Autoneg);
86 + phylink_set_port_modes(mask);
87 + phylink_set(mask, Pause);
88 + phylink_set(mask, Asym_Pause);
89 +
90 + /* With the exclusion of MII, Reverse MII and Reduced MII, we
91 + * support Gigabit, including Half duplex
92 + */
93 + if (state->interface != PHY_INTERFACE_MODE_MII &&
94 + state->interface != PHY_INTERFACE_MODE_REVMII &&
95 + state->interface != PHY_INTERFACE_MODE_RMII) {
96 + phylink_set(mask, 1000baseT_Full);
97 + phylink_set(mask, 1000baseT_Half);
98 + }
99 +
100 + phylink_set(mask, 10baseT_Half);
101 + phylink_set(mask, 10baseT_Full);
102 + phylink_set(mask, 100baseT_Half);
103 + phylink_set(mask, 100baseT_Full);
104 +
105 + bitmap_and(supported, supported, mask,
106 + __ETHTOOL_LINK_MODE_MASK_NBITS);
107 + bitmap_and(state->advertising, state->advertising, mask,
108 + __ETHTOOL_LINK_MODE_MASK_NBITS);
109 +}
110 +
111 +static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
112 + unsigned long *supported,
113 + struct phylink_link_state *state)
114 +{
115 switch (port) {
116 case 0:
117 case 1:
118 @@ -1470,38 +1502,54 @@ static void gswip_phylink_validate(struc
119 return;
120 }
121
122 - /* Allow all the expected bits */
123 - phylink_set(mask, Autoneg);
124 - phylink_set_port_modes(mask);
125 - phylink_set(mask, Pause);
126 - phylink_set(mask, Asym_Pause);
127 + gswip_phylink_set_capab(supported, state);
128
129 - /* With the exclusion of MII, Reverse MII and Reduced MII, we
130 - * support Gigabit, including Half duplex
131 - */
132 - if (state->interface != PHY_INTERFACE_MODE_MII &&
133 - state->interface != PHY_INTERFACE_MODE_REVMII &&
134 - state->interface != PHY_INTERFACE_MODE_RMII) {
135 - phylink_set(mask, 1000baseT_Full);
136 - phylink_set(mask, 1000baseT_Half);
137 + return;
138 +
139 +unsupported:
140 + bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
141 + dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
142 + phy_modes(state->interface), port);
143 +}
144 +
145 +static void gswip_xrx300_phylink_validate(struct dsa_switch *ds, int port,
146 + unsigned long *supported,
147 + struct phylink_link_state *state)
148 +{
149 + switch (port) {
150 + case 0:
151 + if (!phy_interface_mode_is_rgmii(state->interface) &&
152 + state->interface != PHY_INTERFACE_MODE_GMII &&
153 + state->interface != PHY_INTERFACE_MODE_RMII)
154 + goto unsupported;
155 + break;
156 + case 1:
157 + case 2:
158 + case 3:
159 + case 4:
160 + if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
161 + goto unsupported;
162 + break;
163 + case 5:
164 + if (!phy_interface_mode_is_rgmii(state->interface) &&
165 + state->interface != PHY_INTERFACE_MODE_INTERNAL &&
166 + state->interface != PHY_INTERFACE_MODE_RMII)
167 + goto unsupported;
168 + break;
169 + default:
170 + bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
171 + dev_err(ds->dev, "Unsupported port: %i\n", port);
172 + return;
173 }
174
175 - phylink_set(mask, 10baseT_Half);
176 - phylink_set(mask, 10baseT_Full);
177 - phylink_set(mask, 100baseT_Half);
178 - phylink_set(mask, 100baseT_Full);
179 + gswip_phylink_set_capab(supported, state);
180
181 - bitmap_and(supported, supported, mask,
182 - __ETHTOOL_LINK_MODE_MASK_NBITS);
183 - bitmap_and(state->advertising, state->advertising, mask,
184 - __ETHTOOL_LINK_MODE_MASK_NBITS);
185 return;
186
187 unsupported:
188 bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
189 dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
190 phy_modes(state->interface), port);
191 - return;
192 }
193
194 static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link)
195 @@ -1636,6 +1684,9 @@ static void gswip_phylink_mac_config(str
196 case PHY_INTERFACE_MODE_RGMII_TXID:
197 miicfg |= GSWIP_MII_CFG_MODE_RGMII;
198 break;
199 + case PHY_INTERFACE_MODE_GMII:
200 + miicfg |= GSWIP_MII_CFG_MODE_GMII;
201 + break;
202 default:
203 dev_err(ds->dev,
204 "Unsupported interface: %d\n", state->interface);
205 @@ -1762,7 +1813,7 @@ static int gswip_get_sset_count(struct d
206 return ARRAY_SIZE(gswip_rmon_cnt);
207 }
208
209 -static const struct dsa_switch_ops gswip_switch_ops = {
210 +static const struct dsa_switch_ops gswip_xrx200_switch_ops = {
211 .get_tag_protocol = gswip_get_tag_protocol,
212 .setup = gswip_setup,
213 .port_enable = gswip_port_enable,
214 @@ -1778,7 +1829,31 @@ static const struct dsa_switch_ops gswip
215 .port_fdb_add = gswip_port_fdb_add,
216 .port_fdb_del = gswip_port_fdb_del,
217 .port_fdb_dump = gswip_port_fdb_dump,
218 - .phylink_validate = gswip_phylink_validate,
219 + .phylink_validate = gswip_xrx200_phylink_validate,
220 + .phylink_mac_config = gswip_phylink_mac_config,
221 + .phylink_mac_link_down = gswip_phylink_mac_link_down,
222 + .phylink_mac_link_up = gswip_phylink_mac_link_up,
223 + .get_strings = gswip_get_strings,
224 + .get_ethtool_stats = gswip_get_ethtool_stats,
225 + .get_sset_count = gswip_get_sset_count,
226 +};
227 +
228 +static const struct dsa_switch_ops gswip_xrx300_switch_ops = {
229 + .get_tag_protocol = gswip_get_tag_protocol,
230 + .setup = gswip_setup,
231 + .port_enable = gswip_port_enable,
232 + .port_disable = gswip_port_disable,
233 + .port_bridge_join = gswip_port_bridge_join,
234 + .port_bridge_leave = gswip_port_bridge_leave,
235 + .port_fast_age = gswip_port_fast_age,
236 + .port_vlan_filtering = gswip_port_vlan_filtering,
237 + .port_vlan_add = gswip_port_vlan_add,
238 + .port_vlan_del = gswip_port_vlan_del,
239 + .port_stp_state_set = gswip_port_stp_state_set,
240 + .port_fdb_add = gswip_port_fdb_add,
241 + .port_fdb_del = gswip_port_fdb_del,
242 + .port_fdb_dump = gswip_port_fdb_dump,
243 + .phylink_validate = gswip_xrx300_phylink_validate,
244 .phylink_mac_config = gswip_phylink_mac_config,
245 .phylink_mac_link_down = gswip_phylink_mac_link_down,
246 .phylink_mac_link_up = gswip_phylink_mac_link_up,
247 @@ -2040,7 +2115,7 @@ static int gswip_probe(struct platform_d
248 priv->ds->dev = dev;
249 priv->ds->num_ports = priv->hw_info->max_ports;
250 priv->ds->priv = priv;
251 - priv->ds->ops = &gswip_switch_ops;
252 + priv->ds->ops = priv->hw_info->ops;
253 priv->dev = dev;
254 version = gswip_switch_r(priv, GSWIP_VERSION);
255
256 @@ -2124,10 +2199,19 @@ static int gswip_remove(struct platform_
257 static const struct gswip_hw_info gswip_xrx200 = {
258 .max_ports = 7,
259 .cpu_port = 6,
260 + .ops = &gswip_xrx200_switch_ops,
261 +};
262 +
263 +static const struct gswip_hw_info gswip_xrx300 = {
264 + .max_ports = 7,
265 + .cpu_port = 6,
266 + .ops = &gswip_xrx300_switch_ops,
267 };
268
269 static const struct of_device_id gswip_of_match[] = {
270 { .compatible = "lantiq,xrx200-gswip", .data = &gswip_xrx200 },
271 + { .compatible = "lantiq,xrx300-gswip", .data = &gswip_xrx300 },
272 + { .compatible = "lantiq,xrx330-gswip", .data = &gswip_xrx300 },
273 {},
274 };
275 MODULE_DEVICE_TABLE(of, gswip_of_match);