xref: /linux/drivers/net/dsa/microchip/lan937x_main.c (revision c9cd961c0d43a22eb704aa92e1f8fb33e3d286e8)
155ab6ffaSArun Ramadoss // SPDX-License-Identifier: GPL-2.0
255ab6ffaSArun Ramadoss /* Microchip LAN937X switch driver main logic
355ab6ffaSArun Ramadoss  * Copyright (C) 2019-2022 Microchip Technology Inc.
455ab6ffaSArun Ramadoss  */
555ab6ffaSArun Ramadoss #include <linux/kernel.h>
655ab6ffaSArun Ramadoss #include <linux/module.h>
755ab6ffaSArun Ramadoss #include <linux/iopoll.h>
855ab6ffaSArun Ramadoss #include <linux/phy.h>
955ab6ffaSArun Ramadoss #include <linux/of_net.h>
10a50b3536SArun Ramadoss #include <linux/of_mdio.h>
1155ab6ffaSArun Ramadoss #include <linux/if_bridge.h>
12ab882368SArun Ramadoss #include <linux/if_vlan.h>
13*c9cd961cSArun Ramadoss #include <linux/irq.h>
14*c9cd961cSArun Ramadoss #include <linux/irqdomain.h>
1555ab6ffaSArun Ramadoss #include <linux/math.h>
1655ab6ffaSArun Ramadoss #include <net/dsa.h>
1755ab6ffaSArun Ramadoss #include <net/switchdev.h>
1855ab6ffaSArun Ramadoss 
1955ab6ffaSArun Ramadoss #include "lan937x_reg.h"
2055ab6ffaSArun Ramadoss #include "ksz_common.h"
2155ab6ffaSArun Ramadoss #include "lan937x.h"
2255ab6ffaSArun Ramadoss 
23*c9cd961cSArun Ramadoss #define LAN937x_PNIRQS 6
24*c9cd961cSArun Ramadoss 
2555ab6ffaSArun Ramadoss static int lan937x_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
2655ab6ffaSArun Ramadoss {
2755ab6ffaSArun Ramadoss 	return regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0);
2855ab6ffaSArun Ramadoss }
2955ab6ffaSArun Ramadoss 
3055ab6ffaSArun Ramadoss static int lan937x_port_cfg(struct ksz_device *dev, int port, int offset,
3155ab6ffaSArun Ramadoss 			    u8 bits, bool set)
3255ab6ffaSArun Ramadoss {
3355ab6ffaSArun Ramadoss 	return regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset),
3455ab6ffaSArun Ramadoss 				  bits, set ? bits : 0);
3555ab6ffaSArun Ramadoss }
3655ab6ffaSArun Ramadoss 
37ffaf1de2SArun Ramadoss static int lan937x_enable_spi_indirect_access(struct ksz_device *dev)
38ffaf1de2SArun Ramadoss {
39ffaf1de2SArun Ramadoss 	u16 data16;
40ffaf1de2SArun Ramadoss 	int ret;
41ffaf1de2SArun Ramadoss 
42ffaf1de2SArun Ramadoss 	/* Enable Phy access through SPI */
43ffaf1de2SArun Ramadoss 	ret = lan937x_cfg(dev, REG_GLOBAL_CTRL_0, SW_PHY_REG_BLOCK, false);
44ffaf1de2SArun Ramadoss 	if (ret < 0)
45ffaf1de2SArun Ramadoss 		return ret;
46ffaf1de2SArun Ramadoss 
47ffaf1de2SArun Ramadoss 	ret = ksz_read16(dev, REG_VPHY_SPECIAL_CTRL__2, &data16);
48ffaf1de2SArun Ramadoss 	if (ret < 0)
49ffaf1de2SArun Ramadoss 		return ret;
50ffaf1de2SArun Ramadoss 
51ffaf1de2SArun Ramadoss 	/* Allow SPI access */
52ffaf1de2SArun Ramadoss 	data16 |= VPHY_SPI_INDIRECT_ENABLE;
53ffaf1de2SArun Ramadoss 
54ffaf1de2SArun Ramadoss 	return ksz_write16(dev, REG_VPHY_SPECIAL_CTRL__2, data16);
55ffaf1de2SArun Ramadoss }
56ffaf1de2SArun Ramadoss 
57ffaf1de2SArun Ramadoss static int lan937x_vphy_ind_addr_wr(struct ksz_device *dev, int addr, int reg)
58ffaf1de2SArun Ramadoss {
59ffaf1de2SArun Ramadoss 	u16 addr_base = REG_PORT_T1_PHY_CTRL_BASE;
60ffaf1de2SArun Ramadoss 	u16 temp;
61ffaf1de2SArun Ramadoss 
62ffaf1de2SArun Ramadoss 	/* get register address based on the logical port */
63ffaf1de2SArun Ramadoss 	temp = PORT_CTRL_ADDR(addr, (addr_base + (reg << 2)));
64ffaf1de2SArun Ramadoss 
65ffaf1de2SArun Ramadoss 	return ksz_write16(dev, REG_VPHY_IND_ADDR__2, temp);
66ffaf1de2SArun Ramadoss }
67ffaf1de2SArun Ramadoss 
68ffaf1de2SArun Ramadoss static int lan937x_internal_phy_write(struct ksz_device *dev, int addr, int reg,
69ffaf1de2SArun Ramadoss 				      u16 val)
70ffaf1de2SArun Ramadoss {
71ffaf1de2SArun Ramadoss 	unsigned int value;
72ffaf1de2SArun Ramadoss 	int ret;
73ffaf1de2SArun Ramadoss 
74ffaf1de2SArun Ramadoss 	/* Check for internal phy port */
75ffaf1de2SArun Ramadoss 	if (!dev->info->internal_phy[addr])
76ffaf1de2SArun Ramadoss 		return -EOPNOTSUPP;
77ffaf1de2SArun Ramadoss 
78ffaf1de2SArun Ramadoss 	ret = lan937x_vphy_ind_addr_wr(dev, addr, reg);
79ffaf1de2SArun Ramadoss 	if (ret < 0)
80ffaf1de2SArun Ramadoss 		return ret;
81ffaf1de2SArun Ramadoss 
82ffaf1de2SArun Ramadoss 	/* Write the data to be written to the VPHY reg */
83ffaf1de2SArun Ramadoss 	ret = ksz_write16(dev, REG_VPHY_IND_DATA__2, val);
84ffaf1de2SArun Ramadoss 	if (ret < 0)
85ffaf1de2SArun Ramadoss 		return ret;
86ffaf1de2SArun Ramadoss 
87ffaf1de2SArun Ramadoss 	/* Write the Write En and Busy bit */
88ffaf1de2SArun Ramadoss 	ret = ksz_write16(dev, REG_VPHY_IND_CTRL__2,
89ffaf1de2SArun Ramadoss 			  (VPHY_IND_WRITE | VPHY_IND_BUSY));
90ffaf1de2SArun Ramadoss 	if (ret < 0)
91ffaf1de2SArun Ramadoss 		return ret;
92ffaf1de2SArun Ramadoss 
93ffaf1de2SArun Ramadoss 	ret = regmap_read_poll_timeout(dev->regmap[1], REG_VPHY_IND_CTRL__2,
94ffaf1de2SArun Ramadoss 				       value, !(value & VPHY_IND_BUSY), 10,
95ffaf1de2SArun Ramadoss 				       1000);
96ffaf1de2SArun Ramadoss 	if (ret < 0) {
97ffaf1de2SArun Ramadoss 		dev_err(dev->dev, "Failed to write phy register\n");
98ffaf1de2SArun Ramadoss 		return ret;
99ffaf1de2SArun Ramadoss 	}
100ffaf1de2SArun Ramadoss 
101ffaf1de2SArun Ramadoss 	return 0;
102ffaf1de2SArun Ramadoss }
103ffaf1de2SArun Ramadoss 
104ffaf1de2SArun Ramadoss static int lan937x_internal_phy_read(struct ksz_device *dev, int addr, int reg,
105ffaf1de2SArun Ramadoss 				     u16 *val)
106ffaf1de2SArun Ramadoss {
107ffaf1de2SArun Ramadoss 	unsigned int value;
108ffaf1de2SArun Ramadoss 	int ret;
109ffaf1de2SArun Ramadoss 
110ffaf1de2SArun Ramadoss 	/* Check for internal phy port, return 0xffff for non-existent phy */
111ffaf1de2SArun Ramadoss 	if (!dev->info->internal_phy[addr])
112ffaf1de2SArun Ramadoss 		return 0xffff;
113ffaf1de2SArun Ramadoss 
114ffaf1de2SArun Ramadoss 	ret = lan937x_vphy_ind_addr_wr(dev, addr, reg);
115ffaf1de2SArun Ramadoss 	if (ret < 0)
116ffaf1de2SArun Ramadoss 		return ret;
117ffaf1de2SArun Ramadoss 
118ffaf1de2SArun Ramadoss 	/* Write Read and Busy bit to start the transaction */
119ffaf1de2SArun Ramadoss 	ret = ksz_write16(dev, REG_VPHY_IND_CTRL__2, VPHY_IND_BUSY);
120ffaf1de2SArun Ramadoss 	if (ret < 0)
121ffaf1de2SArun Ramadoss 		return ret;
122ffaf1de2SArun Ramadoss 
123ffaf1de2SArun Ramadoss 	ret = regmap_read_poll_timeout(dev->regmap[1], REG_VPHY_IND_CTRL__2,
124ffaf1de2SArun Ramadoss 				       value, !(value & VPHY_IND_BUSY), 10,
125ffaf1de2SArun Ramadoss 				       1000);
126ffaf1de2SArun Ramadoss 	if (ret < 0) {
127ffaf1de2SArun Ramadoss 		dev_err(dev->dev, "Failed to read phy register\n");
128ffaf1de2SArun Ramadoss 		return ret;
129ffaf1de2SArun Ramadoss 	}
130ffaf1de2SArun Ramadoss 
131ffaf1de2SArun Ramadoss 	/* Read the VPHY register which has the PHY data */
132ffaf1de2SArun Ramadoss 	return ksz_read16(dev, REG_VPHY_IND_DATA__2, val);
133ffaf1de2SArun Ramadoss }
134ffaf1de2SArun Ramadoss 
1358f420456SOleksij Rempel int lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data)
136ffaf1de2SArun Ramadoss {
1378f420456SOleksij Rempel 	return lan937x_internal_phy_read(dev, addr, reg, data);
138ffaf1de2SArun Ramadoss }
139ffaf1de2SArun Ramadoss 
1408f420456SOleksij Rempel int lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val)
141ffaf1de2SArun Ramadoss {
1428f420456SOleksij Rempel 	return lan937x_internal_phy_write(dev, addr, reg, val);
143ffaf1de2SArun Ramadoss }
144ffaf1de2SArun Ramadoss 
145a50b3536SArun Ramadoss static int lan937x_sw_mdio_read(struct mii_bus *bus, int addr, int regnum)
146a50b3536SArun Ramadoss {
147a50b3536SArun Ramadoss 	struct ksz_device *dev = bus->priv;
148a50b3536SArun Ramadoss 	u16 val;
149a50b3536SArun Ramadoss 	int ret;
150a50b3536SArun Ramadoss 
151a50b3536SArun Ramadoss 	if (regnum & MII_ADDR_C45)
152a50b3536SArun Ramadoss 		return -EOPNOTSUPP;
153a50b3536SArun Ramadoss 
154a50b3536SArun Ramadoss 	ret = lan937x_internal_phy_read(dev, addr, regnum, &val);
155a50b3536SArun Ramadoss 	if (ret < 0)
156a50b3536SArun Ramadoss 		return ret;
157a50b3536SArun Ramadoss 
158a50b3536SArun Ramadoss 	return val;
159a50b3536SArun Ramadoss }
160a50b3536SArun Ramadoss 
161a50b3536SArun Ramadoss static int lan937x_sw_mdio_write(struct mii_bus *bus, int addr, int regnum,
162a50b3536SArun Ramadoss 				 u16 val)
163a50b3536SArun Ramadoss {
164a50b3536SArun Ramadoss 	struct ksz_device *dev = bus->priv;
165a50b3536SArun Ramadoss 
166a50b3536SArun Ramadoss 	if (regnum & MII_ADDR_C45)
167a50b3536SArun Ramadoss 		return -EOPNOTSUPP;
168a50b3536SArun Ramadoss 
169a50b3536SArun Ramadoss 	return lan937x_internal_phy_write(dev, addr, regnum, val);
170a50b3536SArun Ramadoss }
171a50b3536SArun Ramadoss 
172*c9cd961cSArun Ramadoss static int lan937x_irq_phy_setup(struct ksz_device *dev)
173*c9cd961cSArun Ramadoss {
174*c9cd961cSArun Ramadoss 	struct dsa_switch *ds = dev->ds;
175*c9cd961cSArun Ramadoss 	int phy, err_phy;
176*c9cd961cSArun Ramadoss 	int irq;
177*c9cd961cSArun Ramadoss 	int ret;
178*c9cd961cSArun Ramadoss 
179*c9cd961cSArun Ramadoss 	for (phy = 0; phy < KSZ_MAX_NUM_PORTS; phy++) {
180*c9cd961cSArun Ramadoss 		if (BIT(phy) & ds->phys_mii_mask) {
181*c9cd961cSArun Ramadoss 			irq = irq_find_mapping(dev->ports[phy].pirq.domain,
182*c9cd961cSArun Ramadoss 					       PORT_SRC_PHY_INT);
183*c9cd961cSArun Ramadoss 			if (irq < 0) {
184*c9cd961cSArun Ramadoss 				ret = irq;
185*c9cd961cSArun Ramadoss 				goto out;
186*c9cd961cSArun Ramadoss 			}
187*c9cd961cSArun Ramadoss 			ds->slave_mii_bus->irq[phy] = irq;
188*c9cd961cSArun Ramadoss 		}
189*c9cd961cSArun Ramadoss 	}
190*c9cd961cSArun Ramadoss 	return 0;
191*c9cd961cSArun Ramadoss out:
192*c9cd961cSArun Ramadoss 	err_phy = phy;
193*c9cd961cSArun Ramadoss 
194*c9cd961cSArun Ramadoss 	for (phy = 0; phy < err_phy; phy++)
195*c9cd961cSArun Ramadoss 		if (BIT(phy) & ds->phys_mii_mask)
196*c9cd961cSArun Ramadoss 			irq_dispose_mapping(ds->slave_mii_bus->irq[phy]);
197*c9cd961cSArun Ramadoss 
198*c9cd961cSArun Ramadoss 	return ret;
199*c9cd961cSArun Ramadoss }
200*c9cd961cSArun Ramadoss 
201*c9cd961cSArun Ramadoss static void lan937x_irq_phy_free(struct ksz_device *dev)
202*c9cd961cSArun Ramadoss {
203*c9cd961cSArun Ramadoss 	struct dsa_switch *ds = dev->ds;
204*c9cd961cSArun Ramadoss 	int phy;
205*c9cd961cSArun Ramadoss 
206*c9cd961cSArun Ramadoss 	for (phy = 0; phy < KSZ_MAX_NUM_PORTS; phy++)
207*c9cd961cSArun Ramadoss 		if (BIT(phy) & ds->phys_mii_mask)
208*c9cd961cSArun Ramadoss 			irq_dispose_mapping(ds->slave_mii_bus->irq[phy]);
209*c9cd961cSArun Ramadoss }
210*c9cd961cSArun Ramadoss 
211a50b3536SArun Ramadoss static int lan937x_mdio_register(struct ksz_device *dev)
212a50b3536SArun Ramadoss {
213a50b3536SArun Ramadoss 	struct dsa_switch *ds = dev->ds;
214a50b3536SArun Ramadoss 	struct device_node *mdio_np;
215a50b3536SArun Ramadoss 	struct mii_bus *bus;
216a50b3536SArun Ramadoss 	int ret;
217a50b3536SArun Ramadoss 
218a50b3536SArun Ramadoss 	mdio_np = of_get_child_by_name(dev->dev->of_node, "mdio");
219a50b3536SArun Ramadoss 	if (!mdio_np) {
220a50b3536SArun Ramadoss 		dev_err(ds->dev, "no MDIO bus node\n");
221a50b3536SArun Ramadoss 		return -ENODEV;
222a50b3536SArun Ramadoss 	}
223a50b3536SArun Ramadoss 
224a50b3536SArun Ramadoss 	bus = devm_mdiobus_alloc(ds->dev);
225a50b3536SArun Ramadoss 	if (!bus) {
226a50b3536SArun Ramadoss 		of_node_put(mdio_np);
227a50b3536SArun Ramadoss 		return -ENOMEM;
228a50b3536SArun Ramadoss 	}
229a50b3536SArun Ramadoss 
230a50b3536SArun Ramadoss 	bus->priv = dev;
231a50b3536SArun Ramadoss 	bus->read = lan937x_sw_mdio_read;
232a50b3536SArun Ramadoss 	bus->write = lan937x_sw_mdio_write;
233a50b3536SArun Ramadoss 	bus->name = "lan937x slave smi";
234a50b3536SArun Ramadoss 	snprintf(bus->id, MII_BUS_ID_SIZE, "SMI-%d", ds->index);
235a50b3536SArun Ramadoss 	bus->parent = ds->dev;
236a50b3536SArun Ramadoss 	bus->phy_mask = ~ds->phys_mii_mask;
237a50b3536SArun Ramadoss 
238a50b3536SArun Ramadoss 	ds->slave_mii_bus = bus;
239a50b3536SArun Ramadoss 
240*c9cd961cSArun Ramadoss 	ret = lan937x_irq_phy_setup(dev);
241*c9cd961cSArun Ramadoss 	if (ret)
242*c9cd961cSArun Ramadoss 		return ret;
243*c9cd961cSArun Ramadoss 
244a50b3536SArun Ramadoss 	ret = devm_of_mdiobus_register(ds->dev, bus, mdio_np);
245a50b3536SArun Ramadoss 	if (ret) {
246a50b3536SArun Ramadoss 		dev_err(ds->dev, "unable to register MDIO bus %s\n",
247a50b3536SArun Ramadoss 			bus->id);
248*c9cd961cSArun Ramadoss 		lan937x_irq_phy_free(dev);
249a50b3536SArun Ramadoss 	}
250a50b3536SArun Ramadoss 
251a50b3536SArun Ramadoss 	of_node_put(mdio_np);
252a50b3536SArun Ramadoss 
253a50b3536SArun Ramadoss 	return ret;
254a50b3536SArun Ramadoss }
255a50b3536SArun Ramadoss 
25655ab6ffaSArun Ramadoss int lan937x_reset_switch(struct ksz_device *dev)
25755ab6ffaSArun Ramadoss {
25855ab6ffaSArun Ramadoss 	u32 data32;
25955ab6ffaSArun Ramadoss 	int ret;
26055ab6ffaSArun Ramadoss 
26155ab6ffaSArun Ramadoss 	/* reset switch */
26255ab6ffaSArun Ramadoss 	ret = lan937x_cfg(dev, REG_SW_OPERATION, SW_RESET, true);
26355ab6ffaSArun Ramadoss 	if (ret < 0)
26455ab6ffaSArun Ramadoss 		return ret;
26555ab6ffaSArun Ramadoss 
26655ab6ffaSArun Ramadoss 	/* Enable Auto Aging */
26755ab6ffaSArun Ramadoss 	ret = lan937x_cfg(dev, REG_SW_LUE_CTRL_1, SW_LINK_AUTO_AGING, true);
26855ab6ffaSArun Ramadoss 	if (ret < 0)
26955ab6ffaSArun Ramadoss 		return ret;
27055ab6ffaSArun Ramadoss 
27155ab6ffaSArun Ramadoss 	/* disable interrupts */
27255ab6ffaSArun Ramadoss 	ret = ksz_write32(dev, REG_SW_INT_MASK__4, SWITCH_INT_MASK);
27355ab6ffaSArun Ramadoss 	if (ret < 0)
27455ab6ffaSArun Ramadoss 		return ret;
27555ab6ffaSArun Ramadoss 
276f3139362SArun Ramadoss 	ret = ksz_write32(dev, REG_SW_INT_STATUS__4, POR_READY_INT);
277f3139362SArun Ramadoss 	if (ret < 0)
278f3139362SArun Ramadoss 		return ret;
279f3139362SArun Ramadoss 
28055ab6ffaSArun Ramadoss 	ret = ksz_write32(dev, REG_SW_PORT_INT_MASK__4, 0xFF);
28155ab6ffaSArun Ramadoss 	if (ret < 0)
28255ab6ffaSArun Ramadoss 		return ret;
28355ab6ffaSArun Ramadoss 
28455ab6ffaSArun Ramadoss 	return ksz_read32(dev, REG_SW_PORT_INT_STATUS__4, &data32);
28555ab6ffaSArun Ramadoss }
28655ab6ffaSArun Ramadoss 
28755ab6ffaSArun Ramadoss void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port)
28855ab6ffaSArun Ramadoss {
2898560664fSArun Ramadoss 	const u32 *masks = dev->info->masks;
2908560664fSArun Ramadoss 	const u16 *regs = dev->info->regs;
29155ab6ffaSArun Ramadoss 	struct dsa_switch *ds = dev->ds;
29255ab6ffaSArun Ramadoss 	u8 member;
29355ab6ffaSArun Ramadoss 
29455ab6ffaSArun Ramadoss 	/* enable tag tail for host port */
29555ab6ffaSArun Ramadoss 	if (cpu_port)
29655ab6ffaSArun Ramadoss 		lan937x_port_cfg(dev, port, REG_PORT_CTRL_0,
29755ab6ffaSArun Ramadoss 				 PORT_TAIL_TAG_ENABLE, true);
29855ab6ffaSArun Ramadoss 
29955ab6ffaSArun Ramadoss 	/* disable frame check length field */
30055ab6ffaSArun Ramadoss 	lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0, PORT_CHECK_LENGTH,
30155ab6ffaSArun Ramadoss 			 false);
30255ab6ffaSArun Ramadoss 
30355ab6ffaSArun Ramadoss 	/* set back pressure for half duplex */
30455ab6ffaSArun Ramadoss 	lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_1, PORT_BACK_PRESSURE,
30555ab6ffaSArun Ramadoss 			 true);
30655ab6ffaSArun Ramadoss 
30755ab6ffaSArun Ramadoss 	/* enable 802.1p priority */
30855ab6ffaSArun Ramadoss 	lan937x_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_PRIO_ENABLE, true);
30955ab6ffaSArun Ramadoss 
31055ab6ffaSArun Ramadoss 	if (!dev->info->internal_phy[port])
3118560664fSArun Ramadoss 		lan937x_port_cfg(dev, port, regs[P_XMII_CTRL_0],
3128560664fSArun Ramadoss 				 masks[P_MII_TX_FLOW_CTRL] |
3138560664fSArun Ramadoss 				 masks[P_MII_RX_FLOW_CTRL],
31455ab6ffaSArun Ramadoss 				 true);
31555ab6ffaSArun Ramadoss 
31655ab6ffaSArun Ramadoss 	if (cpu_port)
31755ab6ffaSArun Ramadoss 		member = dsa_user_ports(ds);
31855ab6ffaSArun Ramadoss 	else
31955ab6ffaSArun Ramadoss 		member = BIT(dsa_upstream_port(ds, port));
32055ab6ffaSArun Ramadoss 
32155ab6ffaSArun Ramadoss 	dev->dev_ops->cfg_port_member(dev, port, member);
32255ab6ffaSArun Ramadoss }
32355ab6ffaSArun Ramadoss 
32455ab6ffaSArun Ramadoss void lan937x_config_cpu_port(struct dsa_switch *ds)
32555ab6ffaSArun Ramadoss {
32655ab6ffaSArun Ramadoss 	struct ksz_device *dev = ds->priv;
32755ab6ffaSArun Ramadoss 	struct dsa_port *dp;
32855ab6ffaSArun Ramadoss 
32955ab6ffaSArun Ramadoss 	dsa_switch_for_each_cpu_port(dp, ds) {
33055ab6ffaSArun Ramadoss 		if (dev->info->cpu_ports & (1 << dp->index)) {
33155ab6ffaSArun Ramadoss 			dev->cpu_port = dp->index;
33255ab6ffaSArun Ramadoss 
33355ab6ffaSArun Ramadoss 			/* enable cpu port */
33455ab6ffaSArun Ramadoss 			lan937x_port_setup(dev, dp->index, true);
33555ab6ffaSArun Ramadoss 		}
33655ab6ffaSArun Ramadoss 	}
33755ab6ffaSArun Ramadoss 
33855ab6ffaSArun Ramadoss 	dsa_switch_for_each_user_port(dp, ds) {
33955ab6ffaSArun Ramadoss 		ksz_port_stp_state_set(ds, dp->index, BR_STATE_DISABLED);
34055ab6ffaSArun Ramadoss 	}
34155ab6ffaSArun Ramadoss }
34255ab6ffaSArun Ramadoss 
343ab882368SArun Ramadoss int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu)
344ab882368SArun Ramadoss {
345ab882368SArun Ramadoss 	struct dsa_switch *ds = dev->ds;
346ab882368SArun Ramadoss 	int ret;
347ab882368SArun Ramadoss 
348ab882368SArun Ramadoss 	new_mtu += VLAN_ETH_HLEN + ETH_FCS_LEN;
349ab882368SArun Ramadoss 
350ab882368SArun Ramadoss 	if (dsa_is_cpu_port(ds, port))
351ab882368SArun Ramadoss 		new_mtu += LAN937X_TAG_LEN;
352ab882368SArun Ramadoss 
353ab882368SArun Ramadoss 	if (new_mtu >= FR_MIN_SIZE)
354ab882368SArun Ramadoss 		ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0,
355ab882368SArun Ramadoss 				       PORT_JUMBO_PACKET, true);
356ab882368SArun Ramadoss 	else
357ab882368SArun Ramadoss 		ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0,
358ab882368SArun Ramadoss 				       PORT_JUMBO_PACKET, false);
359ab882368SArun Ramadoss 	if (ret < 0) {
360ab882368SArun Ramadoss 		dev_err(ds->dev, "failed to enable jumbo\n");
361ab882368SArun Ramadoss 		return ret;
362ab882368SArun Ramadoss 	}
363ab882368SArun Ramadoss 
364ab882368SArun Ramadoss 	/* Write the frame size in PORT_MAX_FR_SIZE register */
365ab882368SArun Ramadoss 	ksz_pwrite16(dev, port, PORT_MAX_FR_SIZE, new_mtu);
366ab882368SArun Ramadoss 
367ab882368SArun Ramadoss 	return 0;
368ab882368SArun Ramadoss }
369ab882368SArun Ramadoss 
370b19ac41fSArun Ramadoss static void lan937x_set_tune_adj(struct ksz_device *dev, int port,
371b19ac41fSArun Ramadoss 				 u16 reg, u8 val)
372b19ac41fSArun Ramadoss {
373b19ac41fSArun Ramadoss 	u16 data16;
374b19ac41fSArun Ramadoss 
375b19ac41fSArun Ramadoss 	ksz_pread16(dev, port, reg, &data16);
376b19ac41fSArun Ramadoss 
377b19ac41fSArun Ramadoss 	/* Update tune Adjust */
378b19ac41fSArun Ramadoss 	data16 |= FIELD_PREP(PORT_TUNE_ADJ, val);
379b19ac41fSArun Ramadoss 	ksz_pwrite16(dev, port, reg, data16);
380b19ac41fSArun Ramadoss 
381b19ac41fSArun Ramadoss 	/* write DLL reset to take effect */
382b19ac41fSArun Ramadoss 	data16 |= PORT_DLL_RESET;
383b19ac41fSArun Ramadoss 	ksz_pwrite16(dev, port, reg, data16);
384b19ac41fSArun Ramadoss }
385b19ac41fSArun Ramadoss 
386b19ac41fSArun Ramadoss static void lan937x_set_rgmii_tx_delay(struct ksz_device *dev, int port)
387b19ac41fSArun Ramadoss {
388b19ac41fSArun Ramadoss 	u8 val;
389b19ac41fSArun Ramadoss 
390b19ac41fSArun Ramadoss 	/* Apply different codes based on the ports as per characterization
391b19ac41fSArun Ramadoss 	 * results
392b19ac41fSArun Ramadoss 	 */
393b19ac41fSArun Ramadoss 	val = (port == LAN937X_RGMII_1_PORT) ? RGMII_1_TX_DELAY_2NS :
394b19ac41fSArun Ramadoss 		RGMII_2_TX_DELAY_2NS;
395b19ac41fSArun Ramadoss 
396b19ac41fSArun Ramadoss 	lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_5, val);
397b19ac41fSArun Ramadoss }
398b19ac41fSArun Ramadoss 
399b19ac41fSArun Ramadoss static void lan937x_set_rgmii_rx_delay(struct ksz_device *dev, int port)
400b19ac41fSArun Ramadoss {
401b19ac41fSArun Ramadoss 	u8 val;
402b19ac41fSArun Ramadoss 
403b19ac41fSArun Ramadoss 	val = (port == LAN937X_RGMII_1_PORT) ? RGMII_1_RX_DELAY_2NS :
404b19ac41fSArun Ramadoss 		RGMII_2_RX_DELAY_2NS;
405b19ac41fSArun Ramadoss 
406b19ac41fSArun Ramadoss 	lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_4, val);
407b19ac41fSArun Ramadoss }
408b19ac41fSArun Ramadoss 
409c14e878dSArun Ramadoss void lan937x_phylink_get_caps(struct ksz_device *dev, int port,
410c14e878dSArun Ramadoss 			      struct phylink_config *config)
411c14e878dSArun Ramadoss {
412c14e878dSArun Ramadoss 	config->mac_capabilities = MAC_100FD;
413c14e878dSArun Ramadoss 
414c14e878dSArun Ramadoss 	if (dev->info->supports_rgmii[port]) {
415c14e878dSArun Ramadoss 		/* MII/RMII/RGMII ports */
416c14e878dSArun Ramadoss 		config->mac_capabilities |= MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
417c14e878dSArun Ramadoss 					    MAC_100HD | MAC_10 | MAC_1000FD;
418c14e878dSArun Ramadoss 	}
419c14e878dSArun Ramadoss }
420c14e878dSArun Ramadoss 
421b19ac41fSArun Ramadoss void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port)
422b19ac41fSArun Ramadoss {
423b19ac41fSArun Ramadoss 	struct ksz_port *p = &dev->ports[port];
424b19ac41fSArun Ramadoss 
425b19ac41fSArun Ramadoss 	if (p->rgmii_tx_val) {
426b19ac41fSArun Ramadoss 		lan937x_set_rgmii_tx_delay(dev, port);
427b19ac41fSArun Ramadoss 		dev_info(dev->dev, "Applied rgmii tx delay for the port %d\n",
428b19ac41fSArun Ramadoss 			 port);
429b19ac41fSArun Ramadoss 	}
430b19ac41fSArun Ramadoss 
431b19ac41fSArun Ramadoss 	if (p->rgmii_rx_val) {
432b19ac41fSArun Ramadoss 		lan937x_set_rgmii_rx_delay(dev, port);
433b19ac41fSArun Ramadoss 		dev_info(dev->dev, "Applied rgmii rx delay for the port %d\n",
434b19ac41fSArun Ramadoss 			 port);
435b19ac41fSArun Ramadoss 	}
436b19ac41fSArun Ramadoss }
437b19ac41fSArun Ramadoss 
438*c9cd961cSArun Ramadoss int lan937x_switch_init(struct ksz_device *dev)
439*c9cd961cSArun Ramadoss {
440*c9cd961cSArun Ramadoss 	dev->port_mask = (1 << dev->info->port_cnt) - 1;
441*c9cd961cSArun Ramadoss 
442*c9cd961cSArun Ramadoss 	return 0;
443*c9cd961cSArun Ramadoss }
444*c9cd961cSArun Ramadoss 
445*c9cd961cSArun Ramadoss static void lan937x_girq_mask(struct irq_data *d)
446*c9cd961cSArun Ramadoss {
447*c9cd961cSArun Ramadoss 	struct ksz_device *dev = irq_data_get_irq_chip_data(d);
448*c9cd961cSArun Ramadoss 	unsigned int n = d->hwirq;
449*c9cd961cSArun Ramadoss 
450*c9cd961cSArun Ramadoss 	dev->girq.masked |= (1 << n);
451*c9cd961cSArun Ramadoss }
452*c9cd961cSArun Ramadoss 
453*c9cd961cSArun Ramadoss static void lan937x_girq_unmask(struct irq_data *d)
454*c9cd961cSArun Ramadoss {
455*c9cd961cSArun Ramadoss 	struct ksz_device *dev = irq_data_get_irq_chip_data(d);
456*c9cd961cSArun Ramadoss 	unsigned int n = d->hwirq;
457*c9cd961cSArun Ramadoss 
458*c9cd961cSArun Ramadoss 	dev->girq.masked &= ~(1 << n);
459*c9cd961cSArun Ramadoss }
460*c9cd961cSArun Ramadoss 
461*c9cd961cSArun Ramadoss static void lan937x_girq_bus_lock(struct irq_data *d)
462*c9cd961cSArun Ramadoss {
463*c9cd961cSArun Ramadoss 	struct ksz_device *dev = irq_data_get_irq_chip_data(d);
464*c9cd961cSArun Ramadoss 
465*c9cd961cSArun Ramadoss 	mutex_lock(&dev->lock_irq);
466*c9cd961cSArun Ramadoss }
467*c9cd961cSArun Ramadoss 
468*c9cd961cSArun Ramadoss static void lan937x_girq_bus_sync_unlock(struct irq_data *d)
469*c9cd961cSArun Ramadoss {
470*c9cd961cSArun Ramadoss 	struct ksz_device *dev = irq_data_get_irq_chip_data(d);
471*c9cd961cSArun Ramadoss 	int ret;
472*c9cd961cSArun Ramadoss 
473*c9cd961cSArun Ramadoss 	ret = ksz_write32(dev, REG_SW_PORT_INT_MASK__4, dev->girq.masked);
474*c9cd961cSArun Ramadoss 	if (ret)
475*c9cd961cSArun Ramadoss 		dev_err(dev->dev, "failed to change IRQ mask\n");
476*c9cd961cSArun Ramadoss 
477*c9cd961cSArun Ramadoss 	mutex_unlock(&dev->lock_irq);
478*c9cd961cSArun Ramadoss }
479*c9cd961cSArun Ramadoss 
480*c9cd961cSArun Ramadoss static const struct irq_chip lan937x_girq_chip = {
481*c9cd961cSArun Ramadoss 	.name			= "lan937x-global",
482*c9cd961cSArun Ramadoss 	.irq_mask		= lan937x_girq_mask,
483*c9cd961cSArun Ramadoss 	.irq_unmask		= lan937x_girq_unmask,
484*c9cd961cSArun Ramadoss 	.irq_bus_lock		= lan937x_girq_bus_lock,
485*c9cd961cSArun Ramadoss 	.irq_bus_sync_unlock	= lan937x_girq_bus_sync_unlock,
486*c9cd961cSArun Ramadoss };
487*c9cd961cSArun Ramadoss 
488*c9cd961cSArun Ramadoss static int lan937x_girq_domain_map(struct irq_domain *d,
489*c9cd961cSArun Ramadoss 				   unsigned int irq, irq_hw_number_t hwirq)
490*c9cd961cSArun Ramadoss {
491*c9cd961cSArun Ramadoss 	struct ksz_device *dev = d->host_data;
492*c9cd961cSArun Ramadoss 
493*c9cd961cSArun Ramadoss 	irq_set_chip_data(irq, d->host_data);
494*c9cd961cSArun Ramadoss 	irq_set_chip_and_handler(irq, &dev->girq.chip, handle_level_irq);
495*c9cd961cSArun Ramadoss 	irq_set_noprobe(irq);
496*c9cd961cSArun Ramadoss 
497*c9cd961cSArun Ramadoss 	return 0;
498*c9cd961cSArun Ramadoss }
499*c9cd961cSArun Ramadoss 
500*c9cd961cSArun Ramadoss static const struct irq_domain_ops lan937x_girq_domain_ops = {
501*c9cd961cSArun Ramadoss 	.map	= lan937x_girq_domain_map,
502*c9cd961cSArun Ramadoss 	.xlate	= irq_domain_xlate_twocell,
503*c9cd961cSArun Ramadoss };
504*c9cd961cSArun Ramadoss 
505*c9cd961cSArun Ramadoss static void lan937x_girq_free(struct ksz_device *dev)
506*c9cd961cSArun Ramadoss {
507*c9cd961cSArun Ramadoss 	int irq, virq;
508*c9cd961cSArun Ramadoss 
509*c9cd961cSArun Ramadoss 	free_irq(dev->irq, dev);
510*c9cd961cSArun Ramadoss 
511*c9cd961cSArun Ramadoss 	for (irq = 0; irq < dev->girq.nirqs; irq++) {
512*c9cd961cSArun Ramadoss 		virq = irq_find_mapping(dev->girq.domain, irq);
513*c9cd961cSArun Ramadoss 		irq_dispose_mapping(virq);
514*c9cd961cSArun Ramadoss 	}
515*c9cd961cSArun Ramadoss 
516*c9cd961cSArun Ramadoss 	irq_domain_remove(dev->girq.domain);
517*c9cd961cSArun Ramadoss }
518*c9cd961cSArun Ramadoss 
519*c9cd961cSArun Ramadoss static irqreturn_t lan937x_girq_thread_fn(int irq, void *dev_id)
520*c9cd961cSArun Ramadoss {
521*c9cd961cSArun Ramadoss 	struct ksz_device *dev = dev_id;
522*c9cd961cSArun Ramadoss 	unsigned int nhandled = 0;
523*c9cd961cSArun Ramadoss 	unsigned int sub_irq;
524*c9cd961cSArun Ramadoss 	unsigned int n;
525*c9cd961cSArun Ramadoss 	u32 data;
526*c9cd961cSArun Ramadoss 	int ret;
527*c9cd961cSArun Ramadoss 
528*c9cd961cSArun Ramadoss 	/* Read global interrupt status register */
529*c9cd961cSArun Ramadoss 	ret = ksz_read32(dev, REG_SW_PORT_INT_STATUS__4, &data);
530*c9cd961cSArun Ramadoss 	if (ret)
531*c9cd961cSArun Ramadoss 		goto out;
532*c9cd961cSArun Ramadoss 
533*c9cd961cSArun Ramadoss 	for (n = 0; n < dev->girq.nirqs; ++n) {
534*c9cd961cSArun Ramadoss 		if (data & (1 << n)) {
535*c9cd961cSArun Ramadoss 			sub_irq = irq_find_mapping(dev->girq.domain, n);
536*c9cd961cSArun Ramadoss 			handle_nested_irq(sub_irq);
537*c9cd961cSArun Ramadoss 			++nhandled;
538*c9cd961cSArun Ramadoss 		}
539*c9cd961cSArun Ramadoss 	}
540*c9cd961cSArun Ramadoss out:
541*c9cd961cSArun Ramadoss 	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
542*c9cd961cSArun Ramadoss }
543*c9cd961cSArun Ramadoss 
544*c9cd961cSArun Ramadoss static int lan937x_girq_setup(struct ksz_device *dev)
545*c9cd961cSArun Ramadoss {
546*c9cd961cSArun Ramadoss 	int ret, irq;
547*c9cd961cSArun Ramadoss 
548*c9cd961cSArun Ramadoss 	dev->girq.nirqs = dev->info->port_cnt;
549*c9cd961cSArun Ramadoss 	dev->girq.domain = irq_domain_add_simple(NULL, dev->girq.nirqs, 0,
550*c9cd961cSArun Ramadoss 						 &lan937x_girq_domain_ops, dev);
551*c9cd961cSArun Ramadoss 	if (!dev->girq.domain)
552*c9cd961cSArun Ramadoss 		return -ENOMEM;
553*c9cd961cSArun Ramadoss 
554*c9cd961cSArun Ramadoss 	for (irq = 0; irq < dev->girq.nirqs; irq++)
555*c9cd961cSArun Ramadoss 		irq_create_mapping(dev->girq.domain, irq);
556*c9cd961cSArun Ramadoss 
557*c9cd961cSArun Ramadoss 	dev->girq.chip = lan937x_girq_chip;
558*c9cd961cSArun Ramadoss 	dev->girq.masked = ~0;
559*c9cd961cSArun Ramadoss 
560*c9cd961cSArun Ramadoss 	ret = request_threaded_irq(dev->irq, NULL, lan937x_girq_thread_fn,
561*c9cd961cSArun Ramadoss 				   IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
562*c9cd961cSArun Ramadoss 				   dev_name(dev->dev), dev);
563*c9cd961cSArun Ramadoss 	if (ret)
564*c9cd961cSArun Ramadoss 		goto out;
565*c9cd961cSArun Ramadoss 
566*c9cd961cSArun Ramadoss 	return 0;
567*c9cd961cSArun Ramadoss 
568*c9cd961cSArun Ramadoss out:
569*c9cd961cSArun Ramadoss 	lan937x_girq_free(dev);
570*c9cd961cSArun Ramadoss 
571*c9cd961cSArun Ramadoss 	return ret;
572*c9cd961cSArun Ramadoss }
573*c9cd961cSArun Ramadoss 
574*c9cd961cSArun Ramadoss static void lan937x_pirq_mask(struct irq_data *d)
575*c9cd961cSArun Ramadoss {
576*c9cd961cSArun Ramadoss 	struct ksz_port *port = irq_data_get_irq_chip_data(d);
577*c9cd961cSArun Ramadoss 	unsigned int n = d->hwirq;
578*c9cd961cSArun Ramadoss 
579*c9cd961cSArun Ramadoss 	port->pirq.masked |= (1 << n);
580*c9cd961cSArun Ramadoss }
581*c9cd961cSArun Ramadoss 
582*c9cd961cSArun Ramadoss static void lan937x_pirq_unmask(struct irq_data *d)
583*c9cd961cSArun Ramadoss {
584*c9cd961cSArun Ramadoss 	struct ksz_port *port = irq_data_get_irq_chip_data(d);
585*c9cd961cSArun Ramadoss 	unsigned int n = d->hwirq;
586*c9cd961cSArun Ramadoss 
587*c9cd961cSArun Ramadoss 	port->pirq.masked &= ~(1 << n);
588*c9cd961cSArun Ramadoss }
589*c9cd961cSArun Ramadoss 
590*c9cd961cSArun Ramadoss static void lan937x_pirq_bus_lock(struct irq_data *d)
591*c9cd961cSArun Ramadoss {
592*c9cd961cSArun Ramadoss 	struct ksz_port *port = irq_data_get_irq_chip_data(d);
593*c9cd961cSArun Ramadoss 	struct ksz_device *dev = port->ksz_dev;
594*c9cd961cSArun Ramadoss 
595*c9cd961cSArun Ramadoss 	mutex_lock(&dev->lock_irq);
596*c9cd961cSArun Ramadoss }
597*c9cd961cSArun Ramadoss 
598*c9cd961cSArun Ramadoss static void lan937x_pirq_bus_sync_unlock(struct irq_data *d)
599*c9cd961cSArun Ramadoss {
600*c9cd961cSArun Ramadoss 	struct ksz_port *port = irq_data_get_irq_chip_data(d);
601*c9cd961cSArun Ramadoss 	struct ksz_device *dev = port->ksz_dev;
602*c9cd961cSArun Ramadoss 
603*c9cd961cSArun Ramadoss 	ksz_pwrite8(dev, port->num, REG_PORT_INT_MASK, port->pirq.masked);
604*c9cd961cSArun Ramadoss 	mutex_unlock(&dev->lock_irq);
605*c9cd961cSArun Ramadoss }
606*c9cd961cSArun Ramadoss 
607*c9cd961cSArun Ramadoss static const struct irq_chip lan937x_pirq_chip = {
608*c9cd961cSArun Ramadoss 	.name			= "lan937x-port",
609*c9cd961cSArun Ramadoss 	.irq_mask		= lan937x_pirq_mask,
610*c9cd961cSArun Ramadoss 	.irq_unmask		= lan937x_pirq_unmask,
611*c9cd961cSArun Ramadoss 	.irq_bus_lock		= lan937x_pirq_bus_lock,
612*c9cd961cSArun Ramadoss 	.irq_bus_sync_unlock	= lan937x_pirq_bus_sync_unlock,
613*c9cd961cSArun Ramadoss };
614*c9cd961cSArun Ramadoss 
615*c9cd961cSArun Ramadoss static int lan937x_pirq_domain_map(struct irq_domain *d, unsigned int irq,
616*c9cd961cSArun Ramadoss 				   irq_hw_number_t hwirq)
617*c9cd961cSArun Ramadoss {
618*c9cd961cSArun Ramadoss 	struct ksz_port *port = d->host_data;
619*c9cd961cSArun Ramadoss 
620*c9cd961cSArun Ramadoss 	irq_set_chip_data(irq, d->host_data);
621*c9cd961cSArun Ramadoss 	irq_set_chip_and_handler(irq, &port->pirq.chip, handle_level_irq);
622*c9cd961cSArun Ramadoss 	irq_set_noprobe(irq);
623*c9cd961cSArun Ramadoss 
624*c9cd961cSArun Ramadoss 	return 0;
625*c9cd961cSArun Ramadoss }
626*c9cd961cSArun Ramadoss 
627*c9cd961cSArun Ramadoss static const struct irq_domain_ops lan937x_pirq_domain_ops = {
628*c9cd961cSArun Ramadoss 	.map	= lan937x_pirq_domain_map,
629*c9cd961cSArun Ramadoss 	.xlate	= irq_domain_xlate_twocell,
630*c9cd961cSArun Ramadoss };
631*c9cd961cSArun Ramadoss 
632*c9cd961cSArun Ramadoss static void lan937x_pirq_free(struct ksz_device *dev, u8 p)
633*c9cd961cSArun Ramadoss {
634*c9cd961cSArun Ramadoss 	struct ksz_port *port = &dev->ports[p];
635*c9cd961cSArun Ramadoss 	int irq, virq;
636*c9cd961cSArun Ramadoss 	int irq_num;
637*c9cd961cSArun Ramadoss 
638*c9cd961cSArun Ramadoss 	irq_num = irq_find_mapping(dev->girq.domain, p);
639*c9cd961cSArun Ramadoss 	if (irq_num < 0)
640*c9cd961cSArun Ramadoss 		return;
641*c9cd961cSArun Ramadoss 
642*c9cd961cSArun Ramadoss 	free_irq(irq_num, port);
643*c9cd961cSArun Ramadoss 
644*c9cd961cSArun Ramadoss 	for (irq = 0; irq < port->pirq.nirqs; irq++) {
645*c9cd961cSArun Ramadoss 		virq = irq_find_mapping(port->pirq.domain, irq);
646*c9cd961cSArun Ramadoss 		irq_dispose_mapping(virq);
647*c9cd961cSArun Ramadoss 	}
648*c9cd961cSArun Ramadoss 
649*c9cd961cSArun Ramadoss 	irq_domain_remove(port->pirq.domain);
650*c9cd961cSArun Ramadoss }
651*c9cd961cSArun Ramadoss 
652*c9cd961cSArun Ramadoss static irqreturn_t lan937x_pirq_thread_fn(int irq, void *dev_id)
653*c9cd961cSArun Ramadoss {
654*c9cd961cSArun Ramadoss 	struct ksz_port *port = dev_id;
655*c9cd961cSArun Ramadoss 	unsigned int nhandled = 0;
656*c9cd961cSArun Ramadoss 	struct ksz_device *dev;
657*c9cd961cSArun Ramadoss 	unsigned int sub_irq;
658*c9cd961cSArun Ramadoss 	unsigned int n;
659*c9cd961cSArun Ramadoss 	u8 data;
660*c9cd961cSArun Ramadoss 
661*c9cd961cSArun Ramadoss 	dev = port->ksz_dev;
662*c9cd961cSArun Ramadoss 
663*c9cd961cSArun Ramadoss 	/* Read port interrupt status register */
664*c9cd961cSArun Ramadoss 	ksz_pread8(dev, port->num, REG_PORT_INT_STATUS, &data);
665*c9cd961cSArun Ramadoss 
666*c9cd961cSArun Ramadoss 	for (n = 0; n < port->pirq.nirqs; ++n) {
667*c9cd961cSArun Ramadoss 		if (data & (1 << n)) {
668*c9cd961cSArun Ramadoss 			sub_irq = irq_find_mapping(port->pirq.domain, n);
669*c9cd961cSArun Ramadoss 			handle_nested_irq(sub_irq);
670*c9cd961cSArun Ramadoss 			++nhandled;
671*c9cd961cSArun Ramadoss 		}
672*c9cd961cSArun Ramadoss 	}
673*c9cd961cSArun Ramadoss 
674*c9cd961cSArun Ramadoss 	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
675*c9cd961cSArun Ramadoss }
676*c9cd961cSArun Ramadoss 
677*c9cd961cSArun Ramadoss static int lan937x_pirq_setup(struct ksz_device *dev, u8 p)
678*c9cd961cSArun Ramadoss {
679*c9cd961cSArun Ramadoss 	struct ksz_port *port = &dev->ports[p];
680*c9cd961cSArun Ramadoss 	int ret, irq;
681*c9cd961cSArun Ramadoss 	int irq_num;
682*c9cd961cSArun Ramadoss 
683*c9cd961cSArun Ramadoss 	port->pirq.nirqs = LAN937x_PNIRQS;
684*c9cd961cSArun Ramadoss 	port->pirq.domain = irq_domain_add_simple(dev->dev->of_node,
685*c9cd961cSArun Ramadoss 						  port->pirq.nirqs, 0,
686*c9cd961cSArun Ramadoss 						  &lan937x_pirq_domain_ops,
687*c9cd961cSArun Ramadoss 						  port);
688*c9cd961cSArun Ramadoss 	if (!port->pirq.domain)
689*c9cd961cSArun Ramadoss 		return -ENOMEM;
690*c9cd961cSArun Ramadoss 
691*c9cd961cSArun Ramadoss 	for (irq = 0; irq < port->pirq.nirqs; irq++)
692*c9cd961cSArun Ramadoss 		irq_create_mapping(port->pirq.domain, irq);
693*c9cd961cSArun Ramadoss 
694*c9cd961cSArun Ramadoss 	port->pirq.chip = lan937x_pirq_chip;
695*c9cd961cSArun Ramadoss 	port->pirq.masked = ~0;
696*c9cd961cSArun Ramadoss 
697*c9cd961cSArun Ramadoss 	irq_num = irq_find_mapping(dev->girq.domain, p);
698*c9cd961cSArun Ramadoss 	if (irq_num < 0)
699*c9cd961cSArun Ramadoss 		return irq_num;
700*c9cd961cSArun Ramadoss 
701*c9cd961cSArun Ramadoss 	snprintf(port->pirq.name, sizeof(port->pirq.name), "port_irq-%d", p);
702*c9cd961cSArun Ramadoss 
703*c9cd961cSArun Ramadoss 	ret = request_threaded_irq(irq_num, NULL, lan937x_pirq_thread_fn,
704*c9cd961cSArun Ramadoss 				   IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
705*c9cd961cSArun Ramadoss 				   port->pirq.name, port);
706*c9cd961cSArun Ramadoss 	if (ret)
707*c9cd961cSArun Ramadoss 		goto out;
708*c9cd961cSArun Ramadoss 
709*c9cd961cSArun Ramadoss 	return 0;
710*c9cd961cSArun Ramadoss 
711*c9cd961cSArun Ramadoss out:
712*c9cd961cSArun Ramadoss 	lan937x_pirq_free(dev, p);
713*c9cd961cSArun Ramadoss 
714*c9cd961cSArun Ramadoss 	return ret;
715*c9cd961cSArun Ramadoss }
716*c9cd961cSArun Ramadoss 
71755ab6ffaSArun Ramadoss int lan937x_setup(struct dsa_switch *ds)
71855ab6ffaSArun Ramadoss {
71955ab6ffaSArun Ramadoss 	struct ksz_device *dev = ds->priv;
720*c9cd961cSArun Ramadoss 	struct dsa_port *dp;
721ffaf1de2SArun Ramadoss 	int ret;
722ffaf1de2SArun Ramadoss 
723ffaf1de2SArun Ramadoss 	/* enable Indirect Access from SPI to the VPHY registers */
724ffaf1de2SArun Ramadoss 	ret = lan937x_enable_spi_indirect_access(dev);
725ffaf1de2SArun Ramadoss 	if (ret < 0) {
726ffaf1de2SArun Ramadoss 		dev_err(dev->dev, "failed to enable spi indirect access");
727ffaf1de2SArun Ramadoss 		return ret;
728ffaf1de2SArun Ramadoss 	}
72955ab6ffaSArun Ramadoss 
730*c9cd961cSArun Ramadoss 	if (dev->irq > 0) {
731*c9cd961cSArun Ramadoss 		ret = lan937x_girq_setup(dev);
732*c9cd961cSArun Ramadoss 		if (ret)
733*c9cd961cSArun Ramadoss 			return ret;
734*c9cd961cSArun Ramadoss 
735*c9cd961cSArun Ramadoss 		dsa_switch_for_each_user_port(dp, dev->ds) {
736*c9cd961cSArun Ramadoss 			ret = lan937x_pirq_setup(dev, dp->index);
737*c9cd961cSArun Ramadoss 			if (ret)
738*c9cd961cSArun Ramadoss 				goto out_girq;
739*c9cd961cSArun Ramadoss 		}
740*c9cd961cSArun Ramadoss 	}
741*c9cd961cSArun Ramadoss 
742a50b3536SArun Ramadoss 	ret = lan937x_mdio_register(dev);
743a50b3536SArun Ramadoss 	if (ret < 0) {
744a50b3536SArun Ramadoss 		dev_err(dev->dev, "failed to register the mdio");
745*c9cd961cSArun Ramadoss 		goto out_pirq;
746a50b3536SArun Ramadoss 	}
747a50b3536SArun Ramadoss 
74855ab6ffaSArun Ramadoss 	/* The VLAN aware is a global setting. Mixed vlan
74955ab6ffaSArun Ramadoss 	 * filterings are not supported.
75055ab6ffaSArun Ramadoss 	 */
75155ab6ffaSArun Ramadoss 	ds->vlan_filtering_is_global = true;
75255ab6ffaSArun Ramadoss 
75355ab6ffaSArun Ramadoss 	/* Enable aggressive back off for half duplex & UNH mode */
75455ab6ffaSArun Ramadoss 	lan937x_cfg(dev, REG_SW_MAC_CTRL_0,
75555ab6ffaSArun Ramadoss 		    (SW_PAUSE_UNH_MODE | SW_NEW_BACKOFF | SW_AGGR_BACKOFF),
75655ab6ffaSArun Ramadoss 		    true);
75755ab6ffaSArun Ramadoss 
75855ab6ffaSArun Ramadoss 	/* If NO_EXC_COLLISION_DROP bit is set, the switch will not drop
75955ab6ffaSArun Ramadoss 	 * packets when 16 or more collisions occur
76055ab6ffaSArun Ramadoss 	 */
76155ab6ffaSArun Ramadoss 	lan937x_cfg(dev, REG_SW_MAC_CTRL_1, NO_EXC_COLLISION_DROP, true);
76255ab6ffaSArun Ramadoss 
76355ab6ffaSArun Ramadoss 	/* enable global MIB counter freeze function */
76455ab6ffaSArun Ramadoss 	lan937x_cfg(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FREEZE, true);
76555ab6ffaSArun Ramadoss 
76655ab6ffaSArun Ramadoss 	/* disable CLK125 & CLK25, 1: disable, 0: enable */
76755ab6ffaSArun Ramadoss 	lan937x_cfg(dev, REG_SW_GLOBAL_OUTPUT_CTRL__1,
76855ab6ffaSArun Ramadoss 		    (SW_CLK125_ENB | SW_CLK25_ENB), true);
76955ab6ffaSArun Ramadoss 
77055ab6ffaSArun Ramadoss 	return 0;
771*c9cd961cSArun Ramadoss 
772*c9cd961cSArun Ramadoss out_pirq:
773*c9cd961cSArun Ramadoss 	if (dev->irq > 0)
774*c9cd961cSArun Ramadoss 		dsa_switch_for_each_user_port(dp, dev->ds)
775*c9cd961cSArun Ramadoss 			lan937x_pirq_free(dev, dp->index);
776*c9cd961cSArun Ramadoss out_girq:
777*c9cd961cSArun Ramadoss 	if (dev->irq > 0)
778*c9cd961cSArun Ramadoss 		lan937x_girq_free(dev);
779*c9cd961cSArun Ramadoss 
780*c9cd961cSArun Ramadoss 	return ret;
78155ab6ffaSArun Ramadoss }
78255ab6ffaSArun Ramadoss 
783*c9cd961cSArun Ramadoss void lan937x_teardown(struct dsa_switch *ds)
78455ab6ffaSArun Ramadoss {
785*c9cd961cSArun Ramadoss 	struct ksz_device *dev = ds->priv;
786*c9cd961cSArun Ramadoss 	struct dsa_port *dp;
78755ab6ffaSArun Ramadoss 
788*c9cd961cSArun Ramadoss 	if (dev->irq > 0) {
789*c9cd961cSArun Ramadoss 		dsa_switch_for_each_user_port(dp, dev->ds)
790*c9cd961cSArun Ramadoss 			lan937x_pirq_free(dev, dp->index);
791*c9cd961cSArun Ramadoss 
792*c9cd961cSArun Ramadoss 		lan937x_girq_free(dev);
793*c9cd961cSArun Ramadoss 	}
79455ab6ffaSArun Ramadoss }
79555ab6ffaSArun Ramadoss 
79655ab6ffaSArun Ramadoss void lan937x_switch_exit(struct ksz_device *dev)
79755ab6ffaSArun Ramadoss {
79855ab6ffaSArun Ramadoss 	lan937x_reset_switch(dev);
79955ab6ffaSArun Ramadoss }
80055ab6ffaSArun Ramadoss 
80155ab6ffaSArun Ramadoss MODULE_AUTHOR("Arun Ramadoss <arun.ramadoss@microchip.com>");
80255ab6ffaSArun Ramadoss MODULE_DESCRIPTION("Microchip LAN937x Series Switch DSA Driver");
80355ab6ffaSArun Ramadoss MODULE_LICENSE("GPL");
804