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
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).
11 Allowed port configurations:
14 GMAC0: RGMII, MII, REVMII or RMII port
15 GMAC1: RGMII, MII, REVMII or RMII port
19 GMAC5: GPHY1 (MII) or RGMII port
27 GMAC5: GPHY1 (MII) or RGMII port
30 GMAC0: RGMII, GMII or RMII port
33 GMAC3: GPHY0 (MII) or GPHY3 (GMII)
35 GMAC5: GPHY1 (MII), RGMII or RMII port
37 Tested on D-Link DWR966 (xRX330) with OpenWRT.
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>
43 drivers/net/dsa/lantiq_gswip.c | 142 ++++++++++++++++++++++++++-------
44 1 file changed, 113 insertions(+), 29 deletions(-)
46 --- a/drivers/net/dsa/lantiq_gswip.c
47 +++ b/drivers/net/dsa/lantiq_gswip.c
49 // SPDX-License-Identifier: GPL-2.0
51 - * Lantiq / Intel GSWIP switch driver for VRX200 SoCs
52 + * Lantiq / Intel GSWIP switch driver for VRX200, xRX300 and xRX330 SoCs
54 * Copyright (C) 2010 Lantiq Deutschland
55 * Copyright (C) 2012 John Crispin <john@phrozen.org>
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
65 struct gswip_hw_info {
68 + const struct dsa_switch_ops *ops;
71 struct xway_gphy_match_data {
72 @@ -1438,12 +1440,42 @@ static int gswip_port_fdb_dump(struct ds
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)
82 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
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);
90 + /* With the exclusion of MII, Reverse MII and Reduced MII, we
91 + * support Gigabit, including Half duplex
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);
100 + phylink_set(mask, 10baseT_Half);
101 + phylink_set(mask, 10baseT_Full);
102 + phylink_set(mask, 100baseT_Half);
103 + phylink_set(mask, 100baseT_Full);
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);
111 +static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
112 + unsigned long *supported,
113 + struct phylink_link_state *state)
118 @@ -1470,38 +1502,54 @@ static void gswip_phylink_validate(struc
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);
129 - /* With the exclusion of MII, Reverse MII and Reduced MII, we
130 - * support Gigabit, including Half duplex
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);
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);
145 +static void gswip_xrx300_phylink_validate(struct dsa_switch *ds, int port,
146 + unsigned long *supported,
147 + struct phylink_link_state *state)
151 + if (!phy_interface_mode_is_rgmii(state->interface) &&
152 + state->interface != PHY_INTERFACE_MODE_GMII &&
153 + state->interface != PHY_INTERFACE_MODE_RMII)
160 + if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
164 + if (!phy_interface_mode_is_rgmii(state->interface) &&
165 + state->interface != PHY_INTERFACE_MODE_INTERNAL &&
166 + state->interface != PHY_INTERFACE_MODE_RMII)
170 + bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
171 + dev_err(ds->dev, "Unsupported port: %i\n", port);
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);
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);
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);
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;
199 + case PHY_INTERFACE_MODE_GMII:
200 + miicfg |= GSWIP_MII_CFG_MODE_GMII;
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);
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,
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 @@ -2042,7 +2117,7 @@ static int gswip_probe(struct platform_d
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;
254 version = gswip_switch_r(priv, GSWIP_VERSION);
256 @@ -2126,10 +2201,19 @@ static int gswip_remove(struct platform_
257 static const struct gswip_hw_info gswip_xrx200 = {
260 + .ops = &gswip_xrx200_switch_ops,
263 +static const struct gswip_hw_info gswip_xrx300 = {
266 + .ops = &gswip_xrx300_switch_ops,
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 },
275 MODULE_DEVICE_TABLE(of, gswip_of_match);