xref: /linux/drivers/net/dsa/lantiq/lantiq_gswip.c (revision cb477c30512db29325c0503ba96a6158a61b7e7c)
1*cb477c30SDaniel Golle // SPDX-License-Identifier: GPL-2.0
2*cb477c30SDaniel Golle /*
3*cb477c30SDaniel Golle  * Lantiq / Intel GSWIP switch driver for VRX200, xRX300 and xRX330 SoCs
4*cb477c30SDaniel Golle  *
5*cb477c30SDaniel Golle  * Copyright (C) 2010 Lantiq Deutschland
6*cb477c30SDaniel Golle  * Copyright (C) 2012 John Crispin <john@phrozen.org>
7*cb477c30SDaniel Golle  * Copyright (C) 2017 - 2019 Hauke Mehrtens <hauke@hauke-m.de>
8*cb477c30SDaniel Golle  *
9*cb477c30SDaniel Golle  * The VLAN and bridge model the GSWIP hardware uses does not directly
10*cb477c30SDaniel Golle  * matches the model DSA uses.
11*cb477c30SDaniel Golle  *
12*cb477c30SDaniel Golle  * The hardware has 64 possible table entries for bridges with one VLAN
13*cb477c30SDaniel Golle  * ID, one flow id and a list of ports for each bridge. All entries which
14*cb477c30SDaniel Golle  * match the same flow ID are combined in the mac learning table, they
15*cb477c30SDaniel Golle  * act as one global bridge.
16*cb477c30SDaniel Golle  * The hardware does not support VLAN filter on the port, but on the
17*cb477c30SDaniel Golle  * bridge, this driver converts the DSA model to the hardware.
18*cb477c30SDaniel Golle  *
19*cb477c30SDaniel Golle  * The CPU gets all the exception frames which do not match any forwarding
20*cb477c30SDaniel Golle  * rule and the CPU port is also added to all bridges. This makes it possible
21*cb477c30SDaniel Golle  * to handle all the special cases easily in software.
22*cb477c30SDaniel Golle  * At the initialization the driver allocates one bridge table entry for
23*cb477c30SDaniel Golle  * each switch port which is used when the port is used without an
24*cb477c30SDaniel Golle  * explicit bridge. This prevents the frames from being forwarded
25*cb477c30SDaniel Golle  * between all LAN ports by default.
26*cb477c30SDaniel Golle  */
27*cb477c30SDaniel Golle 
28*cb477c30SDaniel Golle #include "lantiq_gswip.h"
29*cb477c30SDaniel Golle #include "lantiq_pce.h"
30*cb477c30SDaniel Golle 
31*cb477c30SDaniel Golle #include <linux/delay.h>
32*cb477c30SDaniel Golle #include <linux/etherdevice.h>
33*cb477c30SDaniel Golle #include <linux/firmware.h>
34*cb477c30SDaniel Golle #include <linux/if_bridge.h>
35*cb477c30SDaniel Golle #include <linux/if_vlan.h>
36*cb477c30SDaniel Golle #include <linux/iopoll.h>
37*cb477c30SDaniel Golle #include <linux/mfd/syscon.h>
38*cb477c30SDaniel Golle #include <linux/module.h>
39*cb477c30SDaniel Golle #include <linux/of_mdio.h>
40*cb477c30SDaniel Golle #include <linux/of_net.h>
41*cb477c30SDaniel Golle #include <linux/of_platform.h>
42*cb477c30SDaniel Golle #include <linux/phy.h>
43*cb477c30SDaniel Golle #include <linux/phylink.h>
44*cb477c30SDaniel Golle #include <dt-bindings/mips/lantiq_rcu_gphy.h>
45*cb477c30SDaniel Golle 
46*cb477c30SDaniel Golle struct xway_gphy_match_data {
47*cb477c30SDaniel Golle 	char *fe_firmware_name;
48*cb477c30SDaniel Golle 	char *ge_firmware_name;
49*cb477c30SDaniel Golle };
50*cb477c30SDaniel Golle 
51*cb477c30SDaniel Golle struct gswip_pce_table_entry {
52*cb477c30SDaniel Golle 	u16 index;      // PCE_TBL_ADDR.ADDR = pData->table_index
53*cb477c30SDaniel Golle 	u16 table;      // PCE_TBL_CTRL.ADDR = pData->table
54*cb477c30SDaniel Golle 	u16 key[8];
55*cb477c30SDaniel Golle 	u16 val[5];
56*cb477c30SDaniel Golle 	u16 mask;
57*cb477c30SDaniel Golle 	u8 gmap;
58*cb477c30SDaniel Golle 	bool type;
59*cb477c30SDaniel Golle 	bool valid;
60*cb477c30SDaniel Golle 	bool key_mode;
61*cb477c30SDaniel Golle };
62*cb477c30SDaniel Golle 
63*cb477c30SDaniel Golle struct gswip_rmon_cnt_desc {
64*cb477c30SDaniel Golle 	unsigned int size;
65*cb477c30SDaniel Golle 	unsigned int offset;
66*cb477c30SDaniel Golle 	const char *name;
67*cb477c30SDaniel Golle };
68*cb477c30SDaniel Golle 
69*cb477c30SDaniel Golle #define MIB_DESC(_size, _offset, _name) {.size = _size, .offset = _offset, .name = _name}
70*cb477c30SDaniel Golle 
71*cb477c30SDaniel Golle static const struct gswip_rmon_cnt_desc gswip_rmon_cnt[] = {
72*cb477c30SDaniel Golle 	/** Receive Packet Count (only packets that are accepted and not discarded). */
73*cb477c30SDaniel Golle 	MIB_DESC(1, 0x1F, "RxGoodPkts"),
74*cb477c30SDaniel Golle 	MIB_DESC(1, 0x23, "RxUnicastPkts"),
75*cb477c30SDaniel Golle 	MIB_DESC(1, 0x22, "RxMulticastPkts"),
76*cb477c30SDaniel Golle 	MIB_DESC(1, 0x21, "RxFCSErrorPkts"),
77*cb477c30SDaniel Golle 	MIB_DESC(1, 0x1D, "RxUnderSizeGoodPkts"),
78*cb477c30SDaniel Golle 	MIB_DESC(1, 0x1E, "RxUnderSizeErrorPkts"),
79*cb477c30SDaniel Golle 	MIB_DESC(1, 0x1B, "RxOversizeGoodPkts"),
80*cb477c30SDaniel Golle 	MIB_DESC(1, 0x1C, "RxOversizeErrorPkts"),
81*cb477c30SDaniel Golle 	MIB_DESC(1, 0x20, "RxGoodPausePkts"),
82*cb477c30SDaniel Golle 	MIB_DESC(1, 0x1A, "RxAlignErrorPkts"),
83*cb477c30SDaniel Golle 	MIB_DESC(1, 0x12, "Rx64BytePkts"),
84*cb477c30SDaniel Golle 	MIB_DESC(1, 0x13, "Rx127BytePkts"),
85*cb477c30SDaniel Golle 	MIB_DESC(1, 0x14, "Rx255BytePkts"),
86*cb477c30SDaniel Golle 	MIB_DESC(1, 0x15, "Rx511BytePkts"),
87*cb477c30SDaniel Golle 	MIB_DESC(1, 0x16, "Rx1023BytePkts"),
88*cb477c30SDaniel Golle 	/** Receive Size 1024-1522 (or more, if configured) Packet Count. */
89*cb477c30SDaniel Golle 	MIB_DESC(1, 0x17, "RxMaxBytePkts"),
90*cb477c30SDaniel Golle 	MIB_DESC(1, 0x18, "RxDroppedPkts"),
91*cb477c30SDaniel Golle 	MIB_DESC(1, 0x19, "RxFilteredPkts"),
92*cb477c30SDaniel Golle 	MIB_DESC(2, 0x24, "RxGoodBytes"),
93*cb477c30SDaniel Golle 	MIB_DESC(2, 0x26, "RxBadBytes"),
94*cb477c30SDaniel Golle 	MIB_DESC(1, 0x11, "TxAcmDroppedPkts"),
95*cb477c30SDaniel Golle 	MIB_DESC(1, 0x0C, "TxGoodPkts"),
96*cb477c30SDaniel Golle 	MIB_DESC(1, 0x06, "TxUnicastPkts"),
97*cb477c30SDaniel Golle 	MIB_DESC(1, 0x07, "TxMulticastPkts"),
98*cb477c30SDaniel Golle 	MIB_DESC(1, 0x00, "Tx64BytePkts"),
99*cb477c30SDaniel Golle 	MIB_DESC(1, 0x01, "Tx127BytePkts"),
100*cb477c30SDaniel Golle 	MIB_DESC(1, 0x02, "Tx255BytePkts"),
101*cb477c30SDaniel Golle 	MIB_DESC(1, 0x03, "Tx511BytePkts"),
102*cb477c30SDaniel Golle 	MIB_DESC(1, 0x04, "Tx1023BytePkts"),
103*cb477c30SDaniel Golle 	/** Transmit Size 1024-1522 (or more, if configured) Packet Count. */
104*cb477c30SDaniel Golle 	MIB_DESC(1, 0x05, "TxMaxBytePkts"),
105*cb477c30SDaniel Golle 	MIB_DESC(1, 0x08, "TxSingleCollCount"),
106*cb477c30SDaniel Golle 	MIB_DESC(1, 0x09, "TxMultCollCount"),
107*cb477c30SDaniel Golle 	MIB_DESC(1, 0x0A, "TxLateCollCount"),
108*cb477c30SDaniel Golle 	MIB_DESC(1, 0x0B, "TxExcessCollCount"),
109*cb477c30SDaniel Golle 	MIB_DESC(1, 0x0D, "TxPauseCount"),
110*cb477c30SDaniel Golle 	MIB_DESC(1, 0x10, "TxDroppedPkts"),
111*cb477c30SDaniel Golle 	MIB_DESC(2, 0x0E, "TxGoodBytes"),
112*cb477c30SDaniel Golle };
113*cb477c30SDaniel Golle 
114*cb477c30SDaniel Golle static u32 gswip_switch_r(struct gswip_priv *priv, u32 offset)
115*cb477c30SDaniel Golle {
116*cb477c30SDaniel Golle 	return __raw_readl(priv->gswip + (offset * 4));
117*cb477c30SDaniel Golle }
118*cb477c30SDaniel Golle 
119*cb477c30SDaniel Golle static void gswip_switch_w(struct gswip_priv *priv, u32 val, u32 offset)
120*cb477c30SDaniel Golle {
121*cb477c30SDaniel Golle 	__raw_writel(val, priv->gswip + (offset * 4));
122*cb477c30SDaniel Golle }
123*cb477c30SDaniel Golle 
124*cb477c30SDaniel Golle static void gswip_switch_mask(struct gswip_priv *priv, u32 clear, u32 set,
125*cb477c30SDaniel Golle 			      u32 offset)
126*cb477c30SDaniel Golle {
127*cb477c30SDaniel Golle 	u32 val = gswip_switch_r(priv, offset);
128*cb477c30SDaniel Golle 
129*cb477c30SDaniel Golle 	val &= ~(clear);
130*cb477c30SDaniel Golle 	val |= set;
131*cb477c30SDaniel Golle 	gswip_switch_w(priv, val, offset);
132*cb477c30SDaniel Golle }
133*cb477c30SDaniel Golle 
134*cb477c30SDaniel Golle static u32 gswip_switch_r_timeout(struct gswip_priv *priv, u32 offset,
135*cb477c30SDaniel Golle 				  u32 cleared)
136*cb477c30SDaniel Golle {
137*cb477c30SDaniel Golle 	u32 val;
138*cb477c30SDaniel Golle 
139*cb477c30SDaniel Golle 	return readx_poll_timeout(__raw_readl, priv->gswip + (offset * 4), val,
140*cb477c30SDaniel Golle 				  (val & cleared) == 0, 20, 50000);
141*cb477c30SDaniel Golle }
142*cb477c30SDaniel Golle 
143*cb477c30SDaniel Golle static u32 gswip_mdio_r(struct gswip_priv *priv, u32 offset)
144*cb477c30SDaniel Golle {
145*cb477c30SDaniel Golle 	return __raw_readl(priv->mdio + (offset * 4));
146*cb477c30SDaniel Golle }
147*cb477c30SDaniel Golle 
148*cb477c30SDaniel Golle static void gswip_mdio_w(struct gswip_priv *priv, u32 val, u32 offset)
149*cb477c30SDaniel Golle {
150*cb477c30SDaniel Golle 	__raw_writel(val, priv->mdio + (offset * 4));
151*cb477c30SDaniel Golle }
152*cb477c30SDaniel Golle 
153*cb477c30SDaniel Golle static void gswip_mdio_mask(struct gswip_priv *priv, u32 clear, u32 set,
154*cb477c30SDaniel Golle 			    u32 offset)
155*cb477c30SDaniel Golle {
156*cb477c30SDaniel Golle 	u32 val = gswip_mdio_r(priv, offset);
157*cb477c30SDaniel Golle 
158*cb477c30SDaniel Golle 	val &= ~(clear);
159*cb477c30SDaniel Golle 	val |= set;
160*cb477c30SDaniel Golle 	gswip_mdio_w(priv, val, offset);
161*cb477c30SDaniel Golle }
162*cb477c30SDaniel Golle 
163*cb477c30SDaniel Golle static u32 gswip_mii_r(struct gswip_priv *priv, u32 offset)
164*cb477c30SDaniel Golle {
165*cb477c30SDaniel Golle 	return __raw_readl(priv->mii + (offset * 4));
166*cb477c30SDaniel Golle }
167*cb477c30SDaniel Golle 
168*cb477c30SDaniel Golle static void gswip_mii_w(struct gswip_priv *priv, u32 val, u32 offset)
169*cb477c30SDaniel Golle {
170*cb477c30SDaniel Golle 	__raw_writel(val, priv->mii + (offset * 4));
171*cb477c30SDaniel Golle }
172*cb477c30SDaniel Golle 
173*cb477c30SDaniel Golle static void gswip_mii_mask(struct gswip_priv *priv, u32 clear, u32 set,
174*cb477c30SDaniel Golle 			   u32 offset)
175*cb477c30SDaniel Golle {
176*cb477c30SDaniel Golle 	u32 val = gswip_mii_r(priv, offset);
177*cb477c30SDaniel Golle 
178*cb477c30SDaniel Golle 	val &= ~(clear);
179*cb477c30SDaniel Golle 	val |= set;
180*cb477c30SDaniel Golle 	gswip_mii_w(priv, val, offset);
181*cb477c30SDaniel Golle }
182*cb477c30SDaniel Golle 
183*cb477c30SDaniel Golle static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set,
184*cb477c30SDaniel Golle 			       int port)
185*cb477c30SDaniel Golle {
186*cb477c30SDaniel Golle 	/* MII_CFG register only exists for MII ports */
187*cb477c30SDaniel Golle 	if (!(priv->hw_info->mii_ports & BIT(port)))
188*cb477c30SDaniel Golle 		return;
189*cb477c30SDaniel Golle 
190*cb477c30SDaniel Golle 	gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port));
191*cb477c30SDaniel Golle }
192*cb477c30SDaniel Golle 
193*cb477c30SDaniel Golle static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set,
194*cb477c30SDaniel Golle 				int port)
195*cb477c30SDaniel Golle {
196*cb477c30SDaniel Golle 	/* MII_PCDU register only exists for MII ports */
197*cb477c30SDaniel Golle 	if (!(priv->hw_info->mii_ports & BIT(port)))
198*cb477c30SDaniel Golle 		return;
199*cb477c30SDaniel Golle 
200*cb477c30SDaniel Golle 	switch (port) {
201*cb477c30SDaniel Golle 	case 0:
202*cb477c30SDaniel Golle 		gswip_mii_mask(priv, clear, set, GSWIP_MII_PCDU0);
203*cb477c30SDaniel Golle 		break;
204*cb477c30SDaniel Golle 	case 1:
205*cb477c30SDaniel Golle 		gswip_mii_mask(priv, clear, set, GSWIP_MII_PCDU1);
206*cb477c30SDaniel Golle 		break;
207*cb477c30SDaniel Golle 	case 5:
208*cb477c30SDaniel Golle 		gswip_mii_mask(priv, clear, set, GSWIP_MII_PCDU5);
209*cb477c30SDaniel Golle 		break;
210*cb477c30SDaniel Golle 	}
211*cb477c30SDaniel Golle }
212*cb477c30SDaniel Golle 
213*cb477c30SDaniel Golle static int gswip_mdio_poll(struct gswip_priv *priv)
214*cb477c30SDaniel Golle {
215*cb477c30SDaniel Golle 	int cnt = 100;
216*cb477c30SDaniel Golle 
217*cb477c30SDaniel Golle 	while (likely(cnt--)) {
218*cb477c30SDaniel Golle 		u32 ctrl = gswip_mdio_r(priv, GSWIP_MDIO_CTRL);
219*cb477c30SDaniel Golle 
220*cb477c30SDaniel Golle 		if ((ctrl & GSWIP_MDIO_CTRL_BUSY) == 0)
221*cb477c30SDaniel Golle 			return 0;
222*cb477c30SDaniel Golle 		usleep_range(20, 40);
223*cb477c30SDaniel Golle 	}
224*cb477c30SDaniel Golle 
225*cb477c30SDaniel Golle 	return -ETIMEDOUT;
226*cb477c30SDaniel Golle }
227*cb477c30SDaniel Golle 
228*cb477c30SDaniel Golle static int gswip_mdio_wr(struct mii_bus *bus, int addr, int reg, u16 val)
229*cb477c30SDaniel Golle {
230*cb477c30SDaniel Golle 	struct gswip_priv *priv = bus->priv;
231*cb477c30SDaniel Golle 	int err;
232*cb477c30SDaniel Golle 
233*cb477c30SDaniel Golle 	err = gswip_mdio_poll(priv);
234*cb477c30SDaniel Golle 	if (err) {
235*cb477c30SDaniel Golle 		dev_err(&bus->dev, "waiting for MDIO bus busy timed out\n");
236*cb477c30SDaniel Golle 		return err;
237*cb477c30SDaniel Golle 	}
238*cb477c30SDaniel Golle 
239*cb477c30SDaniel Golle 	gswip_mdio_w(priv, val, GSWIP_MDIO_WRITE);
240*cb477c30SDaniel Golle 	gswip_mdio_w(priv, GSWIP_MDIO_CTRL_BUSY | GSWIP_MDIO_CTRL_WR |
241*cb477c30SDaniel Golle 		((addr & GSWIP_MDIO_CTRL_PHYAD_MASK) << GSWIP_MDIO_CTRL_PHYAD_SHIFT) |
242*cb477c30SDaniel Golle 		(reg & GSWIP_MDIO_CTRL_REGAD_MASK),
243*cb477c30SDaniel Golle 		GSWIP_MDIO_CTRL);
244*cb477c30SDaniel Golle 
245*cb477c30SDaniel Golle 	return 0;
246*cb477c30SDaniel Golle }
247*cb477c30SDaniel Golle 
248*cb477c30SDaniel Golle static int gswip_mdio_rd(struct mii_bus *bus, int addr, int reg)
249*cb477c30SDaniel Golle {
250*cb477c30SDaniel Golle 	struct gswip_priv *priv = bus->priv;
251*cb477c30SDaniel Golle 	int err;
252*cb477c30SDaniel Golle 
253*cb477c30SDaniel Golle 	err = gswip_mdio_poll(priv);
254*cb477c30SDaniel Golle 	if (err) {
255*cb477c30SDaniel Golle 		dev_err(&bus->dev, "waiting for MDIO bus busy timed out\n");
256*cb477c30SDaniel Golle 		return err;
257*cb477c30SDaniel Golle 	}
258*cb477c30SDaniel Golle 
259*cb477c30SDaniel Golle 	gswip_mdio_w(priv, GSWIP_MDIO_CTRL_BUSY | GSWIP_MDIO_CTRL_RD |
260*cb477c30SDaniel Golle 		((addr & GSWIP_MDIO_CTRL_PHYAD_MASK) << GSWIP_MDIO_CTRL_PHYAD_SHIFT) |
261*cb477c30SDaniel Golle 		(reg & GSWIP_MDIO_CTRL_REGAD_MASK),
262*cb477c30SDaniel Golle 		GSWIP_MDIO_CTRL);
263*cb477c30SDaniel Golle 
264*cb477c30SDaniel Golle 	err = gswip_mdio_poll(priv);
265*cb477c30SDaniel Golle 	if (err) {
266*cb477c30SDaniel Golle 		dev_err(&bus->dev, "waiting for MDIO bus busy timed out\n");
267*cb477c30SDaniel Golle 		return err;
268*cb477c30SDaniel Golle 	}
269*cb477c30SDaniel Golle 
270*cb477c30SDaniel Golle 	return gswip_mdio_r(priv, GSWIP_MDIO_READ);
271*cb477c30SDaniel Golle }
272*cb477c30SDaniel Golle 
273*cb477c30SDaniel Golle static int gswip_mdio(struct gswip_priv *priv)
274*cb477c30SDaniel Golle {
275*cb477c30SDaniel Golle 	struct device_node *mdio_np, *switch_np = priv->dev->of_node;
276*cb477c30SDaniel Golle 	struct device *dev = priv->dev;
277*cb477c30SDaniel Golle 	struct mii_bus *bus;
278*cb477c30SDaniel Golle 	int err = 0;
279*cb477c30SDaniel Golle 
280*cb477c30SDaniel Golle 	mdio_np = of_get_compatible_child(switch_np, "lantiq,xrx200-mdio");
281*cb477c30SDaniel Golle 	if (!of_device_is_available(mdio_np))
282*cb477c30SDaniel Golle 		goto out_put_node;
283*cb477c30SDaniel Golle 
284*cb477c30SDaniel Golle 	bus = devm_mdiobus_alloc(dev);
285*cb477c30SDaniel Golle 	if (!bus) {
286*cb477c30SDaniel Golle 		err = -ENOMEM;
287*cb477c30SDaniel Golle 		goto out_put_node;
288*cb477c30SDaniel Golle 	}
289*cb477c30SDaniel Golle 
290*cb477c30SDaniel Golle 	bus->priv = priv;
291*cb477c30SDaniel Golle 	bus->read = gswip_mdio_rd;
292*cb477c30SDaniel Golle 	bus->write = gswip_mdio_wr;
293*cb477c30SDaniel Golle 	bus->name = "lantiq,xrx200-mdio";
294*cb477c30SDaniel Golle 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(priv->dev));
295*cb477c30SDaniel Golle 	bus->parent = priv->dev;
296*cb477c30SDaniel Golle 
297*cb477c30SDaniel Golle 	err = devm_of_mdiobus_register(dev, bus, mdio_np);
298*cb477c30SDaniel Golle 
299*cb477c30SDaniel Golle out_put_node:
300*cb477c30SDaniel Golle 	of_node_put(mdio_np);
301*cb477c30SDaniel Golle 
302*cb477c30SDaniel Golle 	return err;
303*cb477c30SDaniel Golle }
304*cb477c30SDaniel Golle 
305*cb477c30SDaniel Golle static int gswip_pce_table_entry_read(struct gswip_priv *priv,
306*cb477c30SDaniel Golle 				      struct gswip_pce_table_entry *tbl)
307*cb477c30SDaniel Golle {
308*cb477c30SDaniel Golle 	int i;
309*cb477c30SDaniel Golle 	int err;
310*cb477c30SDaniel Golle 	u16 crtl;
311*cb477c30SDaniel Golle 	u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSRD :
312*cb477c30SDaniel Golle 					GSWIP_PCE_TBL_CTRL_OPMOD_ADRD;
313*cb477c30SDaniel Golle 
314*cb477c30SDaniel Golle 	mutex_lock(&priv->pce_table_lock);
315*cb477c30SDaniel Golle 
316*cb477c30SDaniel Golle 	err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
317*cb477c30SDaniel Golle 				     GSWIP_PCE_TBL_CTRL_BAS);
318*cb477c30SDaniel Golle 	if (err) {
319*cb477c30SDaniel Golle 		mutex_unlock(&priv->pce_table_lock);
320*cb477c30SDaniel Golle 		return err;
321*cb477c30SDaniel Golle 	}
322*cb477c30SDaniel Golle 
323*cb477c30SDaniel Golle 	gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR);
324*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK |
325*cb477c30SDaniel Golle 				GSWIP_PCE_TBL_CTRL_OPMOD_MASK,
326*cb477c30SDaniel Golle 			  tbl->table | addr_mode | GSWIP_PCE_TBL_CTRL_BAS,
327*cb477c30SDaniel Golle 			  GSWIP_PCE_TBL_CTRL);
328*cb477c30SDaniel Golle 
329*cb477c30SDaniel Golle 	err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
330*cb477c30SDaniel Golle 				     GSWIP_PCE_TBL_CTRL_BAS);
331*cb477c30SDaniel Golle 	if (err) {
332*cb477c30SDaniel Golle 		mutex_unlock(&priv->pce_table_lock);
333*cb477c30SDaniel Golle 		return err;
334*cb477c30SDaniel Golle 	}
335*cb477c30SDaniel Golle 
336*cb477c30SDaniel Golle 	for (i = 0; i < ARRAY_SIZE(tbl->key); i++)
337*cb477c30SDaniel Golle 		tbl->key[i] = gswip_switch_r(priv, GSWIP_PCE_TBL_KEY(i));
338*cb477c30SDaniel Golle 
339*cb477c30SDaniel Golle 	for (i = 0; i < ARRAY_SIZE(tbl->val); i++)
340*cb477c30SDaniel Golle 		tbl->val[i] = gswip_switch_r(priv, GSWIP_PCE_TBL_VAL(i));
341*cb477c30SDaniel Golle 
342*cb477c30SDaniel Golle 	tbl->mask = gswip_switch_r(priv, GSWIP_PCE_TBL_MASK);
343*cb477c30SDaniel Golle 
344*cb477c30SDaniel Golle 	crtl = gswip_switch_r(priv, GSWIP_PCE_TBL_CTRL);
345*cb477c30SDaniel Golle 
346*cb477c30SDaniel Golle 	tbl->type = !!(crtl & GSWIP_PCE_TBL_CTRL_TYPE);
347*cb477c30SDaniel Golle 	tbl->valid = !!(crtl & GSWIP_PCE_TBL_CTRL_VLD);
348*cb477c30SDaniel Golle 	tbl->gmap = (crtl & GSWIP_PCE_TBL_CTRL_GMAP_MASK) >> 7;
349*cb477c30SDaniel Golle 
350*cb477c30SDaniel Golle 	mutex_unlock(&priv->pce_table_lock);
351*cb477c30SDaniel Golle 
352*cb477c30SDaniel Golle 	return 0;
353*cb477c30SDaniel Golle }
354*cb477c30SDaniel Golle 
355*cb477c30SDaniel Golle static int gswip_pce_table_entry_write(struct gswip_priv *priv,
356*cb477c30SDaniel Golle 				       struct gswip_pce_table_entry *tbl)
357*cb477c30SDaniel Golle {
358*cb477c30SDaniel Golle 	int i;
359*cb477c30SDaniel Golle 	int err;
360*cb477c30SDaniel Golle 	u16 crtl;
361*cb477c30SDaniel Golle 	u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSWR :
362*cb477c30SDaniel Golle 					GSWIP_PCE_TBL_CTRL_OPMOD_ADWR;
363*cb477c30SDaniel Golle 
364*cb477c30SDaniel Golle 	mutex_lock(&priv->pce_table_lock);
365*cb477c30SDaniel Golle 
366*cb477c30SDaniel Golle 	err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
367*cb477c30SDaniel Golle 				     GSWIP_PCE_TBL_CTRL_BAS);
368*cb477c30SDaniel Golle 	if (err) {
369*cb477c30SDaniel Golle 		mutex_unlock(&priv->pce_table_lock);
370*cb477c30SDaniel Golle 		return err;
371*cb477c30SDaniel Golle 	}
372*cb477c30SDaniel Golle 
373*cb477c30SDaniel Golle 	gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR);
374*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK |
375*cb477c30SDaniel Golle 				GSWIP_PCE_TBL_CTRL_OPMOD_MASK,
376*cb477c30SDaniel Golle 			  tbl->table | addr_mode,
377*cb477c30SDaniel Golle 			  GSWIP_PCE_TBL_CTRL);
378*cb477c30SDaniel Golle 
379*cb477c30SDaniel Golle 	for (i = 0; i < ARRAY_SIZE(tbl->key); i++)
380*cb477c30SDaniel Golle 		gswip_switch_w(priv, tbl->key[i], GSWIP_PCE_TBL_KEY(i));
381*cb477c30SDaniel Golle 
382*cb477c30SDaniel Golle 	for (i = 0; i < ARRAY_SIZE(tbl->val); i++)
383*cb477c30SDaniel Golle 		gswip_switch_w(priv, tbl->val[i], GSWIP_PCE_TBL_VAL(i));
384*cb477c30SDaniel Golle 
385*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK |
386*cb477c30SDaniel Golle 				GSWIP_PCE_TBL_CTRL_OPMOD_MASK,
387*cb477c30SDaniel Golle 			  tbl->table | addr_mode,
388*cb477c30SDaniel Golle 			  GSWIP_PCE_TBL_CTRL);
389*cb477c30SDaniel Golle 
390*cb477c30SDaniel Golle 	gswip_switch_w(priv, tbl->mask, GSWIP_PCE_TBL_MASK);
391*cb477c30SDaniel Golle 
392*cb477c30SDaniel Golle 	crtl = gswip_switch_r(priv, GSWIP_PCE_TBL_CTRL);
393*cb477c30SDaniel Golle 	crtl &= ~(GSWIP_PCE_TBL_CTRL_TYPE | GSWIP_PCE_TBL_CTRL_VLD |
394*cb477c30SDaniel Golle 		  GSWIP_PCE_TBL_CTRL_GMAP_MASK);
395*cb477c30SDaniel Golle 	if (tbl->type)
396*cb477c30SDaniel Golle 		crtl |= GSWIP_PCE_TBL_CTRL_TYPE;
397*cb477c30SDaniel Golle 	if (tbl->valid)
398*cb477c30SDaniel Golle 		crtl |= GSWIP_PCE_TBL_CTRL_VLD;
399*cb477c30SDaniel Golle 	crtl |= (tbl->gmap << 7) & GSWIP_PCE_TBL_CTRL_GMAP_MASK;
400*cb477c30SDaniel Golle 	crtl |= GSWIP_PCE_TBL_CTRL_BAS;
401*cb477c30SDaniel Golle 	gswip_switch_w(priv, crtl, GSWIP_PCE_TBL_CTRL);
402*cb477c30SDaniel Golle 
403*cb477c30SDaniel Golle 	err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
404*cb477c30SDaniel Golle 				     GSWIP_PCE_TBL_CTRL_BAS);
405*cb477c30SDaniel Golle 
406*cb477c30SDaniel Golle 	mutex_unlock(&priv->pce_table_lock);
407*cb477c30SDaniel Golle 
408*cb477c30SDaniel Golle 	return err;
409*cb477c30SDaniel Golle }
410*cb477c30SDaniel Golle 
411*cb477c30SDaniel Golle /* Add the LAN port into a bridge with the CPU port by
412*cb477c30SDaniel Golle  * default. This prevents automatic forwarding of
413*cb477c30SDaniel Golle  * packages between the LAN ports when no explicit
414*cb477c30SDaniel Golle  * bridge is configured.
415*cb477c30SDaniel Golle  */
416*cb477c30SDaniel Golle static int gswip_add_single_port_br(struct gswip_priv *priv, int port, bool add)
417*cb477c30SDaniel Golle {
418*cb477c30SDaniel Golle 	struct gswip_pce_table_entry vlan_active = {0,};
419*cb477c30SDaniel Golle 	struct gswip_pce_table_entry vlan_mapping = {0,};
420*cb477c30SDaniel Golle 	int err;
421*cb477c30SDaniel Golle 
422*cb477c30SDaniel Golle 	vlan_active.index = port + 1;
423*cb477c30SDaniel Golle 	vlan_active.table = GSWIP_TABLE_ACTIVE_VLAN;
424*cb477c30SDaniel Golle 	vlan_active.key[0] = 0; /* vid */
425*cb477c30SDaniel Golle 	vlan_active.val[0] = port + 1 /* fid */;
426*cb477c30SDaniel Golle 	vlan_active.valid = add;
427*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_write(priv, &vlan_active);
428*cb477c30SDaniel Golle 	if (err) {
429*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to write active VLAN: %d\n", err);
430*cb477c30SDaniel Golle 		return err;
431*cb477c30SDaniel Golle 	}
432*cb477c30SDaniel Golle 
433*cb477c30SDaniel Golle 	if (!add)
434*cb477c30SDaniel Golle 		return 0;
435*cb477c30SDaniel Golle 
436*cb477c30SDaniel Golle 	vlan_mapping.index = port + 1;
437*cb477c30SDaniel Golle 	vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING;
438*cb477c30SDaniel Golle 	vlan_mapping.val[0] = 0 /* vid */;
439*cb477c30SDaniel Golle 	vlan_mapping.val[1] = BIT(port) | dsa_cpu_ports(priv->ds);
440*cb477c30SDaniel Golle 	vlan_mapping.val[2] = 0;
441*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_write(priv, &vlan_mapping);
442*cb477c30SDaniel Golle 	if (err) {
443*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err);
444*cb477c30SDaniel Golle 		return err;
445*cb477c30SDaniel Golle 	}
446*cb477c30SDaniel Golle 
447*cb477c30SDaniel Golle 	return 0;
448*cb477c30SDaniel Golle }
449*cb477c30SDaniel Golle 
450*cb477c30SDaniel Golle static int gswip_port_enable(struct dsa_switch *ds, int port,
451*cb477c30SDaniel Golle 			     struct phy_device *phydev)
452*cb477c30SDaniel Golle {
453*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
454*cb477c30SDaniel Golle 	int err;
455*cb477c30SDaniel Golle 
456*cb477c30SDaniel Golle 	if (!dsa_is_cpu_port(ds, port)) {
457*cb477c30SDaniel Golle 		u32 mdio_phy = 0;
458*cb477c30SDaniel Golle 
459*cb477c30SDaniel Golle 		err = gswip_add_single_port_br(priv, port, true);
460*cb477c30SDaniel Golle 		if (err)
461*cb477c30SDaniel Golle 			return err;
462*cb477c30SDaniel Golle 
463*cb477c30SDaniel Golle 		if (phydev)
464*cb477c30SDaniel Golle 			mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
465*cb477c30SDaniel Golle 
466*cb477c30SDaniel Golle 		gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
467*cb477c30SDaniel Golle 				GSWIP_MDIO_PHYp(port));
468*cb477c30SDaniel Golle 	}
469*cb477c30SDaniel Golle 
470*cb477c30SDaniel Golle 	/* RMON Counter Enable for port */
471*cb477c30SDaniel Golle 	gswip_switch_w(priv, GSWIP_BM_PCFG_CNTEN, GSWIP_BM_PCFGp(port));
472*cb477c30SDaniel Golle 
473*cb477c30SDaniel Golle 	/* enable port fetch/store dma & VLAN Modification */
474*cb477c30SDaniel Golle 	gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_EN |
475*cb477c30SDaniel Golle 				   GSWIP_FDMA_PCTRL_VLANMOD_BOTH,
476*cb477c30SDaniel Golle 			 GSWIP_FDMA_PCTRLp(port));
477*cb477c30SDaniel Golle 	gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN,
478*cb477c30SDaniel Golle 			  GSWIP_SDMA_PCTRLp(port));
479*cb477c30SDaniel Golle 
480*cb477c30SDaniel Golle 	return 0;
481*cb477c30SDaniel Golle }
482*cb477c30SDaniel Golle 
483*cb477c30SDaniel Golle static void gswip_port_disable(struct dsa_switch *ds, int port)
484*cb477c30SDaniel Golle {
485*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
486*cb477c30SDaniel Golle 
487*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_FDMA_PCTRL_EN, 0,
488*cb477c30SDaniel Golle 			  GSWIP_FDMA_PCTRLp(port));
489*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_SDMA_PCTRL_EN, 0,
490*cb477c30SDaniel Golle 			  GSWIP_SDMA_PCTRLp(port));
491*cb477c30SDaniel Golle }
492*cb477c30SDaniel Golle 
493*cb477c30SDaniel Golle static int gswip_pce_load_microcode(struct gswip_priv *priv)
494*cb477c30SDaniel Golle {
495*cb477c30SDaniel Golle 	int i;
496*cb477c30SDaniel Golle 	int err;
497*cb477c30SDaniel Golle 
498*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK |
499*cb477c30SDaniel Golle 				GSWIP_PCE_TBL_CTRL_OPMOD_MASK,
500*cb477c30SDaniel Golle 			  GSWIP_PCE_TBL_CTRL_OPMOD_ADWR, GSWIP_PCE_TBL_CTRL);
501*cb477c30SDaniel Golle 	gswip_switch_w(priv, 0, GSWIP_PCE_TBL_MASK);
502*cb477c30SDaniel Golle 
503*cb477c30SDaniel Golle 	for (i = 0; i < priv->hw_info->pce_microcode_size; i++) {
504*cb477c30SDaniel Golle 		gswip_switch_w(priv, i, GSWIP_PCE_TBL_ADDR);
505*cb477c30SDaniel Golle 		gswip_switch_w(priv, (*priv->hw_info->pce_microcode)[i].val_0,
506*cb477c30SDaniel Golle 			       GSWIP_PCE_TBL_VAL(0));
507*cb477c30SDaniel Golle 		gswip_switch_w(priv, (*priv->hw_info->pce_microcode)[i].val_1,
508*cb477c30SDaniel Golle 			       GSWIP_PCE_TBL_VAL(1));
509*cb477c30SDaniel Golle 		gswip_switch_w(priv, (*priv->hw_info->pce_microcode)[i].val_2,
510*cb477c30SDaniel Golle 			       GSWIP_PCE_TBL_VAL(2));
511*cb477c30SDaniel Golle 		gswip_switch_w(priv, (*priv->hw_info->pce_microcode)[i].val_3,
512*cb477c30SDaniel Golle 			       GSWIP_PCE_TBL_VAL(3));
513*cb477c30SDaniel Golle 
514*cb477c30SDaniel Golle 		/* start the table access: */
515*cb477c30SDaniel Golle 		gswip_switch_mask(priv, 0, GSWIP_PCE_TBL_CTRL_BAS,
516*cb477c30SDaniel Golle 				  GSWIP_PCE_TBL_CTRL);
517*cb477c30SDaniel Golle 		err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
518*cb477c30SDaniel Golle 					     GSWIP_PCE_TBL_CTRL_BAS);
519*cb477c30SDaniel Golle 		if (err)
520*cb477c30SDaniel Golle 			return err;
521*cb477c30SDaniel Golle 	}
522*cb477c30SDaniel Golle 
523*cb477c30SDaniel Golle 	/* tell the switch that the microcode is loaded */
524*cb477c30SDaniel Golle 	gswip_switch_mask(priv, 0, GSWIP_PCE_GCTRL_0_MC_VALID,
525*cb477c30SDaniel Golle 			  GSWIP_PCE_GCTRL_0);
526*cb477c30SDaniel Golle 
527*cb477c30SDaniel Golle 	return 0;
528*cb477c30SDaniel Golle }
529*cb477c30SDaniel Golle 
530*cb477c30SDaniel Golle static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port,
531*cb477c30SDaniel Golle 				     bool vlan_filtering,
532*cb477c30SDaniel Golle 				     struct netlink_ext_ack *extack)
533*cb477c30SDaniel Golle {
534*cb477c30SDaniel Golle 	struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port));
535*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
536*cb477c30SDaniel Golle 
537*cb477c30SDaniel Golle 	/* Do not allow changing the VLAN filtering options while in bridge */
538*cb477c30SDaniel Golle 	if (bridge && !!(priv->port_vlan_filter & BIT(port)) != vlan_filtering) {
539*cb477c30SDaniel Golle 		NL_SET_ERR_MSG_MOD(extack,
540*cb477c30SDaniel Golle 				   "Dynamic toggling of vlan_filtering not supported");
541*cb477c30SDaniel Golle 		return -EIO;
542*cb477c30SDaniel Golle 	}
543*cb477c30SDaniel Golle 
544*cb477c30SDaniel Golle 	if (vlan_filtering) {
545*cb477c30SDaniel Golle 		/* Use tag based VLAN */
546*cb477c30SDaniel Golle 		gswip_switch_mask(priv,
547*cb477c30SDaniel Golle 				  GSWIP_PCE_VCTRL_VSR,
548*cb477c30SDaniel Golle 				  GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
549*cb477c30SDaniel Golle 				  GSWIP_PCE_VCTRL_VEMR,
550*cb477c30SDaniel Golle 				  GSWIP_PCE_VCTRL(port));
551*cb477c30SDaniel Golle 		gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0,
552*cb477c30SDaniel Golle 				  GSWIP_PCE_PCTRL_0p(port));
553*cb477c30SDaniel Golle 	} else {
554*cb477c30SDaniel Golle 		/* Use port based VLAN */
555*cb477c30SDaniel Golle 		gswip_switch_mask(priv,
556*cb477c30SDaniel Golle 				  GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
557*cb477c30SDaniel Golle 				  GSWIP_PCE_VCTRL_VEMR,
558*cb477c30SDaniel Golle 				  GSWIP_PCE_VCTRL_VSR,
559*cb477c30SDaniel Golle 				  GSWIP_PCE_VCTRL(port));
560*cb477c30SDaniel Golle 		gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_TVM,
561*cb477c30SDaniel Golle 				  GSWIP_PCE_PCTRL_0p(port));
562*cb477c30SDaniel Golle 	}
563*cb477c30SDaniel Golle 
564*cb477c30SDaniel Golle 	return 0;
565*cb477c30SDaniel Golle }
566*cb477c30SDaniel Golle 
567*cb477c30SDaniel Golle static int gswip_setup(struct dsa_switch *ds)
568*cb477c30SDaniel Golle {
569*cb477c30SDaniel Golle 	unsigned int cpu_ports = dsa_cpu_ports(ds);
570*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
571*cb477c30SDaniel Golle 	struct dsa_port *cpu_dp;
572*cb477c30SDaniel Golle 	int err, i;
573*cb477c30SDaniel Golle 
574*cb477c30SDaniel Golle 	gswip_switch_w(priv, GSWIP_SWRES_R0, GSWIP_SWRES);
575*cb477c30SDaniel Golle 	usleep_range(5000, 10000);
576*cb477c30SDaniel Golle 	gswip_switch_w(priv, 0, GSWIP_SWRES);
577*cb477c30SDaniel Golle 
578*cb477c30SDaniel Golle 	/* disable port fetch/store dma on all ports */
579*cb477c30SDaniel Golle 	for (i = 0; i < priv->hw_info->max_ports; i++) {
580*cb477c30SDaniel Golle 		gswip_port_disable(ds, i);
581*cb477c30SDaniel Golle 		gswip_port_vlan_filtering(ds, i, false, NULL);
582*cb477c30SDaniel Golle 	}
583*cb477c30SDaniel Golle 
584*cb477c30SDaniel Golle 	/* enable Switch */
585*cb477c30SDaniel Golle 	gswip_mdio_mask(priv, 0, GSWIP_MDIO_GLOB_ENABLE, GSWIP_MDIO_GLOB);
586*cb477c30SDaniel Golle 
587*cb477c30SDaniel Golle 	err = gswip_pce_load_microcode(priv);
588*cb477c30SDaniel Golle 	if (err) {
589*cb477c30SDaniel Golle 		dev_err(priv->dev, "writing PCE microcode failed, %i\n", err);
590*cb477c30SDaniel Golle 		return err;
591*cb477c30SDaniel Golle 	}
592*cb477c30SDaniel Golle 
593*cb477c30SDaniel Golle 	/* Default unknown Broadcast/Multicast/Unicast port maps */
594*cb477c30SDaniel Golle 	gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP1);
595*cb477c30SDaniel Golle 	gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP2);
596*cb477c30SDaniel Golle 	gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP3);
597*cb477c30SDaniel Golle 
598*cb477c30SDaniel Golle 	/* Deactivate MDIO PHY auto polling. Some PHYs as the AR8030 have an
599*cb477c30SDaniel Golle 	 * interoperability problem with this auto polling mechanism because
600*cb477c30SDaniel Golle 	 * their status registers think that the link is in a different state
601*cb477c30SDaniel Golle 	 * than it actually is. For the AR8030 it has the BMSR_ESTATEN bit set
602*cb477c30SDaniel Golle 	 * as well as ESTATUS_1000_TFULL and ESTATUS_1000_XFULL. This makes the
603*cb477c30SDaniel Golle 	 * auto polling state machine consider the link being negotiated with
604*cb477c30SDaniel Golle 	 * 1Gbit/s. Since the PHY itself is a Fast Ethernet RMII PHY this leads
605*cb477c30SDaniel Golle 	 * to the switch port being completely dead (RX and TX are both not
606*cb477c30SDaniel Golle 	 * working).
607*cb477c30SDaniel Golle 	 * Also with various other PHY / port combinations (PHY11G GPHY, PHY22F
608*cb477c30SDaniel Golle 	 * GPHY, external RGMII PEF7071/7072) any traffic would stop. Sometimes
609*cb477c30SDaniel Golle 	 * it would work fine for a few minutes to hours and then stop, on
610*cb477c30SDaniel Golle 	 * other device it would no traffic could be sent or received at all.
611*cb477c30SDaniel Golle 	 * Testing shows that when PHY auto polling is disabled these problems
612*cb477c30SDaniel Golle 	 * go away.
613*cb477c30SDaniel Golle 	 */
614*cb477c30SDaniel Golle 	gswip_mdio_w(priv, 0x0, GSWIP_MDIO_MDC_CFG0);
615*cb477c30SDaniel Golle 
616*cb477c30SDaniel Golle 	/* Configure the MDIO Clock 2.5 MHz */
617*cb477c30SDaniel Golle 	gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1);
618*cb477c30SDaniel Golle 
619*cb477c30SDaniel Golle 	/* Disable the xMII interface and clear it's isolation bit */
620*cb477c30SDaniel Golle 	for (i = 0; i < priv->hw_info->max_ports; i++)
621*cb477c30SDaniel Golle 		gswip_mii_mask_cfg(priv,
622*cb477c30SDaniel Golle 				   GSWIP_MII_CFG_EN | GSWIP_MII_CFG_ISOLATE,
623*cb477c30SDaniel Golle 				   0, i);
624*cb477c30SDaniel Golle 
625*cb477c30SDaniel Golle 	dsa_switch_for_each_cpu_port(cpu_dp, ds) {
626*cb477c30SDaniel Golle 		/* enable special tag insertion on cpu port */
627*cb477c30SDaniel Golle 		gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN,
628*cb477c30SDaniel Golle 				  GSWIP_FDMA_PCTRLp(cpu_dp->index));
629*cb477c30SDaniel Golle 
630*cb477c30SDaniel Golle 		/* accept special tag in ingress direction */
631*cb477c30SDaniel Golle 		gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
632*cb477c30SDaniel Golle 				  GSWIP_PCE_PCTRL_0p(cpu_dp->index));
633*cb477c30SDaniel Golle 	}
634*cb477c30SDaniel Golle 
635*cb477c30SDaniel Golle 	gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD,
636*cb477c30SDaniel Golle 			  GSWIP_BM_QUEUE_GCTRL);
637*cb477c30SDaniel Golle 
638*cb477c30SDaniel Golle 	/* VLAN aware Switching */
639*cb477c30SDaniel Golle 	gswip_switch_mask(priv, 0, GSWIP_PCE_GCTRL_0_VLAN, GSWIP_PCE_GCTRL_0);
640*cb477c30SDaniel Golle 
641*cb477c30SDaniel Golle 	/* Flush MAC Table */
642*cb477c30SDaniel Golle 	gswip_switch_mask(priv, 0, GSWIP_PCE_GCTRL_0_MTFL, GSWIP_PCE_GCTRL_0);
643*cb477c30SDaniel Golle 
644*cb477c30SDaniel Golle 	err = gswip_switch_r_timeout(priv, GSWIP_PCE_GCTRL_0,
645*cb477c30SDaniel Golle 				     GSWIP_PCE_GCTRL_0_MTFL);
646*cb477c30SDaniel Golle 	if (err) {
647*cb477c30SDaniel Golle 		dev_err(priv->dev, "MAC flushing didn't finish\n");
648*cb477c30SDaniel Golle 		return err;
649*cb477c30SDaniel Golle 	}
650*cb477c30SDaniel Golle 
651*cb477c30SDaniel Golle 	ds->mtu_enforcement_ingress = true;
652*cb477c30SDaniel Golle 
653*cb477c30SDaniel Golle 	ds->configure_vlan_while_not_filtering = false;
654*cb477c30SDaniel Golle 
655*cb477c30SDaniel Golle 	return 0;
656*cb477c30SDaniel Golle }
657*cb477c30SDaniel Golle 
658*cb477c30SDaniel Golle static enum dsa_tag_protocol gswip_get_tag_protocol(struct dsa_switch *ds,
659*cb477c30SDaniel Golle 						    int port,
660*cb477c30SDaniel Golle 						    enum dsa_tag_protocol mp)
661*cb477c30SDaniel Golle {
662*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
663*cb477c30SDaniel Golle 
664*cb477c30SDaniel Golle 	return priv->hw_info->tag_protocol;
665*cb477c30SDaniel Golle }
666*cb477c30SDaniel Golle 
667*cb477c30SDaniel Golle static int gswip_vlan_active_create(struct gswip_priv *priv,
668*cb477c30SDaniel Golle 				    struct net_device *bridge,
669*cb477c30SDaniel Golle 				    int fid, u16 vid)
670*cb477c30SDaniel Golle {
671*cb477c30SDaniel Golle 	struct gswip_pce_table_entry vlan_active = {0,};
672*cb477c30SDaniel Golle 	unsigned int max_ports = priv->hw_info->max_ports;
673*cb477c30SDaniel Golle 	int idx = -1;
674*cb477c30SDaniel Golle 	int err;
675*cb477c30SDaniel Golle 	int i;
676*cb477c30SDaniel Golle 
677*cb477c30SDaniel Golle 	/* Look for a free slot */
678*cb477c30SDaniel Golle 	for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) {
679*cb477c30SDaniel Golle 		if (!priv->vlans[i].bridge) {
680*cb477c30SDaniel Golle 			idx = i;
681*cb477c30SDaniel Golle 			break;
682*cb477c30SDaniel Golle 		}
683*cb477c30SDaniel Golle 	}
684*cb477c30SDaniel Golle 
685*cb477c30SDaniel Golle 	if (idx == -1)
686*cb477c30SDaniel Golle 		return -ENOSPC;
687*cb477c30SDaniel Golle 
688*cb477c30SDaniel Golle 	if (fid == -1)
689*cb477c30SDaniel Golle 		fid = idx;
690*cb477c30SDaniel Golle 
691*cb477c30SDaniel Golle 	vlan_active.index = idx;
692*cb477c30SDaniel Golle 	vlan_active.table = GSWIP_TABLE_ACTIVE_VLAN;
693*cb477c30SDaniel Golle 	vlan_active.key[0] = vid;
694*cb477c30SDaniel Golle 	vlan_active.val[0] = fid;
695*cb477c30SDaniel Golle 	vlan_active.valid = true;
696*cb477c30SDaniel Golle 
697*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_write(priv, &vlan_active);
698*cb477c30SDaniel Golle 	if (err) {
699*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to write active VLAN: %d\n",	err);
700*cb477c30SDaniel Golle 		return err;
701*cb477c30SDaniel Golle 	}
702*cb477c30SDaniel Golle 
703*cb477c30SDaniel Golle 	priv->vlans[idx].bridge = bridge;
704*cb477c30SDaniel Golle 	priv->vlans[idx].vid = vid;
705*cb477c30SDaniel Golle 	priv->vlans[idx].fid = fid;
706*cb477c30SDaniel Golle 
707*cb477c30SDaniel Golle 	return idx;
708*cb477c30SDaniel Golle }
709*cb477c30SDaniel Golle 
710*cb477c30SDaniel Golle static int gswip_vlan_active_remove(struct gswip_priv *priv, int idx)
711*cb477c30SDaniel Golle {
712*cb477c30SDaniel Golle 	struct gswip_pce_table_entry vlan_active = {0,};
713*cb477c30SDaniel Golle 	int err;
714*cb477c30SDaniel Golle 
715*cb477c30SDaniel Golle 	vlan_active.index = idx;
716*cb477c30SDaniel Golle 	vlan_active.table = GSWIP_TABLE_ACTIVE_VLAN;
717*cb477c30SDaniel Golle 	vlan_active.valid = false;
718*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_write(priv, &vlan_active);
719*cb477c30SDaniel Golle 	if (err)
720*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to delete active VLAN: %d\n", err);
721*cb477c30SDaniel Golle 	priv->vlans[idx].bridge = NULL;
722*cb477c30SDaniel Golle 
723*cb477c30SDaniel Golle 	return err;
724*cb477c30SDaniel Golle }
725*cb477c30SDaniel Golle 
726*cb477c30SDaniel Golle static int gswip_vlan_add_unaware(struct gswip_priv *priv,
727*cb477c30SDaniel Golle 				  struct net_device *bridge, int port)
728*cb477c30SDaniel Golle {
729*cb477c30SDaniel Golle 	struct gswip_pce_table_entry vlan_mapping = {0,};
730*cb477c30SDaniel Golle 	unsigned int max_ports = priv->hw_info->max_ports;
731*cb477c30SDaniel Golle 	bool active_vlan_created = false;
732*cb477c30SDaniel Golle 	int idx = -1;
733*cb477c30SDaniel Golle 	int i;
734*cb477c30SDaniel Golle 	int err;
735*cb477c30SDaniel Golle 
736*cb477c30SDaniel Golle 	/* Check if there is already a page for this bridge */
737*cb477c30SDaniel Golle 	for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) {
738*cb477c30SDaniel Golle 		if (priv->vlans[i].bridge == bridge) {
739*cb477c30SDaniel Golle 			idx = i;
740*cb477c30SDaniel Golle 			break;
741*cb477c30SDaniel Golle 		}
742*cb477c30SDaniel Golle 	}
743*cb477c30SDaniel Golle 
744*cb477c30SDaniel Golle 	/* If this bridge is not programmed yet, add a Active VLAN table
745*cb477c30SDaniel Golle 	 * entry in a free slot and prepare the VLAN mapping table entry.
746*cb477c30SDaniel Golle 	 */
747*cb477c30SDaniel Golle 	if (idx == -1) {
748*cb477c30SDaniel Golle 		idx = gswip_vlan_active_create(priv, bridge, -1, 0);
749*cb477c30SDaniel Golle 		if (idx < 0)
750*cb477c30SDaniel Golle 			return idx;
751*cb477c30SDaniel Golle 		active_vlan_created = true;
752*cb477c30SDaniel Golle 
753*cb477c30SDaniel Golle 		vlan_mapping.index = idx;
754*cb477c30SDaniel Golle 		vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING;
755*cb477c30SDaniel Golle 		/* VLAN ID byte, maps to the VLAN ID of vlan active table */
756*cb477c30SDaniel Golle 		vlan_mapping.val[0] = 0;
757*cb477c30SDaniel Golle 	} else {
758*cb477c30SDaniel Golle 		/* Read the existing VLAN mapping entry from the switch */
759*cb477c30SDaniel Golle 		vlan_mapping.index = idx;
760*cb477c30SDaniel Golle 		vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING;
761*cb477c30SDaniel Golle 		err = gswip_pce_table_entry_read(priv, &vlan_mapping);
762*cb477c30SDaniel Golle 		if (err) {
763*cb477c30SDaniel Golle 			dev_err(priv->dev, "failed to read VLAN mapping: %d\n",
764*cb477c30SDaniel Golle 				err);
765*cb477c30SDaniel Golle 			return err;
766*cb477c30SDaniel Golle 		}
767*cb477c30SDaniel Golle 	}
768*cb477c30SDaniel Golle 
769*cb477c30SDaniel Golle 	/* Update the VLAN mapping entry and write it to the switch */
770*cb477c30SDaniel Golle 	vlan_mapping.val[1] |= dsa_cpu_ports(priv->ds);
771*cb477c30SDaniel Golle 	vlan_mapping.val[1] |= BIT(port);
772*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_write(priv, &vlan_mapping);
773*cb477c30SDaniel Golle 	if (err) {
774*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err);
775*cb477c30SDaniel Golle 		/* In case an Active VLAN was creaetd delete it again */
776*cb477c30SDaniel Golle 		if (active_vlan_created)
777*cb477c30SDaniel Golle 			gswip_vlan_active_remove(priv, idx);
778*cb477c30SDaniel Golle 		return err;
779*cb477c30SDaniel Golle 	}
780*cb477c30SDaniel Golle 
781*cb477c30SDaniel Golle 	gswip_switch_w(priv, 0, GSWIP_PCE_DEFPVID(port));
782*cb477c30SDaniel Golle 	return 0;
783*cb477c30SDaniel Golle }
784*cb477c30SDaniel Golle 
785*cb477c30SDaniel Golle static int gswip_vlan_add_aware(struct gswip_priv *priv,
786*cb477c30SDaniel Golle 				struct net_device *bridge, int port,
787*cb477c30SDaniel Golle 				u16 vid, bool untagged,
788*cb477c30SDaniel Golle 				bool pvid)
789*cb477c30SDaniel Golle {
790*cb477c30SDaniel Golle 	struct gswip_pce_table_entry vlan_mapping = {0,};
791*cb477c30SDaniel Golle 	unsigned int max_ports = priv->hw_info->max_ports;
792*cb477c30SDaniel Golle 	unsigned int cpu_ports = dsa_cpu_ports(priv->ds);
793*cb477c30SDaniel Golle 	bool active_vlan_created = false;
794*cb477c30SDaniel Golle 	int idx = -1;
795*cb477c30SDaniel Golle 	int fid = -1;
796*cb477c30SDaniel Golle 	int i;
797*cb477c30SDaniel Golle 	int err;
798*cb477c30SDaniel Golle 
799*cb477c30SDaniel Golle 	/* Check if there is already a page for this bridge */
800*cb477c30SDaniel Golle 	for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) {
801*cb477c30SDaniel Golle 		if (priv->vlans[i].bridge == bridge) {
802*cb477c30SDaniel Golle 			if (fid != -1 && fid != priv->vlans[i].fid)
803*cb477c30SDaniel Golle 				dev_err(priv->dev, "one bridge with multiple flow ids\n");
804*cb477c30SDaniel Golle 			fid = priv->vlans[i].fid;
805*cb477c30SDaniel Golle 			if (priv->vlans[i].vid == vid) {
806*cb477c30SDaniel Golle 				idx = i;
807*cb477c30SDaniel Golle 				break;
808*cb477c30SDaniel Golle 			}
809*cb477c30SDaniel Golle 		}
810*cb477c30SDaniel Golle 	}
811*cb477c30SDaniel Golle 
812*cb477c30SDaniel Golle 	/* If this bridge is not programmed yet, add a Active VLAN table
813*cb477c30SDaniel Golle 	 * entry in a free slot and prepare the VLAN mapping table entry.
814*cb477c30SDaniel Golle 	 */
815*cb477c30SDaniel Golle 	if (idx == -1) {
816*cb477c30SDaniel Golle 		idx = gswip_vlan_active_create(priv, bridge, fid, vid);
817*cb477c30SDaniel Golle 		if (idx < 0)
818*cb477c30SDaniel Golle 			return idx;
819*cb477c30SDaniel Golle 		active_vlan_created = true;
820*cb477c30SDaniel Golle 
821*cb477c30SDaniel Golle 		vlan_mapping.index = idx;
822*cb477c30SDaniel Golle 		vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING;
823*cb477c30SDaniel Golle 		/* VLAN ID byte, maps to the VLAN ID of vlan active table */
824*cb477c30SDaniel Golle 		vlan_mapping.val[0] = vid;
825*cb477c30SDaniel Golle 	} else {
826*cb477c30SDaniel Golle 		/* Read the existing VLAN mapping entry from the switch */
827*cb477c30SDaniel Golle 		vlan_mapping.index = idx;
828*cb477c30SDaniel Golle 		vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING;
829*cb477c30SDaniel Golle 		err = gswip_pce_table_entry_read(priv, &vlan_mapping);
830*cb477c30SDaniel Golle 		if (err) {
831*cb477c30SDaniel Golle 			dev_err(priv->dev, "failed to read VLAN mapping: %d\n",
832*cb477c30SDaniel Golle 				err);
833*cb477c30SDaniel Golle 			return err;
834*cb477c30SDaniel Golle 		}
835*cb477c30SDaniel Golle 	}
836*cb477c30SDaniel Golle 
837*cb477c30SDaniel Golle 	vlan_mapping.val[0] = vid;
838*cb477c30SDaniel Golle 	/* Update the VLAN mapping entry and write it to the switch */
839*cb477c30SDaniel Golle 	vlan_mapping.val[1] |= cpu_ports;
840*cb477c30SDaniel Golle 	vlan_mapping.val[2] |= cpu_ports;
841*cb477c30SDaniel Golle 	vlan_mapping.val[1] |= BIT(port);
842*cb477c30SDaniel Golle 	if (untagged)
843*cb477c30SDaniel Golle 		vlan_mapping.val[2] &= ~BIT(port);
844*cb477c30SDaniel Golle 	else
845*cb477c30SDaniel Golle 		vlan_mapping.val[2] |= BIT(port);
846*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_write(priv, &vlan_mapping);
847*cb477c30SDaniel Golle 	if (err) {
848*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err);
849*cb477c30SDaniel Golle 		/* In case an Active VLAN was creaetd delete it again */
850*cb477c30SDaniel Golle 		if (active_vlan_created)
851*cb477c30SDaniel Golle 			gswip_vlan_active_remove(priv, idx);
852*cb477c30SDaniel Golle 		return err;
853*cb477c30SDaniel Golle 	}
854*cb477c30SDaniel Golle 
855*cb477c30SDaniel Golle 	if (pvid)
856*cb477c30SDaniel Golle 		gswip_switch_w(priv, idx, GSWIP_PCE_DEFPVID(port));
857*cb477c30SDaniel Golle 
858*cb477c30SDaniel Golle 	return 0;
859*cb477c30SDaniel Golle }
860*cb477c30SDaniel Golle 
861*cb477c30SDaniel Golle static int gswip_vlan_remove(struct gswip_priv *priv,
862*cb477c30SDaniel Golle 			     struct net_device *bridge, int port,
863*cb477c30SDaniel Golle 			     u16 vid, bool pvid, bool vlan_aware)
864*cb477c30SDaniel Golle {
865*cb477c30SDaniel Golle 	struct gswip_pce_table_entry vlan_mapping = {0,};
866*cb477c30SDaniel Golle 	unsigned int max_ports = priv->hw_info->max_ports;
867*cb477c30SDaniel Golle 	int idx = -1;
868*cb477c30SDaniel Golle 	int i;
869*cb477c30SDaniel Golle 	int err;
870*cb477c30SDaniel Golle 
871*cb477c30SDaniel Golle 	/* Check if there is already a page for this bridge */
872*cb477c30SDaniel Golle 	for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) {
873*cb477c30SDaniel Golle 		if (priv->vlans[i].bridge == bridge &&
874*cb477c30SDaniel Golle 		    (!vlan_aware || priv->vlans[i].vid == vid)) {
875*cb477c30SDaniel Golle 			idx = i;
876*cb477c30SDaniel Golle 			break;
877*cb477c30SDaniel Golle 		}
878*cb477c30SDaniel Golle 	}
879*cb477c30SDaniel Golle 
880*cb477c30SDaniel Golle 	if (idx == -1) {
881*cb477c30SDaniel Golle 		dev_err(priv->dev, "bridge to leave does not exists\n");
882*cb477c30SDaniel Golle 		return -ENOENT;
883*cb477c30SDaniel Golle 	}
884*cb477c30SDaniel Golle 
885*cb477c30SDaniel Golle 	vlan_mapping.index = idx;
886*cb477c30SDaniel Golle 	vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING;
887*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_read(priv, &vlan_mapping);
888*cb477c30SDaniel Golle 	if (err) {
889*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to read VLAN mapping: %d\n",	err);
890*cb477c30SDaniel Golle 		return err;
891*cb477c30SDaniel Golle 	}
892*cb477c30SDaniel Golle 
893*cb477c30SDaniel Golle 	vlan_mapping.val[1] &= ~BIT(port);
894*cb477c30SDaniel Golle 	vlan_mapping.val[2] &= ~BIT(port);
895*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_write(priv, &vlan_mapping);
896*cb477c30SDaniel Golle 	if (err) {
897*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to write VLAN mapping: %d\n", err);
898*cb477c30SDaniel Golle 		return err;
899*cb477c30SDaniel Golle 	}
900*cb477c30SDaniel Golle 
901*cb477c30SDaniel Golle 	/* In case all ports are removed from the bridge, remove the VLAN */
902*cb477c30SDaniel Golle 	if (!(vlan_mapping.val[1] & ~dsa_cpu_ports(priv->ds))) {
903*cb477c30SDaniel Golle 		err = gswip_vlan_active_remove(priv, idx);
904*cb477c30SDaniel Golle 		if (err) {
905*cb477c30SDaniel Golle 			dev_err(priv->dev, "failed to write active VLAN: %d\n",
906*cb477c30SDaniel Golle 				err);
907*cb477c30SDaniel Golle 			return err;
908*cb477c30SDaniel Golle 		}
909*cb477c30SDaniel Golle 	}
910*cb477c30SDaniel Golle 
911*cb477c30SDaniel Golle 	/* GSWIP 2.2 (GRX300) and later program here the VID directly. */
912*cb477c30SDaniel Golle 	if (pvid)
913*cb477c30SDaniel Golle 		gswip_switch_w(priv, 0, GSWIP_PCE_DEFPVID(port));
914*cb477c30SDaniel Golle 
915*cb477c30SDaniel Golle 	return 0;
916*cb477c30SDaniel Golle }
917*cb477c30SDaniel Golle 
918*cb477c30SDaniel Golle static int gswip_port_bridge_join(struct dsa_switch *ds, int port,
919*cb477c30SDaniel Golle 				  struct dsa_bridge bridge,
920*cb477c30SDaniel Golle 				  bool *tx_fwd_offload,
921*cb477c30SDaniel Golle 				  struct netlink_ext_ack *extack)
922*cb477c30SDaniel Golle {
923*cb477c30SDaniel Golle 	struct net_device *br = bridge.dev;
924*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
925*cb477c30SDaniel Golle 	int err;
926*cb477c30SDaniel Golle 
927*cb477c30SDaniel Golle 	/* When the bridge uses VLAN filtering we have to configure VLAN
928*cb477c30SDaniel Golle 	 * specific bridges. No bridge is configured here.
929*cb477c30SDaniel Golle 	 */
930*cb477c30SDaniel Golle 	if (!br_vlan_enabled(br)) {
931*cb477c30SDaniel Golle 		err = gswip_vlan_add_unaware(priv, br, port);
932*cb477c30SDaniel Golle 		if (err)
933*cb477c30SDaniel Golle 			return err;
934*cb477c30SDaniel Golle 		priv->port_vlan_filter &= ~BIT(port);
935*cb477c30SDaniel Golle 	} else {
936*cb477c30SDaniel Golle 		priv->port_vlan_filter |= BIT(port);
937*cb477c30SDaniel Golle 	}
938*cb477c30SDaniel Golle 	return gswip_add_single_port_br(priv, port, false);
939*cb477c30SDaniel Golle }
940*cb477c30SDaniel Golle 
941*cb477c30SDaniel Golle static void gswip_port_bridge_leave(struct dsa_switch *ds, int port,
942*cb477c30SDaniel Golle 				    struct dsa_bridge bridge)
943*cb477c30SDaniel Golle {
944*cb477c30SDaniel Golle 	struct net_device *br = bridge.dev;
945*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
946*cb477c30SDaniel Golle 
947*cb477c30SDaniel Golle 	gswip_add_single_port_br(priv, port, true);
948*cb477c30SDaniel Golle 
949*cb477c30SDaniel Golle 	/* When the bridge uses VLAN filtering we have to configure VLAN
950*cb477c30SDaniel Golle 	 * specific bridges. No bridge is configured here.
951*cb477c30SDaniel Golle 	 */
952*cb477c30SDaniel Golle 	if (!br_vlan_enabled(br))
953*cb477c30SDaniel Golle 		gswip_vlan_remove(priv, br, port, 0, true, false);
954*cb477c30SDaniel Golle }
955*cb477c30SDaniel Golle 
956*cb477c30SDaniel Golle static int gswip_port_vlan_prepare(struct dsa_switch *ds, int port,
957*cb477c30SDaniel Golle 				   const struct switchdev_obj_port_vlan *vlan,
958*cb477c30SDaniel Golle 				   struct netlink_ext_ack *extack)
959*cb477c30SDaniel Golle {
960*cb477c30SDaniel Golle 	struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port));
961*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
962*cb477c30SDaniel Golle 	unsigned int max_ports = priv->hw_info->max_ports;
963*cb477c30SDaniel Golle 	int pos = max_ports;
964*cb477c30SDaniel Golle 	int i, idx = -1;
965*cb477c30SDaniel Golle 
966*cb477c30SDaniel Golle 	/* We only support VLAN filtering on bridges */
967*cb477c30SDaniel Golle 	if (!dsa_is_cpu_port(ds, port) && !bridge)
968*cb477c30SDaniel Golle 		return -EOPNOTSUPP;
969*cb477c30SDaniel Golle 
970*cb477c30SDaniel Golle 	/* Check if there is already a page for this VLAN */
971*cb477c30SDaniel Golle 	for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) {
972*cb477c30SDaniel Golle 		if (priv->vlans[i].bridge == bridge &&
973*cb477c30SDaniel Golle 		    priv->vlans[i].vid == vlan->vid) {
974*cb477c30SDaniel Golle 			idx = i;
975*cb477c30SDaniel Golle 			break;
976*cb477c30SDaniel Golle 		}
977*cb477c30SDaniel Golle 	}
978*cb477c30SDaniel Golle 
979*cb477c30SDaniel Golle 	/* If this VLAN is not programmed yet, we have to reserve
980*cb477c30SDaniel Golle 	 * one entry in the VLAN table. Make sure we start at the
981*cb477c30SDaniel Golle 	 * next position round.
982*cb477c30SDaniel Golle 	 */
983*cb477c30SDaniel Golle 	if (idx == -1) {
984*cb477c30SDaniel Golle 		/* Look for a free slot */
985*cb477c30SDaniel Golle 		for (; pos < ARRAY_SIZE(priv->vlans); pos++) {
986*cb477c30SDaniel Golle 			if (!priv->vlans[pos].bridge) {
987*cb477c30SDaniel Golle 				idx = pos;
988*cb477c30SDaniel Golle 				pos++;
989*cb477c30SDaniel Golle 				break;
990*cb477c30SDaniel Golle 			}
991*cb477c30SDaniel Golle 		}
992*cb477c30SDaniel Golle 
993*cb477c30SDaniel Golle 		if (idx == -1) {
994*cb477c30SDaniel Golle 			NL_SET_ERR_MSG_MOD(extack, "No slot in VLAN table");
995*cb477c30SDaniel Golle 			return -ENOSPC;
996*cb477c30SDaniel Golle 		}
997*cb477c30SDaniel Golle 	}
998*cb477c30SDaniel Golle 
999*cb477c30SDaniel Golle 	return 0;
1000*cb477c30SDaniel Golle }
1001*cb477c30SDaniel Golle 
1002*cb477c30SDaniel Golle static int gswip_port_vlan_add(struct dsa_switch *ds, int port,
1003*cb477c30SDaniel Golle 			       const struct switchdev_obj_port_vlan *vlan,
1004*cb477c30SDaniel Golle 			       struct netlink_ext_ack *extack)
1005*cb477c30SDaniel Golle {
1006*cb477c30SDaniel Golle 	struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port));
1007*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1008*cb477c30SDaniel Golle 	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1009*cb477c30SDaniel Golle 	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1010*cb477c30SDaniel Golle 	int err;
1011*cb477c30SDaniel Golle 
1012*cb477c30SDaniel Golle 	err = gswip_port_vlan_prepare(ds, port, vlan, extack);
1013*cb477c30SDaniel Golle 	if (err)
1014*cb477c30SDaniel Golle 		return err;
1015*cb477c30SDaniel Golle 
1016*cb477c30SDaniel Golle 	/* We have to receive all packets on the CPU port and should not
1017*cb477c30SDaniel Golle 	 * do any VLAN filtering here. This is also called with bridge
1018*cb477c30SDaniel Golle 	 * NULL and then we do not know for which bridge to configure
1019*cb477c30SDaniel Golle 	 * this.
1020*cb477c30SDaniel Golle 	 */
1021*cb477c30SDaniel Golle 	if (dsa_is_cpu_port(ds, port))
1022*cb477c30SDaniel Golle 		return 0;
1023*cb477c30SDaniel Golle 
1024*cb477c30SDaniel Golle 	return gswip_vlan_add_aware(priv, bridge, port, vlan->vid,
1025*cb477c30SDaniel Golle 				    untagged, pvid);
1026*cb477c30SDaniel Golle }
1027*cb477c30SDaniel Golle 
1028*cb477c30SDaniel Golle static int gswip_port_vlan_del(struct dsa_switch *ds, int port,
1029*cb477c30SDaniel Golle 			       const struct switchdev_obj_port_vlan *vlan)
1030*cb477c30SDaniel Golle {
1031*cb477c30SDaniel Golle 	struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port));
1032*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1033*cb477c30SDaniel Golle 	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1034*cb477c30SDaniel Golle 
1035*cb477c30SDaniel Golle 	/* We have to receive all packets on the CPU port and should not
1036*cb477c30SDaniel Golle 	 * do any VLAN filtering here. This is also called with bridge
1037*cb477c30SDaniel Golle 	 * NULL and then we do not know for which bridge to configure
1038*cb477c30SDaniel Golle 	 * this.
1039*cb477c30SDaniel Golle 	 */
1040*cb477c30SDaniel Golle 	if (dsa_is_cpu_port(ds, port))
1041*cb477c30SDaniel Golle 		return 0;
1042*cb477c30SDaniel Golle 
1043*cb477c30SDaniel Golle 	return gswip_vlan_remove(priv, bridge, port, vlan->vid, pvid, true);
1044*cb477c30SDaniel Golle }
1045*cb477c30SDaniel Golle 
1046*cb477c30SDaniel Golle static void gswip_port_fast_age(struct dsa_switch *ds, int port)
1047*cb477c30SDaniel Golle {
1048*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1049*cb477c30SDaniel Golle 	struct gswip_pce_table_entry mac_bridge = {0,};
1050*cb477c30SDaniel Golle 	int i;
1051*cb477c30SDaniel Golle 	int err;
1052*cb477c30SDaniel Golle 
1053*cb477c30SDaniel Golle 	for (i = 0; i < 2048; i++) {
1054*cb477c30SDaniel Golle 		mac_bridge.table = GSWIP_TABLE_MAC_BRIDGE;
1055*cb477c30SDaniel Golle 		mac_bridge.index = i;
1056*cb477c30SDaniel Golle 
1057*cb477c30SDaniel Golle 		err = gswip_pce_table_entry_read(priv, &mac_bridge);
1058*cb477c30SDaniel Golle 		if (err) {
1059*cb477c30SDaniel Golle 			dev_err(priv->dev, "failed to read mac bridge: %d\n",
1060*cb477c30SDaniel Golle 				err);
1061*cb477c30SDaniel Golle 			return;
1062*cb477c30SDaniel Golle 		}
1063*cb477c30SDaniel Golle 
1064*cb477c30SDaniel Golle 		if (!mac_bridge.valid)
1065*cb477c30SDaniel Golle 			continue;
1066*cb477c30SDaniel Golle 
1067*cb477c30SDaniel Golle 		if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC)
1068*cb477c30SDaniel Golle 			continue;
1069*cb477c30SDaniel Golle 
1070*cb477c30SDaniel Golle 		if (port != FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT,
1071*cb477c30SDaniel Golle 				      mac_bridge.val[0]))
1072*cb477c30SDaniel Golle 			continue;
1073*cb477c30SDaniel Golle 
1074*cb477c30SDaniel Golle 		mac_bridge.valid = false;
1075*cb477c30SDaniel Golle 		err = gswip_pce_table_entry_write(priv, &mac_bridge);
1076*cb477c30SDaniel Golle 		if (err) {
1077*cb477c30SDaniel Golle 			dev_err(priv->dev, "failed to write mac bridge: %d\n",
1078*cb477c30SDaniel Golle 				err);
1079*cb477c30SDaniel Golle 			return;
1080*cb477c30SDaniel Golle 		}
1081*cb477c30SDaniel Golle 	}
1082*cb477c30SDaniel Golle }
1083*cb477c30SDaniel Golle 
1084*cb477c30SDaniel Golle static void gswip_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
1085*cb477c30SDaniel Golle {
1086*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1087*cb477c30SDaniel Golle 	u32 stp_state;
1088*cb477c30SDaniel Golle 
1089*cb477c30SDaniel Golle 	switch (state) {
1090*cb477c30SDaniel Golle 	case BR_STATE_DISABLED:
1091*cb477c30SDaniel Golle 		gswip_switch_mask(priv, GSWIP_SDMA_PCTRL_EN, 0,
1092*cb477c30SDaniel Golle 				  GSWIP_SDMA_PCTRLp(port));
1093*cb477c30SDaniel Golle 		return;
1094*cb477c30SDaniel Golle 	case BR_STATE_BLOCKING:
1095*cb477c30SDaniel Golle 	case BR_STATE_LISTENING:
1096*cb477c30SDaniel Golle 		stp_state = GSWIP_PCE_PCTRL_0_PSTATE_LISTEN;
1097*cb477c30SDaniel Golle 		break;
1098*cb477c30SDaniel Golle 	case BR_STATE_LEARNING:
1099*cb477c30SDaniel Golle 		stp_state = GSWIP_PCE_PCTRL_0_PSTATE_LEARNING;
1100*cb477c30SDaniel Golle 		break;
1101*cb477c30SDaniel Golle 	case BR_STATE_FORWARDING:
1102*cb477c30SDaniel Golle 		stp_state = GSWIP_PCE_PCTRL_0_PSTATE_FORWARDING;
1103*cb477c30SDaniel Golle 		break;
1104*cb477c30SDaniel Golle 	default:
1105*cb477c30SDaniel Golle 		dev_err(priv->dev, "invalid STP state: %d\n", state);
1106*cb477c30SDaniel Golle 		return;
1107*cb477c30SDaniel Golle 	}
1108*cb477c30SDaniel Golle 
1109*cb477c30SDaniel Golle 	gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN,
1110*cb477c30SDaniel Golle 			  GSWIP_SDMA_PCTRLp(port));
1111*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_PSTATE_MASK, stp_state,
1112*cb477c30SDaniel Golle 			  GSWIP_PCE_PCTRL_0p(port));
1113*cb477c30SDaniel Golle }
1114*cb477c30SDaniel Golle 
1115*cb477c30SDaniel Golle static int gswip_port_fdb(struct dsa_switch *ds, int port,
1116*cb477c30SDaniel Golle 			  const unsigned char *addr, u16 vid, bool add)
1117*cb477c30SDaniel Golle {
1118*cb477c30SDaniel Golle 	struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port));
1119*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1120*cb477c30SDaniel Golle 	struct gswip_pce_table_entry mac_bridge = {0,};
1121*cb477c30SDaniel Golle 	unsigned int max_ports = priv->hw_info->max_ports;
1122*cb477c30SDaniel Golle 	int fid = -1;
1123*cb477c30SDaniel Golle 	int i;
1124*cb477c30SDaniel Golle 	int err;
1125*cb477c30SDaniel Golle 
1126*cb477c30SDaniel Golle 	if (!bridge)
1127*cb477c30SDaniel Golle 		return -EINVAL;
1128*cb477c30SDaniel Golle 
1129*cb477c30SDaniel Golle 	for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) {
1130*cb477c30SDaniel Golle 		if (priv->vlans[i].bridge == bridge) {
1131*cb477c30SDaniel Golle 			fid = priv->vlans[i].fid;
1132*cb477c30SDaniel Golle 			break;
1133*cb477c30SDaniel Golle 		}
1134*cb477c30SDaniel Golle 	}
1135*cb477c30SDaniel Golle 
1136*cb477c30SDaniel Golle 	if (fid == -1) {
1137*cb477c30SDaniel Golle 		dev_err(priv->dev, "no FID found for bridge %s\n",
1138*cb477c30SDaniel Golle 			bridge->name);
1139*cb477c30SDaniel Golle 		return -EINVAL;
1140*cb477c30SDaniel Golle 	}
1141*cb477c30SDaniel Golle 
1142*cb477c30SDaniel Golle 	mac_bridge.table = GSWIP_TABLE_MAC_BRIDGE;
1143*cb477c30SDaniel Golle 	mac_bridge.key_mode = true;
1144*cb477c30SDaniel Golle 	mac_bridge.key[0] = addr[5] | (addr[4] << 8);
1145*cb477c30SDaniel Golle 	mac_bridge.key[1] = addr[3] | (addr[2] << 8);
1146*cb477c30SDaniel Golle 	mac_bridge.key[2] = addr[1] | (addr[0] << 8);
1147*cb477c30SDaniel Golle 	mac_bridge.key[3] = FIELD_PREP(GSWIP_TABLE_MAC_BRIDGE_KEY3_FID, fid);
1148*cb477c30SDaniel Golle 	mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */
1149*cb477c30SDaniel Golle 	mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC;
1150*cb477c30SDaniel Golle 	mac_bridge.valid = add;
1151*cb477c30SDaniel Golle 
1152*cb477c30SDaniel Golle 	err = gswip_pce_table_entry_write(priv, &mac_bridge);
1153*cb477c30SDaniel Golle 	if (err)
1154*cb477c30SDaniel Golle 		dev_err(priv->dev, "failed to write mac bridge: %d\n", err);
1155*cb477c30SDaniel Golle 
1156*cb477c30SDaniel Golle 	return err;
1157*cb477c30SDaniel Golle }
1158*cb477c30SDaniel Golle 
1159*cb477c30SDaniel Golle static int gswip_port_fdb_add(struct dsa_switch *ds, int port,
1160*cb477c30SDaniel Golle 			      const unsigned char *addr, u16 vid,
1161*cb477c30SDaniel Golle 			      struct dsa_db db)
1162*cb477c30SDaniel Golle {
1163*cb477c30SDaniel Golle 	return gswip_port_fdb(ds, port, addr, vid, true);
1164*cb477c30SDaniel Golle }
1165*cb477c30SDaniel Golle 
1166*cb477c30SDaniel Golle static int gswip_port_fdb_del(struct dsa_switch *ds, int port,
1167*cb477c30SDaniel Golle 			      const unsigned char *addr, u16 vid,
1168*cb477c30SDaniel Golle 			      struct dsa_db db)
1169*cb477c30SDaniel Golle {
1170*cb477c30SDaniel Golle 	return gswip_port_fdb(ds, port, addr, vid, false);
1171*cb477c30SDaniel Golle }
1172*cb477c30SDaniel Golle 
1173*cb477c30SDaniel Golle static int gswip_port_fdb_dump(struct dsa_switch *ds, int port,
1174*cb477c30SDaniel Golle 			       dsa_fdb_dump_cb_t *cb, void *data)
1175*cb477c30SDaniel Golle {
1176*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1177*cb477c30SDaniel Golle 	struct gswip_pce_table_entry mac_bridge = {0,};
1178*cb477c30SDaniel Golle 	unsigned char addr[ETH_ALEN];
1179*cb477c30SDaniel Golle 	int i;
1180*cb477c30SDaniel Golle 	int err;
1181*cb477c30SDaniel Golle 
1182*cb477c30SDaniel Golle 	for (i = 0; i < 2048; i++) {
1183*cb477c30SDaniel Golle 		mac_bridge.table = GSWIP_TABLE_MAC_BRIDGE;
1184*cb477c30SDaniel Golle 		mac_bridge.index = i;
1185*cb477c30SDaniel Golle 
1186*cb477c30SDaniel Golle 		err = gswip_pce_table_entry_read(priv, &mac_bridge);
1187*cb477c30SDaniel Golle 		if (err) {
1188*cb477c30SDaniel Golle 			dev_err(priv->dev,
1189*cb477c30SDaniel Golle 				"failed to read mac bridge entry %d: %d\n",
1190*cb477c30SDaniel Golle 				i, err);
1191*cb477c30SDaniel Golle 			return err;
1192*cb477c30SDaniel Golle 		}
1193*cb477c30SDaniel Golle 
1194*cb477c30SDaniel Golle 		if (!mac_bridge.valid)
1195*cb477c30SDaniel Golle 			continue;
1196*cb477c30SDaniel Golle 
1197*cb477c30SDaniel Golle 		addr[5] = mac_bridge.key[0] & 0xff;
1198*cb477c30SDaniel Golle 		addr[4] = (mac_bridge.key[0] >> 8) & 0xff;
1199*cb477c30SDaniel Golle 		addr[3] = mac_bridge.key[1] & 0xff;
1200*cb477c30SDaniel Golle 		addr[2] = (mac_bridge.key[1] >> 8) & 0xff;
1201*cb477c30SDaniel Golle 		addr[1] = mac_bridge.key[2] & 0xff;
1202*cb477c30SDaniel Golle 		addr[0] = (mac_bridge.key[2] >> 8) & 0xff;
1203*cb477c30SDaniel Golle 		if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC) {
1204*cb477c30SDaniel Golle 			if (mac_bridge.val[0] & BIT(port)) {
1205*cb477c30SDaniel Golle 				err = cb(addr, 0, true, data);
1206*cb477c30SDaniel Golle 				if (err)
1207*cb477c30SDaniel Golle 					return err;
1208*cb477c30SDaniel Golle 			}
1209*cb477c30SDaniel Golle 		} else {
1210*cb477c30SDaniel Golle 			if (port == FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT,
1211*cb477c30SDaniel Golle 					      mac_bridge.val[0])) {
1212*cb477c30SDaniel Golle 				err = cb(addr, 0, false, data);
1213*cb477c30SDaniel Golle 				if (err)
1214*cb477c30SDaniel Golle 					return err;
1215*cb477c30SDaniel Golle 			}
1216*cb477c30SDaniel Golle 		}
1217*cb477c30SDaniel Golle 	}
1218*cb477c30SDaniel Golle 	return 0;
1219*cb477c30SDaniel Golle }
1220*cb477c30SDaniel Golle 
1221*cb477c30SDaniel Golle static int gswip_port_max_mtu(struct dsa_switch *ds, int port)
1222*cb477c30SDaniel Golle {
1223*cb477c30SDaniel Golle 	/* Includes 8 bytes for special header. */
1224*cb477c30SDaniel Golle 	return GSWIP_MAX_PACKET_LENGTH - VLAN_ETH_HLEN - ETH_FCS_LEN;
1225*cb477c30SDaniel Golle }
1226*cb477c30SDaniel Golle 
1227*cb477c30SDaniel Golle static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
1228*cb477c30SDaniel Golle {
1229*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1230*cb477c30SDaniel Golle 
1231*cb477c30SDaniel Golle 	/* CPU port always has maximum mtu of user ports, so use it to set
1232*cb477c30SDaniel Golle 	 * switch frame size, including 8 byte special header.
1233*cb477c30SDaniel Golle 	 */
1234*cb477c30SDaniel Golle 	if (dsa_is_cpu_port(ds, port)) {
1235*cb477c30SDaniel Golle 		new_mtu += 8;
1236*cb477c30SDaniel Golle 		gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
1237*cb477c30SDaniel Golle 			       GSWIP_MAC_FLEN);
1238*cb477c30SDaniel Golle 	}
1239*cb477c30SDaniel Golle 
1240*cb477c30SDaniel Golle 	/* Enable MLEN for ports with non-standard MTUs, including the special
1241*cb477c30SDaniel Golle 	 * header on the CPU port added above.
1242*cb477c30SDaniel Golle 	 */
1243*cb477c30SDaniel Golle 	if (new_mtu != ETH_DATA_LEN)
1244*cb477c30SDaniel Golle 		gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
1245*cb477c30SDaniel Golle 				  GSWIP_MAC_CTRL_2p(port));
1246*cb477c30SDaniel Golle 	else
1247*cb477c30SDaniel Golle 		gswip_switch_mask(priv, GSWIP_MAC_CTRL_2_MLEN, 0,
1248*cb477c30SDaniel Golle 				  GSWIP_MAC_CTRL_2p(port));
1249*cb477c30SDaniel Golle 
1250*cb477c30SDaniel Golle 	return 0;
1251*cb477c30SDaniel Golle }
1252*cb477c30SDaniel Golle 
1253*cb477c30SDaniel Golle static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
1254*cb477c30SDaniel Golle 					  struct phylink_config *config)
1255*cb477c30SDaniel Golle {
1256*cb477c30SDaniel Golle 	switch (port) {
1257*cb477c30SDaniel Golle 	case 0:
1258*cb477c30SDaniel Golle 	case 1:
1259*cb477c30SDaniel Golle 		phy_interface_set_rgmii(config->supported_interfaces);
1260*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_MII,
1261*cb477c30SDaniel Golle 			  config->supported_interfaces);
1262*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_REVMII,
1263*cb477c30SDaniel Golle 			  config->supported_interfaces);
1264*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_RMII,
1265*cb477c30SDaniel Golle 			  config->supported_interfaces);
1266*cb477c30SDaniel Golle 		break;
1267*cb477c30SDaniel Golle 
1268*cb477c30SDaniel Golle 	case 2:
1269*cb477c30SDaniel Golle 	case 3:
1270*cb477c30SDaniel Golle 	case 4:
1271*cb477c30SDaniel Golle 	case 6:
1272*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
1273*cb477c30SDaniel Golle 			  config->supported_interfaces);
1274*cb477c30SDaniel Golle 		break;
1275*cb477c30SDaniel Golle 
1276*cb477c30SDaniel Golle 	case 5:
1277*cb477c30SDaniel Golle 		phy_interface_set_rgmii(config->supported_interfaces);
1278*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
1279*cb477c30SDaniel Golle 			  config->supported_interfaces);
1280*cb477c30SDaniel Golle 		break;
1281*cb477c30SDaniel Golle 	}
1282*cb477c30SDaniel Golle 
1283*cb477c30SDaniel Golle 	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
1284*cb477c30SDaniel Golle 		MAC_10 | MAC_100 | MAC_1000;
1285*cb477c30SDaniel Golle }
1286*cb477c30SDaniel Golle 
1287*cb477c30SDaniel Golle static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
1288*cb477c30SDaniel Golle 					  struct phylink_config *config)
1289*cb477c30SDaniel Golle {
1290*cb477c30SDaniel Golle 	switch (port) {
1291*cb477c30SDaniel Golle 	case 0:
1292*cb477c30SDaniel Golle 		phy_interface_set_rgmii(config->supported_interfaces);
1293*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_GMII,
1294*cb477c30SDaniel Golle 			  config->supported_interfaces);
1295*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_RMII,
1296*cb477c30SDaniel Golle 			  config->supported_interfaces);
1297*cb477c30SDaniel Golle 		break;
1298*cb477c30SDaniel Golle 
1299*cb477c30SDaniel Golle 	case 1:
1300*cb477c30SDaniel Golle 	case 2:
1301*cb477c30SDaniel Golle 	case 3:
1302*cb477c30SDaniel Golle 	case 4:
1303*cb477c30SDaniel Golle 	case 6:
1304*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
1305*cb477c30SDaniel Golle 			  config->supported_interfaces);
1306*cb477c30SDaniel Golle 		break;
1307*cb477c30SDaniel Golle 
1308*cb477c30SDaniel Golle 	case 5:
1309*cb477c30SDaniel Golle 		phy_interface_set_rgmii(config->supported_interfaces);
1310*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
1311*cb477c30SDaniel Golle 			  config->supported_interfaces);
1312*cb477c30SDaniel Golle 		__set_bit(PHY_INTERFACE_MODE_RMII,
1313*cb477c30SDaniel Golle 			  config->supported_interfaces);
1314*cb477c30SDaniel Golle 		break;
1315*cb477c30SDaniel Golle 	}
1316*cb477c30SDaniel Golle 
1317*cb477c30SDaniel Golle 	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
1318*cb477c30SDaniel Golle 		MAC_10 | MAC_100 | MAC_1000;
1319*cb477c30SDaniel Golle }
1320*cb477c30SDaniel Golle 
1321*cb477c30SDaniel Golle static void gswip_phylink_get_caps(struct dsa_switch *ds, int port,
1322*cb477c30SDaniel Golle 				   struct phylink_config *config)
1323*cb477c30SDaniel Golle {
1324*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1325*cb477c30SDaniel Golle 
1326*cb477c30SDaniel Golle 	priv->hw_info->phylink_get_caps(ds, port, config);
1327*cb477c30SDaniel Golle }
1328*cb477c30SDaniel Golle 
1329*cb477c30SDaniel Golle static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link)
1330*cb477c30SDaniel Golle {
1331*cb477c30SDaniel Golle 	u32 mdio_phy;
1332*cb477c30SDaniel Golle 
1333*cb477c30SDaniel Golle 	if (link)
1334*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_LINK_UP;
1335*cb477c30SDaniel Golle 	else
1336*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_LINK_DOWN;
1337*cb477c30SDaniel Golle 
1338*cb477c30SDaniel Golle 	gswip_mdio_mask(priv, GSWIP_MDIO_PHY_LINK_MASK, mdio_phy,
1339*cb477c30SDaniel Golle 			GSWIP_MDIO_PHYp(port));
1340*cb477c30SDaniel Golle }
1341*cb477c30SDaniel Golle 
1342*cb477c30SDaniel Golle static void gswip_port_set_speed(struct gswip_priv *priv, int port, int speed,
1343*cb477c30SDaniel Golle 				 phy_interface_t interface)
1344*cb477c30SDaniel Golle {
1345*cb477c30SDaniel Golle 	u32 mdio_phy = 0, mii_cfg = 0, mac_ctrl_0 = 0;
1346*cb477c30SDaniel Golle 
1347*cb477c30SDaniel Golle 	switch (speed) {
1348*cb477c30SDaniel Golle 	case SPEED_10:
1349*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_SPEED_M10;
1350*cb477c30SDaniel Golle 
1351*cb477c30SDaniel Golle 		if (interface == PHY_INTERFACE_MODE_RMII)
1352*cb477c30SDaniel Golle 			mii_cfg = GSWIP_MII_CFG_RATE_M50;
1353*cb477c30SDaniel Golle 		else
1354*cb477c30SDaniel Golle 			mii_cfg = GSWIP_MII_CFG_RATE_M2P5;
1355*cb477c30SDaniel Golle 
1356*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_MII;
1357*cb477c30SDaniel Golle 		break;
1358*cb477c30SDaniel Golle 
1359*cb477c30SDaniel Golle 	case SPEED_100:
1360*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_SPEED_M100;
1361*cb477c30SDaniel Golle 
1362*cb477c30SDaniel Golle 		if (interface == PHY_INTERFACE_MODE_RMII)
1363*cb477c30SDaniel Golle 			mii_cfg = GSWIP_MII_CFG_RATE_M50;
1364*cb477c30SDaniel Golle 		else
1365*cb477c30SDaniel Golle 			mii_cfg = GSWIP_MII_CFG_RATE_M25;
1366*cb477c30SDaniel Golle 
1367*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_MII;
1368*cb477c30SDaniel Golle 		break;
1369*cb477c30SDaniel Golle 
1370*cb477c30SDaniel Golle 	case SPEED_1000:
1371*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_SPEED_G1;
1372*cb477c30SDaniel Golle 
1373*cb477c30SDaniel Golle 		mii_cfg = GSWIP_MII_CFG_RATE_M125;
1374*cb477c30SDaniel Golle 
1375*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_RGMII;
1376*cb477c30SDaniel Golle 		break;
1377*cb477c30SDaniel Golle 	}
1378*cb477c30SDaniel Golle 
1379*cb477c30SDaniel Golle 	gswip_mdio_mask(priv, GSWIP_MDIO_PHY_SPEED_MASK, mdio_phy,
1380*cb477c30SDaniel Golle 			GSWIP_MDIO_PHYp(port));
1381*cb477c30SDaniel Golle 	gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_RATE_MASK, mii_cfg, port);
1382*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_GMII_MASK, mac_ctrl_0,
1383*cb477c30SDaniel Golle 			  GSWIP_MAC_CTRL_0p(port));
1384*cb477c30SDaniel Golle }
1385*cb477c30SDaniel Golle 
1386*cb477c30SDaniel Golle static void gswip_port_set_duplex(struct gswip_priv *priv, int port, int duplex)
1387*cb477c30SDaniel Golle {
1388*cb477c30SDaniel Golle 	u32 mac_ctrl_0, mdio_phy;
1389*cb477c30SDaniel Golle 
1390*cb477c30SDaniel Golle 	if (duplex == DUPLEX_FULL) {
1391*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_FDUP_EN;
1392*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_FDUP_EN;
1393*cb477c30SDaniel Golle 	} else {
1394*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_FDUP_DIS;
1395*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_FDUP_DIS;
1396*cb477c30SDaniel Golle 	}
1397*cb477c30SDaniel Golle 
1398*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_FDUP_MASK, mac_ctrl_0,
1399*cb477c30SDaniel Golle 			  GSWIP_MAC_CTRL_0p(port));
1400*cb477c30SDaniel Golle 	gswip_mdio_mask(priv, GSWIP_MDIO_PHY_FDUP_MASK, mdio_phy,
1401*cb477c30SDaniel Golle 			GSWIP_MDIO_PHYp(port));
1402*cb477c30SDaniel Golle }
1403*cb477c30SDaniel Golle 
1404*cb477c30SDaniel Golle static void gswip_port_set_pause(struct gswip_priv *priv, int port,
1405*cb477c30SDaniel Golle 				 bool tx_pause, bool rx_pause)
1406*cb477c30SDaniel Golle {
1407*cb477c30SDaniel Golle 	u32 mac_ctrl_0, mdio_phy;
1408*cb477c30SDaniel Golle 
1409*cb477c30SDaniel Golle 	if (tx_pause && rx_pause) {
1410*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_RXTX;
1411*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_FCONTX_EN |
1412*cb477c30SDaniel Golle 			   GSWIP_MDIO_PHY_FCONRX_EN;
1413*cb477c30SDaniel Golle 	} else if (tx_pause) {
1414*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_TX;
1415*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_FCONTX_EN |
1416*cb477c30SDaniel Golle 			   GSWIP_MDIO_PHY_FCONRX_DIS;
1417*cb477c30SDaniel Golle 	} else if (rx_pause) {
1418*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_RX;
1419*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_FCONTX_DIS |
1420*cb477c30SDaniel Golle 			   GSWIP_MDIO_PHY_FCONRX_EN;
1421*cb477c30SDaniel Golle 	} else {
1422*cb477c30SDaniel Golle 		mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_NONE;
1423*cb477c30SDaniel Golle 		mdio_phy = GSWIP_MDIO_PHY_FCONTX_DIS |
1424*cb477c30SDaniel Golle 			   GSWIP_MDIO_PHY_FCONRX_DIS;
1425*cb477c30SDaniel Golle 	}
1426*cb477c30SDaniel Golle 
1427*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_FCON_MASK,
1428*cb477c30SDaniel Golle 			  mac_ctrl_0, GSWIP_MAC_CTRL_0p(port));
1429*cb477c30SDaniel Golle 	gswip_mdio_mask(priv,
1430*cb477c30SDaniel Golle 			GSWIP_MDIO_PHY_FCONTX_MASK |
1431*cb477c30SDaniel Golle 			GSWIP_MDIO_PHY_FCONRX_MASK,
1432*cb477c30SDaniel Golle 			mdio_phy, GSWIP_MDIO_PHYp(port));
1433*cb477c30SDaniel Golle }
1434*cb477c30SDaniel Golle 
1435*cb477c30SDaniel Golle static void gswip_phylink_mac_config(struct phylink_config *config,
1436*cb477c30SDaniel Golle 				     unsigned int mode,
1437*cb477c30SDaniel Golle 				     const struct phylink_link_state *state)
1438*cb477c30SDaniel Golle {
1439*cb477c30SDaniel Golle 	struct dsa_port *dp = dsa_phylink_to_port(config);
1440*cb477c30SDaniel Golle 	struct gswip_priv *priv = dp->ds->priv;
1441*cb477c30SDaniel Golle 	int port = dp->index;
1442*cb477c30SDaniel Golle 	u32 miicfg = 0;
1443*cb477c30SDaniel Golle 
1444*cb477c30SDaniel Golle 	miicfg |= GSWIP_MII_CFG_LDCLKDIS;
1445*cb477c30SDaniel Golle 
1446*cb477c30SDaniel Golle 	switch (state->interface) {
1447*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_MII:
1448*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_INTERNAL:
1449*cb477c30SDaniel Golle 		miicfg |= GSWIP_MII_CFG_MODE_MIIM;
1450*cb477c30SDaniel Golle 		break;
1451*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_REVMII:
1452*cb477c30SDaniel Golle 		miicfg |= GSWIP_MII_CFG_MODE_MIIP;
1453*cb477c30SDaniel Golle 		break;
1454*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_RMII:
1455*cb477c30SDaniel Golle 		miicfg |= GSWIP_MII_CFG_MODE_RMIIM;
1456*cb477c30SDaniel Golle 		break;
1457*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_RGMII:
1458*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_RGMII_ID:
1459*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_RGMII_RXID:
1460*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_RGMII_TXID:
1461*cb477c30SDaniel Golle 		miicfg |= GSWIP_MII_CFG_MODE_RGMII;
1462*cb477c30SDaniel Golle 		break;
1463*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_GMII:
1464*cb477c30SDaniel Golle 		miicfg |= GSWIP_MII_CFG_MODE_GMII;
1465*cb477c30SDaniel Golle 		break;
1466*cb477c30SDaniel Golle 	default:
1467*cb477c30SDaniel Golle 		dev_err(dp->ds->dev,
1468*cb477c30SDaniel Golle 			"Unsupported interface: %d\n", state->interface);
1469*cb477c30SDaniel Golle 		return;
1470*cb477c30SDaniel Golle 	}
1471*cb477c30SDaniel Golle 
1472*cb477c30SDaniel Golle 	gswip_mii_mask_cfg(priv,
1473*cb477c30SDaniel Golle 			   GSWIP_MII_CFG_MODE_MASK | GSWIP_MII_CFG_RMII_CLK |
1474*cb477c30SDaniel Golle 			   GSWIP_MII_CFG_RGMII_IBS | GSWIP_MII_CFG_LDCLKDIS,
1475*cb477c30SDaniel Golle 			   miicfg, port);
1476*cb477c30SDaniel Golle 
1477*cb477c30SDaniel Golle 	switch (state->interface) {
1478*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_RGMII_ID:
1479*cb477c30SDaniel Golle 		gswip_mii_mask_pcdu(priv, GSWIP_MII_PCDU_TXDLY_MASK |
1480*cb477c30SDaniel Golle 					  GSWIP_MII_PCDU_RXDLY_MASK, 0, port);
1481*cb477c30SDaniel Golle 		break;
1482*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_RGMII_RXID:
1483*cb477c30SDaniel Golle 		gswip_mii_mask_pcdu(priv, GSWIP_MII_PCDU_RXDLY_MASK, 0, port);
1484*cb477c30SDaniel Golle 		break;
1485*cb477c30SDaniel Golle 	case PHY_INTERFACE_MODE_RGMII_TXID:
1486*cb477c30SDaniel Golle 		gswip_mii_mask_pcdu(priv, GSWIP_MII_PCDU_TXDLY_MASK, 0, port);
1487*cb477c30SDaniel Golle 		break;
1488*cb477c30SDaniel Golle 	default:
1489*cb477c30SDaniel Golle 		break;
1490*cb477c30SDaniel Golle 	}
1491*cb477c30SDaniel Golle }
1492*cb477c30SDaniel Golle 
1493*cb477c30SDaniel Golle static void gswip_phylink_mac_link_down(struct phylink_config *config,
1494*cb477c30SDaniel Golle 					unsigned int mode,
1495*cb477c30SDaniel Golle 					phy_interface_t interface)
1496*cb477c30SDaniel Golle {
1497*cb477c30SDaniel Golle 	struct dsa_port *dp = dsa_phylink_to_port(config);
1498*cb477c30SDaniel Golle 	struct gswip_priv *priv = dp->ds->priv;
1499*cb477c30SDaniel Golle 	int port = dp->index;
1500*cb477c30SDaniel Golle 
1501*cb477c30SDaniel Golle 	gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, port);
1502*cb477c30SDaniel Golle 
1503*cb477c30SDaniel Golle 	if (!dsa_port_is_cpu(dp))
1504*cb477c30SDaniel Golle 		gswip_port_set_link(priv, port, false);
1505*cb477c30SDaniel Golle }
1506*cb477c30SDaniel Golle 
1507*cb477c30SDaniel Golle static void gswip_phylink_mac_link_up(struct phylink_config *config,
1508*cb477c30SDaniel Golle 				      struct phy_device *phydev,
1509*cb477c30SDaniel Golle 				      unsigned int mode,
1510*cb477c30SDaniel Golle 				      phy_interface_t interface,
1511*cb477c30SDaniel Golle 				      int speed, int duplex,
1512*cb477c30SDaniel Golle 				      bool tx_pause, bool rx_pause)
1513*cb477c30SDaniel Golle {
1514*cb477c30SDaniel Golle 	struct dsa_port *dp = dsa_phylink_to_port(config);
1515*cb477c30SDaniel Golle 	struct gswip_priv *priv = dp->ds->priv;
1516*cb477c30SDaniel Golle 	int port = dp->index;
1517*cb477c30SDaniel Golle 
1518*cb477c30SDaniel Golle 	if (!dsa_port_is_cpu(dp)) {
1519*cb477c30SDaniel Golle 		gswip_port_set_link(priv, port, true);
1520*cb477c30SDaniel Golle 		gswip_port_set_speed(priv, port, speed, interface);
1521*cb477c30SDaniel Golle 		gswip_port_set_duplex(priv, port, duplex);
1522*cb477c30SDaniel Golle 		gswip_port_set_pause(priv, port, tx_pause, rx_pause);
1523*cb477c30SDaniel Golle 	}
1524*cb477c30SDaniel Golle 
1525*cb477c30SDaniel Golle 	gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port);
1526*cb477c30SDaniel Golle }
1527*cb477c30SDaniel Golle 
1528*cb477c30SDaniel Golle static void gswip_get_strings(struct dsa_switch *ds, int port, u32 stringset,
1529*cb477c30SDaniel Golle 			      uint8_t *data)
1530*cb477c30SDaniel Golle {
1531*cb477c30SDaniel Golle 	int i;
1532*cb477c30SDaniel Golle 
1533*cb477c30SDaniel Golle 	if (stringset != ETH_SS_STATS)
1534*cb477c30SDaniel Golle 		return;
1535*cb477c30SDaniel Golle 
1536*cb477c30SDaniel Golle 	for (i = 0; i < ARRAY_SIZE(gswip_rmon_cnt); i++)
1537*cb477c30SDaniel Golle 		ethtool_puts(&data, gswip_rmon_cnt[i].name);
1538*cb477c30SDaniel Golle }
1539*cb477c30SDaniel Golle 
1540*cb477c30SDaniel Golle static u32 gswip_bcm_ram_entry_read(struct gswip_priv *priv, u32 table,
1541*cb477c30SDaniel Golle 				    u32 index)
1542*cb477c30SDaniel Golle {
1543*cb477c30SDaniel Golle 	u32 result;
1544*cb477c30SDaniel Golle 	int err;
1545*cb477c30SDaniel Golle 
1546*cb477c30SDaniel Golle 	gswip_switch_w(priv, index, GSWIP_BM_RAM_ADDR);
1547*cb477c30SDaniel Golle 	gswip_switch_mask(priv, GSWIP_BM_RAM_CTRL_ADDR_MASK |
1548*cb477c30SDaniel Golle 				GSWIP_BM_RAM_CTRL_OPMOD,
1549*cb477c30SDaniel Golle 			      table | GSWIP_BM_RAM_CTRL_BAS,
1550*cb477c30SDaniel Golle 			      GSWIP_BM_RAM_CTRL);
1551*cb477c30SDaniel Golle 
1552*cb477c30SDaniel Golle 	err = gswip_switch_r_timeout(priv, GSWIP_BM_RAM_CTRL,
1553*cb477c30SDaniel Golle 				     GSWIP_BM_RAM_CTRL_BAS);
1554*cb477c30SDaniel Golle 	if (err) {
1555*cb477c30SDaniel Golle 		dev_err(priv->dev, "timeout while reading table: %u, index: %u\n",
1556*cb477c30SDaniel Golle 			table, index);
1557*cb477c30SDaniel Golle 		return 0;
1558*cb477c30SDaniel Golle 	}
1559*cb477c30SDaniel Golle 
1560*cb477c30SDaniel Golle 	result = gswip_switch_r(priv, GSWIP_BM_RAM_VAL(0));
1561*cb477c30SDaniel Golle 	result |= gswip_switch_r(priv, GSWIP_BM_RAM_VAL(1)) << 16;
1562*cb477c30SDaniel Golle 
1563*cb477c30SDaniel Golle 	return result;
1564*cb477c30SDaniel Golle }
1565*cb477c30SDaniel Golle 
1566*cb477c30SDaniel Golle static void gswip_get_ethtool_stats(struct dsa_switch *ds, int port,
1567*cb477c30SDaniel Golle 				    uint64_t *data)
1568*cb477c30SDaniel Golle {
1569*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1570*cb477c30SDaniel Golle 	const struct gswip_rmon_cnt_desc *rmon_cnt;
1571*cb477c30SDaniel Golle 	int i;
1572*cb477c30SDaniel Golle 	u64 high;
1573*cb477c30SDaniel Golle 
1574*cb477c30SDaniel Golle 	for (i = 0; i < ARRAY_SIZE(gswip_rmon_cnt); i++) {
1575*cb477c30SDaniel Golle 		rmon_cnt = &gswip_rmon_cnt[i];
1576*cb477c30SDaniel Golle 
1577*cb477c30SDaniel Golle 		data[i] = gswip_bcm_ram_entry_read(priv, port,
1578*cb477c30SDaniel Golle 						   rmon_cnt->offset);
1579*cb477c30SDaniel Golle 		if (rmon_cnt->size == 2) {
1580*cb477c30SDaniel Golle 			high = gswip_bcm_ram_entry_read(priv, port,
1581*cb477c30SDaniel Golle 							rmon_cnt->offset + 1);
1582*cb477c30SDaniel Golle 			data[i] |= high << 32;
1583*cb477c30SDaniel Golle 		}
1584*cb477c30SDaniel Golle 	}
1585*cb477c30SDaniel Golle }
1586*cb477c30SDaniel Golle 
1587*cb477c30SDaniel Golle static int gswip_get_sset_count(struct dsa_switch *ds, int port, int sset)
1588*cb477c30SDaniel Golle {
1589*cb477c30SDaniel Golle 	if (sset != ETH_SS_STATS)
1590*cb477c30SDaniel Golle 		return 0;
1591*cb477c30SDaniel Golle 
1592*cb477c30SDaniel Golle 	return ARRAY_SIZE(gswip_rmon_cnt);
1593*cb477c30SDaniel Golle }
1594*cb477c30SDaniel Golle 
1595*cb477c30SDaniel Golle static const struct phylink_mac_ops gswip_phylink_mac_ops = {
1596*cb477c30SDaniel Golle 	.mac_config	= gswip_phylink_mac_config,
1597*cb477c30SDaniel Golle 	.mac_link_down	= gswip_phylink_mac_link_down,
1598*cb477c30SDaniel Golle 	.mac_link_up	= gswip_phylink_mac_link_up,
1599*cb477c30SDaniel Golle };
1600*cb477c30SDaniel Golle 
1601*cb477c30SDaniel Golle static const struct dsa_switch_ops gswip_switch_ops = {
1602*cb477c30SDaniel Golle 	.get_tag_protocol	= gswip_get_tag_protocol,
1603*cb477c30SDaniel Golle 	.setup			= gswip_setup,
1604*cb477c30SDaniel Golle 	.port_enable		= gswip_port_enable,
1605*cb477c30SDaniel Golle 	.port_disable		= gswip_port_disable,
1606*cb477c30SDaniel Golle 	.port_bridge_join	= gswip_port_bridge_join,
1607*cb477c30SDaniel Golle 	.port_bridge_leave	= gswip_port_bridge_leave,
1608*cb477c30SDaniel Golle 	.port_fast_age		= gswip_port_fast_age,
1609*cb477c30SDaniel Golle 	.port_vlan_filtering	= gswip_port_vlan_filtering,
1610*cb477c30SDaniel Golle 	.port_vlan_add		= gswip_port_vlan_add,
1611*cb477c30SDaniel Golle 	.port_vlan_del		= gswip_port_vlan_del,
1612*cb477c30SDaniel Golle 	.port_stp_state_set	= gswip_port_stp_state_set,
1613*cb477c30SDaniel Golle 	.port_fdb_add		= gswip_port_fdb_add,
1614*cb477c30SDaniel Golle 	.port_fdb_del		= gswip_port_fdb_del,
1615*cb477c30SDaniel Golle 	.port_fdb_dump		= gswip_port_fdb_dump,
1616*cb477c30SDaniel Golle 	.port_change_mtu	= gswip_port_change_mtu,
1617*cb477c30SDaniel Golle 	.port_max_mtu		= gswip_port_max_mtu,
1618*cb477c30SDaniel Golle 	.phylink_get_caps	= gswip_phylink_get_caps,
1619*cb477c30SDaniel Golle 	.get_strings		= gswip_get_strings,
1620*cb477c30SDaniel Golle 	.get_ethtool_stats	= gswip_get_ethtool_stats,
1621*cb477c30SDaniel Golle 	.get_sset_count		= gswip_get_sset_count,
1622*cb477c30SDaniel Golle };
1623*cb477c30SDaniel Golle 
1624*cb477c30SDaniel Golle static const struct xway_gphy_match_data xrx200a1x_gphy_data = {
1625*cb477c30SDaniel Golle 	.fe_firmware_name = "lantiq/xrx200_phy22f_a14.bin",
1626*cb477c30SDaniel Golle 	.ge_firmware_name = "lantiq/xrx200_phy11g_a14.bin",
1627*cb477c30SDaniel Golle };
1628*cb477c30SDaniel Golle 
1629*cb477c30SDaniel Golle static const struct xway_gphy_match_data xrx200a2x_gphy_data = {
1630*cb477c30SDaniel Golle 	.fe_firmware_name = "lantiq/xrx200_phy22f_a22.bin",
1631*cb477c30SDaniel Golle 	.ge_firmware_name = "lantiq/xrx200_phy11g_a22.bin",
1632*cb477c30SDaniel Golle };
1633*cb477c30SDaniel Golle 
1634*cb477c30SDaniel Golle static const struct xway_gphy_match_data xrx300_gphy_data = {
1635*cb477c30SDaniel Golle 	.fe_firmware_name = "lantiq/xrx300_phy22f_a21.bin",
1636*cb477c30SDaniel Golle 	.ge_firmware_name = "lantiq/xrx300_phy11g_a21.bin",
1637*cb477c30SDaniel Golle };
1638*cb477c30SDaniel Golle 
1639*cb477c30SDaniel Golle static const struct of_device_id xway_gphy_match[] __maybe_unused = {
1640*cb477c30SDaniel Golle 	{ .compatible = "lantiq,xrx200-gphy-fw", .data = NULL },
1641*cb477c30SDaniel Golle 	{ .compatible = "lantiq,xrx200a1x-gphy-fw", .data = &xrx200a1x_gphy_data },
1642*cb477c30SDaniel Golle 	{ .compatible = "lantiq,xrx200a2x-gphy-fw", .data = &xrx200a2x_gphy_data },
1643*cb477c30SDaniel Golle 	{ .compatible = "lantiq,xrx300-gphy-fw", .data = &xrx300_gphy_data },
1644*cb477c30SDaniel Golle 	{ .compatible = "lantiq,xrx330-gphy-fw", .data = &xrx300_gphy_data },
1645*cb477c30SDaniel Golle 	{},
1646*cb477c30SDaniel Golle };
1647*cb477c30SDaniel Golle 
1648*cb477c30SDaniel Golle static int gswip_gphy_fw_load(struct gswip_priv *priv, struct gswip_gphy_fw *gphy_fw)
1649*cb477c30SDaniel Golle {
1650*cb477c30SDaniel Golle 	struct device *dev = priv->dev;
1651*cb477c30SDaniel Golle 	const struct firmware *fw;
1652*cb477c30SDaniel Golle 	void *fw_addr;
1653*cb477c30SDaniel Golle 	dma_addr_t dma_addr;
1654*cb477c30SDaniel Golle 	dma_addr_t dev_addr;
1655*cb477c30SDaniel Golle 	size_t size;
1656*cb477c30SDaniel Golle 	int ret;
1657*cb477c30SDaniel Golle 
1658*cb477c30SDaniel Golle 	ret = clk_prepare_enable(gphy_fw->clk_gate);
1659*cb477c30SDaniel Golle 	if (ret)
1660*cb477c30SDaniel Golle 		return ret;
1661*cb477c30SDaniel Golle 
1662*cb477c30SDaniel Golle 	reset_control_assert(gphy_fw->reset);
1663*cb477c30SDaniel Golle 
1664*cb477c30SDaniel Golle 	/* The vendor BSP uses a 200ms delay after asserting the reset line.
1665*cb477c30SDaniel Golle 	 * Without this some users are observing that the PHY is not coming up
1666*cb477c30SDaniel Golle 	 * on the MDIO bus.
1667*cb477c30SDaniel Golle 	 */
1668*cb477c30SDaniel Golle 	msleep(200);
1669*cb477c30SDaniel Golle 
1670*cb477c30SDaniel Golle 	ret = request_firmware(&fw, gphy_fw->fw_name, dev);
1671*cb477c30SDaniel Golle 	if (ret)
1672*cb477c30SDaniel Golle 		return dev_err_probe(dev, ret, "failed to load firmware: %s\n",
1673*cb477c30SDaniel Golle 				     gphy_fw->fw_name);
1674*cb477c30SDaniel Golle 
1675*cb477c30SDaniel Golle 	/* GPHY cores need the firmware code in a persistent and contiguous
1676*cb477c30SDaniel Golle 	 * memory area with a 16 kB boundary aligned start address.
1677*cb477c30SDaniel Golle 	 */
1678*cb477c30SDaniel Golle 	size = fw->size + XRX200_GPHY_FW_ALIGN;
1679*cb477c30SDaniel Golle 
1680*cb477c30SDaniel Golle 	fw_addr = dmam_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL);
1681*cb477c30SDaniel Golle 	if (fw_addr) {
1682*cb477c30SDaniel Golle 		fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN);
1683*cb477c30SDaniel Golle 		dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
1684*cb477c30SDaniel Golle 		memcpy(fw_addr, fw->data, fw->size);
1685*cb477c30SDaniel Golle 	} else {
1686*cb477c30SDaniel Golle 		release_firmware(fw);
1687*cb477c30SDaniel Golle 		return -ENOMEM;
1688*cb477c30SDaniel Golle 	}
1689*cb477c30SDaniel Golle 
1690*cb477c30SDaniel Golle 	release_firmware(fw);
1691*cb477c30SDaniel Golle 
1692*cb477c30SDaniel Golle 	ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, dev_addr);
1693*cb477c30SDaniel Golle 	if (ret)
1694*cb477c30SDaniel Golle 		return ret;
1695*cb477c30SDaniel Golle 
1696*cb477c30SDaniel Golle 	reset_control_deassert(gphy_fw->reset);
1697*cb477c30SDaniel Golle 
1698*cb477c30SDaniel Golle 	return ret;
1699*cb477c30SDaniel Golle }
1700*cb477c30SDaniel Golle 
1701*cb477c30SDaniel Golle static int gswip_gphy_fw_probe(struct gswip_priv *priv,
1702*cb477c30SDaniel Golle 			       struct gswip_gphy_fw *gphy_fw,
1703*cb477c30SDaniel Golle 			       struct device_node *gphy_fw_np, int i)
1704*cb477c30SDaniel Golle {
1705*cb477c30SDaniel Golle 	struct device *dev = priv->dev;
1706*cb477c30SDaniel Golle 	u32 gphy_mode;
1707*cb477c30SDaniel Golle 	int ret;
1708*cb477c30SDaniel Golle 	char gphyname[10];
1709*cb477c30SDaniel Golle 
1710*cb477c30SDaniel Golle 	snprintf(gphyname, sizeof(gphyname), "gphy%d", i);
1711*cb477c30SDaniel Golle 
1712*cb477c30SDaniel Golle 	gphy_fw->clk_gate = devm_clk_get(dev, gphyname);
1713*cb477c30SDaniel Golle 	if (IS_ERR(gphy_fw->clk_gate)) {
1714*cb477c30SDaniel Golle 		return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate),
1715*cb477c30SDaniel Golle 				     "Failed to lookup gate clock\n");
1716*cb477c30SDaniel Golle 	}
1717*cb477c30SDaniel Golle 
1718*cb477c30SDaniel Golle 	ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset);
1719*cb477c30SDaniel Golle 	if (ret)
1720*cb477c30SDaniel Golle 		return ret;
1721*cb477c30SDaniel Golle 
1722*cb477c30SDaniel Golle 	ret = of_property_read_u32(gphy_fw_np, "lantiq,gphy-mode", &gphy_mode);
1723*cb477c30SDaniel Golle 	/* Default to GE mode */
1724*cb477c30SDaniel Golle 	if (ret)
1725*cb477c30SDaniel Golle 		gphy_mode = GPHY_MODE_GE;
1726*cb477c30SDaniel Golle 
1727*cb477c30SDaniel Golle 	switch (gphy_mode) {
1728*cb477c30SDaniel Golle 	case GPHY_MODE_FE:
1729*cb477c30SDaniel Golle 		gphy_fw->fw_name = priv->gphy_fw_name_cfg->fe_firmware_name;
1730*cb477c30SDaniel Golle 		break;
1731*cb477c30SDaniel Golle 	case GPHY_MODE_GE:
1732*cb477c30SDaniel Golle 		gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name;
1733*cb477c30SDaniel Golle 		break;
1734*cb477c30SDaniel Golle 	default:
1735*cb477c30SDaniel Golle 		return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n",
1736*cb477c30SDaniel Golle 				     gphy_mode);
1737*cb477c30SDaniel Golle 	}
1738*cb477c30SDaniel Golle 
1739*cb477c30SDaniel Golle 	gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np);
1740*cb477c30SDaniel Golle 	if (IS_ERR(gphy_fw->reset))
1741*cb477c30SDaniel Golle 		return dev_err_probe(dev, PTR_ERR(gphy_fw->reset),
1742*cb477c30SDaniel Golle 				     "Failed to lookup gphy reset\n");
1743*cb477c30SDaniel Golle 
1744*cb477c30SDaniel Golle 	return gswip_gphy_fw_load(priv, gphy_fw);
1745*cb477c30SDaniel Golle }
1746*cb477c30SDaniel Golle 
1747*cb477c30SDaniel Golle static void gswip_gphy_fw_remove(struct gswip_priv *priv,
1748*cb477c30SDaniel Golle 				 struct gswip_gphy_fw *gphy_fw)
1749*cb477c30SDaniel Golle {
1750*cb477c30SDaniel Golle 	int ret;
1751*cb477c30SDaniel Golle 
1752*cb477c30SDaniel Golle 	/* check if the device was fully probed */
1753*cb477c30SDaniel Golle 	if (!gphy_fw->fw_name)
1754*cb477c30SDaniel Golle 		return;
1755*cb477c30SDaniel Golle 
1756*cb477c30SDaniel Golle 	ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, 0);
1757*cb477c30SDaniel Golle 	if (ret)
1758*cb477c30SDaniel Golle 		dev_err(priv->dev, "can not reset GPHY FW pointer\n");
1759*cb477c30SDaniel Golle 
1760*cb477c30SDaniel Golle 	clk_disable_unprepare(gphy_fw->clk_gate);
1761*cb477c30SDaniel Golle 
1762*cb477c30SDaniel Golle 	reset_control_put(gphy_fw->reset);
1763*cb477c30SDaniel Golle }
1764*cb477c30SDaniel Golle 
1765*cb477c30SDaniel Golle static int gswip_gphy_fw_list(struct gswip_priv *priv,
1766*cb477c30SDaniel Golle 			      struct device_node *gphy_fw_list_np, u32 version)
1767*cb477c30SDaniel Golle {
1768*cb477c30SDaniel Golle 	struct device *dev = priv->dev;
1769*cb477c30SDaniel Golle 	struct device_node *gphy_fw_np;
1770*cb477c30SDaniel Golle 	const struct of_device_id *match;
1771*cb477c30SDaniel Golle 	int err;
1772*cb477c30SDaniel Golle 	int i = 0;
1773*cb477c30SDaniel Golle 
1774*cb477c30SDaniel Golle 	/* The VRX200 rev 1.1 uses the GSWIP 2.0 and needs the older
1775*cb477c30SDaniel Golle 	 * GPHY firmware. The VRX200 rev 1.2 uses the GSWIP 2.1 and also
1776*cb477c30SDaniel Golle 	 * needs a different GPHY firmware.
1777*cb477c30SDaniel Golle 	 */
1778*cb477c30SDaniel Golle 	if (of_device_is_compatible(gphy_fw_list_np, "lantiq,xrx200-gphy-fw")) {
1779*cb477c30SDaniel Golle 		switch (version) {
1780*cb477c30SDaniel Golle 		case GSWIP_VERSION_2_0:
1781*cb477c30SDaniel Golle 			priv->gphy_fw_name_cfg = &xrx200a1x_gphy_data;
1782*cb477c30SDaniel Golle 			break;
1783*cb477c30SDaniel Golle 		case GSWIP_VERSION_2_1:
1784*cb477c30SDaniel Golle 			priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
1785*cb477c30SDaniel Golle 			break;
1786*cb477c30SDaniel Golle 		default:
1787*cb477c30SDaniel Golle 			return dev_err_probe(dev, -ENOENT,
1788*cb477c30SDaniel Golle 					     "unknown GSWIP version: 0x%x\n",
1789*cb477c30SDaniel Golle 					     version);
1790*cb477c30SDaniel Golle 		}
1791*cb477c30SDaniel Golle 	}
1792*cb477c30SDaniel Golle 
1793*cb477c30SDaniel Golle 	match = of_match_node(xway_gphy_match, gphy_fw_list_np);
1794*cb477c30SDaniel Golle 	if (match && match->data)
1795*cb477c30SDaniel Golle 		priv->gphy_fw_name_cfg = match->data;
1796*cb477c30SDaniel Golle 
1797*cb477c30SDaniel Golle 	if (!priv->gphy_fw_name_cfg)
1798*cb477c30SDaniel Golle 		return dev_err_probe(dev, -ENOENT,
1799*cb477c30SDaniel Golle 				     "GPHY compatible type not supported\n");
1800*cb477c30SDaniel Golle 
1801*cb477c30SDaniel Golle 	priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np);
1802*cb477c30SDaniel Golle 	if (!priv->num_gphy_fw)
1803*cb477c30SDaniel Golle 		return -ENOENT;
1804*cb477c30SDaniel Golle 
1805*cb477c30SDaniel Golle 	priv->rcu_regmap = syscon_regmap_lookup_by_phandle(gphy_fw_list_np,
1806*cb477c30SDaniel Golle 							   "lantiq,rcu");
1807*cb477c30SDaniel Golle 	if (IS_ERR(priv->rcu_regmap))
1808*cb477c30SDaniel Golle 		return PTR_ERR(priv->rcu_regmap);
1809*cb477c30SDaniel Golle 
1810*cb477c30SDaniel Golle 	priv->gphy_fw = devm_kmalloc_array(dev, priv->num_gphy_fw,
1811*cb477c30SDaniel Golle 					   sizeof(*priv->gphy_fw),
1812*cb477c30SDaniel Golle 					   GFP_KERNEL | __GFP_ZERO);
1813*cb477c30SDaniel Golle 	if (!priv->gphy_fw)
1814*cb477c30SDaniel Golle 		return -ENOMEM;
1815*cb477c30SDaniel Golle 
1816*cb477c30SDaniel Golle 	for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) {
1817*cb477c30SDaniel Golle 		err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i],
1818*cb477c30SDaniel Golle 					  gphy_fw_np, i);
1819*cb477c30SDaniel Golle 		if (err) {
1820*cb477c30SDaniel Golle 			of_node_put(gphy_fw_np);
1821*cb477c30SDaniel Golle 			goto remove_gphy;
1822*cb477c30SDaniel Golle 		}
1823*cb477c30SDaniel Golle 		i++;
1824*cb477c30SDaniel Golle 	}
1825*cb477c30SDaniel Golle 
1826*cb477c30SDaniel Golle 	/* The standalone PHY11G requires 300ms to be fully
1827*cb477c30SDaniel Golle 	 * initialized and ready for any MDIO communication after being
1828*cb477c30SDaniel Golle 	 * taken out of reset. For the SoC-internal GPHY variant there
1829*cb477c30SDaniel Golle 	 * is no (known) documentation for the minimum time after a
1830*cb477c30SDaniel Golle 	 * reset. Use the same value as for the standalone variant as
1831*cb477c30SDaniel Golle 	 * some users have reported internal PHYs not being detected
1832*cb477c30SDaniel Golle 	 * without any delay.
1833*cb477c30SDaniel Golle 	 */
1834*cb477c30SDaniel Golle 	msleep(300);
1835*cb477c30SDaniel Golle 
1836*cb477c30SDaniel Golle 	return 0;
1837*cb477c30SDaniel Golle 
1838*cb477c30SDaniel Golle remove_gphy:
1839*cb477c30SDaniel Golle 	for (i = 0; i < priv->num_gphy_fw; i++)
1840*cb477c30SDaniel Golle 		gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]);
1841*cb477c30SDaniel Golle 	return err;
1842*cb477c30SDaniel Golle }
1843*cb477c30SDaniel Golle 
1844*cb477c30SDaniel Golle static int gswip_validate_cpu_port(struct dsa_switch *ds)
1845*cb477c30SDaniel Golle {
1846*cb477c30SDaniel Golle 	struct gswip_priv *priv = ds->priv;
1847*cb477c30SDaniel Golle 	struct dsa_port *cpu_dp;
1848*cb477c30SDaniel Golle 	int cpu_port = -1;
1849*cb477c30SDaniel Golle 
1850*cb477c30SDaniel Golle 	dsa_switch_for_each_cpu_port(cpu_dp, ds) {
1851*cb477c30SDaniel Golle 		if (cpu_port != -1)
1852*cb477c30SDaniel Golle 			return dev_err_probe(ds->dev, -EINVAL,
1853*cb477c30SDaniel Golle 					     "only a single CPU port is supported\n");
1854*cb477c30SDaniel Golle 
1855*cb477c30SDaniel Golle 		cpu_port = cpu_dp->index;
1856*cb477c30SDaniel Golle 	}
1857*cb477c30SDaniel Golle 
1858*cb477c30SDaniel Golle 	if (cpu_port == -1)
1859*cb477c30SDaniel Golle 		return dev_err_probe(ds->dev, -EINVAL, "no CPU port defined\n");
1860*cb477c30SDaniel Golle 
1861*cb477c30SDaniel Golle 	if (BIT(cpu_port) & ~priv->hw_info->allowed_cpu_ports)
1862*cb477c30SDaniel Golle 		return dev_err_probe(ds->dev, -EINVAL,
1863*cb477c30SDaniel Golle 				     "unsupported CPU port defined\n");
1864*cb477c30SDaniel Golle 
1865*cb477c30SDaniel Golle 	return 0;
1866*cb477c30SDaniel Golle }
1867*cb477c30SDaniel Golle 
1868*cb477c30SDaniel Golle static int gswip_probe(struct platform_device *pdev)
1869*cb477c30SDaniel Golle {
1870*cb477c30SDaniel Golle 	struct device_node *np, *gphy_fw_np;
1871*cb477c30SDaniel Golle 	struct device *dev = &pdev->dev;
1872*cb477c30SDaniel Golle 	struct gswip_priv *priv;
1873*cb477c30SDaniel Golle 	int err;
1874*cb477c30SDaniel Golle 	int i;
1875*cb477c30SDaniel Golle 	u32 version;
1876*cb477c30SDaniel Golle 
1877*cb477c30SDaniel Golle 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1878*cb477c30SDaniel Golle 	if (!priv)
1879*cb477c30SDaniel Golle 		return -ENOMEM;
1880*cb477c30SDaniel Golle 
1881*cb477c30SDaniel Golle 	priv->gswip = devm_platform_ioremap_resource(pdev, 0);
1882*cb477c30SDaniel Golle 	if (IS_ERR(priv->gswip))
1883*cb477c30SDaniel Golle 		return PTR_ERR(priv->gswip);
1884*cb477c30SDaniel Golle 
1885*cb477c30SDaniel Golle 	priv->mdio = devm_platform_ioremap_resource(pdev, 1);
1886*cb477c30SDaniel Golle 	if (IS_ERR(priv->mdio))
1887*cb477c30SDaniel Golle 		return PTR_ERR(priv->mdio);
1888*cb477c30SDaniel Golle 
1889*cb477c30SDaniel Golle 	priv->mii = devm_platform_ioremap_resource(pdev, 2);
1890*cb477c30SDaniel Golle 	if (IS_ERR(priv->mii))
1891*cb477c30SDaniel Golle 		return PTR_ERR(priv->mii);
1892*cb477c30SDaniel Golle 
1893*cb477c30SDaniel Golle 	priv->hw_info = of_device_get_match_data(dev);
1894*cb477c30SDaniel Golle 	if (!priv->hw_info)
1895*cb477c30SDaniel Golle 		return -EINVAL;
1896*cb477c30SDaniel Golle 
1897*cb477c30SDaniel Golle 	priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
1898*cb477c30SDaniel Golle 	if (!priv->ds)
1899*cb477c30SDaniel Golle 		return -ENOMEM;
1900*cb477c30SDaniel Golle 
1901*cb477c30SDaniel Golle 	priv->ds->dev = dev;
1902*cb477c30SDaniel Golle 	priv->ds->num_ports = priv->hw_info->max_ports;
1903*cb477c30SDaniel Golle 	priv->ds->priv = priv;
1904*cb477c30SDaniel Golle 	priv->ds->ops = &gswip_switch_ops;
1905*cb477c30SDaniel Golle 	priv->ds->phylink_mac_ops = &gswip_phylink_mac_ops;
1906*cb477c30SDaniel Golle 	priv->dev = dev;
1907*cb477c30SDaniel Golle 	mutex_init(&priv->pce_table_lock);
1908*cb477c30SDaniel Golle 	version = gswip_switch_r(priv, GSWIP_VERSION);
1909*cb477c30SDaniel Golle 
1910*cb477c30SDaniel Golle 	/* The hardware has the 'major/minor' version bytes in the wrong order
1911*cb477c30SDaniel Golle 	 * preventing numerical comparisons. Construct a 16-bit unsigned integer
1912*cb477c30SDaniel Golle 	 * having the REV field as most significant byte and the MOD field as
1913*cb477c30SDaniel Golle 	 * least significant byte. This is effectively swapping the two bytes of
1914*cb477c30SDaniel Golle 	 * the version variable, but other than using swab16 it doesn't affect
1915*cb477c30SDaniel Golle 	 * the source variable.
1916*cb477c30SDaniel Golle 	 */
1917*cb477c30SDaniel Golle 	priv->version = GSWIP_VERSION_REV(version) << 8 |
1918*cb477c30SDaniel Golle 			GSWIP_VERSION_MOD(version);
1919*cb477c30SDaniel Golle 
1920*cb477c30SDaniel Golle 	np = dev->of_node;
1921*cb477c30SDaniel Golle 	switch (version) {
1922*cb477c30SDaniel Golle 	case GSWIP_VERSION_2_0:
1923*cb477c30SDaniel Golle 	case GSWIP_VERSION_2_1:
1924*cb477c30SDaniel Golle 		if (!of_device_is_compatible(np, "lantiq,xrx200-gswip"))
1925*cb477c30SDaniel Golle 			return -EINVAL;
1926*cb477c30SDaniel Golle 		break;
1927*cb477c30SDaniel Golle 	case GSWIP_VERSION_2_2:
1928*cb477c30SDaniel Golle 	case GSWIP_VERSION_2_2_ETC:
1929*cb477c30SDaniel Golle 		if (!of_device_is_compatible(np, "lantiq,xrx300-gswip") &&
1930*cb477c30SDaniel Golle 		    !of_device_is_compatible(np, "lantiq,xrx330-gswip"))
1931*cb477c30SDaniel Golle 			return -EINVAL;
1932*cb477c30SDaniel Golle 		break;
1933*cb477c30SDaniel Golle 	default:
1934*cb477c30SDaniel Golle 		return dev_err_probe(dev, -ENOENT,
1935*cb477c30SDaniel Golle 				     "unknown GSWIP version: 0x%x\n", version);
1936*cb477c30SDaniel Golle 	}
1937*cb477c30SDaniel Golle 
1938*cb477c30SDaniel Golle 	/* bring up the mdio bus */
1939*cb477c30SDaniel Golle 	gphy_fw_np = of_get_compatible_child(dev->of_node, "lantiq,gphy-fw");
1940*cb477c30SDaniel Golle 	if (gphy_fw_np) {
1941*cb477c30SDaniel Golle 		err = gswip_gphy_fw_list(priv, gphy_fw_np, version);
1942*cb477c30SDaniel Golle 		of_node_put(gphy_fw_np);
1943*cb477c30SDaniel Golle 		if (err)
1944*cb477c30SDaniel Golle 			return dev_err_probe(dev, err,
1945*cb477c30SDaniel Golle 					     "gphy fw probe failed\n");
1946*cb477c30SDaniel Golle 	}
1947*cb477c30SDaniel Golle 
1948*cb477c30SDaniel Golle 	/* bring up the mdio bus */
1949*cb477c30SDaniel Golle 	err = gswip_mdio(priv);
1950*cb477c30SDaniel Golle 	if (err) {
1951*cb477c30SDaniel Golle 		dev_err_probe(dev, err, "mdio probe failed\n");
1952*cb477c30SDaniel Golle 		goto gphy_fw_remove;
1953*cb477c30SDaniel Golle 	}
1954*cb477c30SDaniel Golle 
1955*cb477c30SDaniel Golle 	err = dsa_register_switch(priv->ds);
1956*cb477c30SDaniel Golle 	if (err) {
1957*cb477c30SDaniel Golle 		dev_err_probe(dev, err, "dsa switch registration failed\n");
1958*cb477c30SDaniel Golle 		goto gphy_fw_remove;
1959*cb477c30SDaniel Golle 	}
1960*cb477c30SDaniel Golle 
1961*cb477c30SDaniel Golle 	err = gswip_validate_cpu_port(priv->ds);
1962*cb477c30SDaniel Golle 	if (err)
1963*cb477c30SDaniel Golle 		goto disable_switch;
1964*cb477c30SDaniel Golle 
1965*cb477c30SDaniel Golle 	platform_set_drvdata(pdev, priv);
1966*cb477c30SDaniel Golle 
1967*cb477c30SDaniel Golle 	dev_info(dev, "probed GSWIP version %lx mod %lx\n",
1968*cb477c30SDaniel Golle 		 GSWIP_VERSION_REV(version), GSWIP_VERSION_MOD(version));
1969*cb477c30SDaniel Golle 	return 0;
1970*cb477c30SDaniel Golle 
1971*cb477c30SDaniel Golle disable_switch:
1972*cb477c30SDaniel Golle 	gswip_mdio_mask(priv, GSWIP_MDIO_GLOB_ENABLE, 0, GSWIP_MDIO_GLOB);
1973*cb477c30SDaniel Golle 	dsa_unregister_switch(priv->ds);
1974*cb477c30SDaniel Golle gphy_fw_remove:
1975*cb477c30SDaniel Golle 	for (i = 0; i < priv->num_gphy_fw; i++)
1976*cb477c30SDaniel Golle 		gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]);
1977*cb477c30SDaniel Golle 	return err;
1978*cb477c30SDaniel Golle }
1979*cb477c30SDaniel Golle 
1980*cb477c30SDaniel Golle static void gswip_remove(struct platform_device *pdev)
1981*cb477c30SDaniel Golle {
1982*cb477c30SDaniel Golle 	struct gswip_priv *priv = platform_get_drvdata(pdev);
1983*cb477c30SDaniel Golle 	int i;
1984*cb477c30SDaniel Golle 
1985*cb477c30SDaniel Golle 	if (!priv)
1986*cb477c30SDaniel Golle 		return;
1987*cb477c30SDaniel Golle 
1988*cb477c30SDaniel Golle 	/* disable the switch */
1989*cb477c30SDaniel Golle 	gswip_mdio_mask(priv, GSWIP_MDIO_GLOB_ENABLE, 0, GSWIP_MDIO_GLOB);
1990*cb477c30SDaniel Golle 
1991*cb477c30SDaniel Golle 	dsa_unregister_switch(priv->ds);
1992*cb477c30SDaniel Golle 
1993*cb477c30SDaniel Golle 	for (i = 0; i < priv->num_gphy_fw; i++)
1994*cb477c30SDaniel Golle 		gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]);
1995*cb477c30SDaniel Golle }
1996*cb477c30SDaniel Golle 
1997*cb477c30SDaniel Golle static void gswip_shutdown(struct platform_device *pdev)
1998*cb477c30SDaniel Golle {
1999*cb477c30SDaniel Golle 	struct gswip_priv *priv = platform_get_drvdata(pdev);
2000*cb477c30SDaniel Golle 
2001*cb477c30SDaniel Golle 	if (!priv)
2002*cb477c30SDaniel Golle 		return;
2003*cb477c30SDaniel Golle 
2004*cb477c30SDaniel Golle 	dsa_switch_shutdown(priv->ds);
2005*cb477c30SDaniel Golle 
2006*cb477c30SDaniel Golle 	platform_set_drvdata(pdev, NULL);
2007*cb477c30SDaniel Golle }
2008*cb477c30SDaniel Golle 
2009*cb477c30SDaniel Golle static const struct gswip_hw_info gswip_xrx200 = {
2010*cb477c30SDaniel Golle 	.max_ports = 7,
2011*cb477c30SDaniel Golle 	.allowed_cpu_ports = BIT(6),
2012*cb477c30SDaniel Golle 	.mii_ports = BIT(0) | BIT(1) | BIT(5),
2013*cb477c30SDaniel Golle 	.phylink_get_caps = gswip_xrx200_phylink_get_caps,
2014*cb477c30SDaniel Golle 	.pce_microcode = &gswip_pce_microcode,
2015*cb477c30SDaniel Golle 	.pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
2016*cb477c30SDaniel Golle 	.tag_protocol = DSA_TAG_PROTO_GSWIP,
2017*cb477c30SDaniel Golle };
2018*cb477c30SDaniel Golle 
2019*cb477c30SDaniel Golle static const struct gswip_hw_info gswip_xrx300 = {
2020*cb477c30SDaniel Golle 	.max_ports = 7,
2021*cb477c30SDaniel Golle 	.allowed_cpu_ports = BIT(6),
2022*cb477c30SDaniel Golle 	.mii_ports = BIT(0) | BIT(5),
2023*cb477c30SDaniel Golle 	.phylink_get_caps = gswip_xrx300_phylink_get_caps,
2024*cb477c30SDaniel Golle 	.pce_microcode = &gswip_pce_microcode,
2025*cb477c30SDaniel Golle 	.pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
2026*cb477c30SDaniel Golle 	.tag_protocol = DSA_TAG_PROTO_GSWIP,
2027*cb477c30SDaniel Golle };
2028*cb477c30SDaniel Golle 
2029*cb477c30SDaniel Golle static const struct of_device_id gswip_of_match[] = {
2030*cb477c30SDaniel Golle 	{ .compatible = "lantiq,xrx200-gswip", .data = &gswip_xrx200 },
2031*cb477c30SDaniel Golle 	{ .compatible = "lantiq,xrx300-gswip", .data = &gswip_xrx300 },
2032*cb477c30SDaniel Golle 	{ .compatible = "lantiq,xrx330-gswip", .data = &gswip_xrx300 },
2033*cb477c30SDaniel Golle 	{},
2034*cb477c30SDaniel Golle };
2035*cb477c30SDaniel Golle MODULE_DEVICE_TABLE(of, gswip_of_match);
2036*cb477c30SDaniel Golle 
2037*cb477c30SDaniel Golle static struct platform_driver gswip_driver = {
2038*cb477c30SDaniel Golle 	.probe = gswip_probe,
2039*cb477c30SDaniel Golle 	.remove = gswip_remove,
2040*cb477c30SDaniel Golle 	.shutdown = gswip_shutdown,
2041*cb477c30SDaniel Golle 	.driver = {
2042*cb477c30SDaniel Golle 		.name = "gswip",
2043*cb477c30SDaniel Golle 		.of_match_table = gswip_of_match,
2044*cb477c30SDaniel Golle 	},
2045*cb477c30SDaniel Golle };
2046*cb477c30SDaniel Golle 
2047*cb477c30SDaniel Golle module_platform_driver(gswip_driver);
2048*cb477c30SDaniel Golle 
2049*cb477c30SDaniel Golle MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin");
2050*cb477c30SDaniel Golle MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin");
2051*cb477c30SDaniel Golle MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin");
2052*cb477c30SDaniel Golle MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin");
2053*cb477c30SDaniel Golle MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin");
2054*cb477c30SDaniel Golle MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin");
2055*cb477c30SDaniel Golle MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
2056*cb477c30SDaniel Golle MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver");
2057*cb477c30SDaniel Golle MODULE_LICENSE("GPL v2");
2058