• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /* Microchip LAN937X switch driver main logic
3  * Copyright (C) 2019-2024 Microchip Technology Inc.
4  */
5 #include <linux/kernel.h>
6 #include <linux/module.h>
7 #include <linux/iopoll.h>
8 #include <linux/phy.h>
9 #include <linux/of_net.h>
10 #include <linux/if_bridge.h>
11 #include <linux/if_vlan.h>
12 #include <linux/math.h>
13 #include <net/dsa.h>
14 #include <net/switchdev.h>
15 
16 #include "lan937x_reg.h"
17 #include "ksz_common.h"
18 #include "ksz9477.h"
19 #include "lan937x.h"
20 
lan937x_cfg(struct ksz_device * dev,u32 addr,u8 bits,bool set)21 static int lan937x_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
22 {
23 	return regmap_update_bits(ksz_regmap_8(dev), addr, bits, set ? bits : 0);
24 }
25 
lan937x_port_cfg(struct ksz_device * dev,int port,int offset,u8 bits,bool set)26 static int lan937x_port_cfg(struct ksz_device *dev, int port, int offset,
27 			    u8 bits, bool set)
28 {
29 	return regmap_update_bits(ksz_regmap_8(dev), PORT_CTRL_ADDR(port, offset),
30 				  bits, set ? bits : 0);
31 }
32 
lan937x_enable_spi_indirect_access(struct ksz_device * dev)33 static int lan937x_enable_spi_indirect_access(struct ksz_device *dev)
34 {
35 	u16 data16;
36 	int ret;
37 
38 	/* Enable Phy access through SPI */
39 	ret = lan937x_cfg(dev, REG_GLOBAL_CTRL_0, SW_PHY_REG_BLOCK, false);
40 	if (ret < 0)
41 		return ret;
42 
43 	ret = ksz_read16(dev, REG_VPHY_SPECIAL_CTRL__2, &data16);
44 	if (ret < 0)
45 		return ret;
46 
47 	/* Allow SPI access */
48 	data16 |= VPHY_SPI_INDIRECT_ENABLE;
49 
50 	return ksz_write16(dev, REG_VPHY_SPECIAL_CTRL__2, data16);
51 }
52 
lan937x_vphy_ind_addr_wr(struct ksz_device * dev,int addr,int reg)53 static int lan937x_vphy_ind_addr_wr(struct ksz_device *dev, int addr, int reg)
54 {
55 	u16 addr_base = REG_PORT_T1_PHY_CTRL_BASE;
56 	u16 temp;
57 
58 	if (is_lan937x_tx_phy(dev, addr))
59 		addr_base = REG_PORT_TX_PHY_CTRL_BASE;
60 
61 	/* get register address based on the logical port */
62 	temp = PORT_CTRL_ADDR(addr, (addr_base + (reg << 2)));
63 
64 	return ksz_write16(dev, REG_VPHY_IND_ADDR__2, temp);
65 }
66 
lan937x_internal_phy_write(struct ksz_device * dev,int addr,int reg,u16 val)67 static int lan937x_internal_phy_write(struct ksz_device *dev, int addr, int reg,
68 				      u16 val)
69 {
70 	unsigned int value;
71 	int ret;
72 
73 	/* Check for internal phy port */
74 	if (!dev->info->internal_phy[addr])
75 		return -EOPNOTSUPP;
76 
77 	ret = lan937x_vphy_ind_addr_wr(dev, addr, reg);
78 	if (ret < 0)
79 		return ret;
80 
81 	/* Write the data to be written to the VPHY reg */
82 	ret = ksz_write16(dev, REG_VPHY_IND_DATA__2, val);
83 	if (ret < 0)
84 		return ret;
85 
86 	/* Write the Write En and Busy bit */
87 	ret = ksz_write16(dev, REG_VPHY_IND_CTRL__2,
88 			  (VPHY_IND_WRITE | VPHY_IND_BUSY));
89 	if (ret < 0)
90 		return ret;
91 
92 	ret = regmap_read_poll_timeout(ksz_regmap_16(dev), REG_VPHY_IND_CTRL__2,
93 				       value, !(value & VPHY_IND_BUSY), 10,
94 				       1000);
95 	if (ret < 0) {
96 		dev_err(dev->dev, "Failed to write phy register\n");
97 		return ret;
98 	}
99 
100 	return 0;
101 }
102 
lan937x_internal_phy_read(struct ksz_device * dev,int addr,int reg,u16 * val)103 static int lan937x_internal_phy_read(struct ksz_device *dev, int addr, int reg,
104 				     u16 *val)
105 {
106 	unsigned int value;
107 	int ret;
108 
109 	/* Check for internal phy port, return 0xffff for non-existent phy */
110 	if (!dev->info->internal_phy[addr])
111 		return 0xffff;
112 
113 	ret = lan937x_vphy_ind_addr_wr(dev, addr, reg);
114 	if (ret < 0)
115 		return ret;
116 
117 	/* Write Read and Busy bit to start the transaction */
118 	ret = ksz_write16(dev, REG_VPHY_IND_CTRL__2, VPHY_IND_BUSY);
119 	if (ret < 0)
120 		return ret;
121 
122 	ret = regmap_read_poll_timeout(ksz_regmap_16(dev), REG_VPHY_IND_CTRL__2,
123 				       value, !(value & VPHY_IND_BUSY), 10,
124 				       1000);
125 	if (ret < 0) {
126 		dev_err(dev->dev, "Failed to read phy register\n");
127 		return ret;
128 	}
129 
130 	/* Read the VPHY register which has the PHY data */
131 	return ksz_read16(dev, REG_VPHY_IND_DATA__2, val);
132 }
133 
lan937x_r_phy(struct ksz_device * dev,u16 addr,u16 reg,u16 * data)134 int lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data)
135 {
136 	return lan937x_internal_phy_read(dev, addr, reg, data);
137 }
138 
lan937x_w_phy(struct ksz_device * dev,u16 addr,u16 reg,u16 val)139 int lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val)
140 {
141 	return lan937x_internal_phy_write(dev, addr, reg, val);
142 }
143 
lan937x_reset_switch(struct ksz_device * dev)144 int lan937x_reset_switch(struct ksz_device *dev)
145 {
146 	u32 data32;
147 	int ret;
148 
149 	/* reset switch */
150 	ret = lan937x_cfg(dev, REG_SW_OPERATION, SW_RESET, true);
151 	if (ret < 0)
152 		return ret;
153 
154 	/* Enable Auto Aging */
155 	ret = lan937x_cfg(dev, REG_SW_LUE_CTRL_1, SW_LINK_AUTO_AGING, true);
156 	if (ret < 0)
157 		return ret;
158 
159 	/* disable interrupts */
160 	ret = ksz_write32(dev, REG_SW_INT_MASK__4, SWITCH_INT_MASK);
161 	if (ret < 0)
162 		return ret;
163 
164 	ret = ksz_write32(dev, REG_SW_INT_STATUS__4, POR_READY_INT);
165 	if (ret < 0)
166 		return ret;
167 
168 	ret = ksz_write32(dev, REG_SW_PORT_INT_MASK__4, 0xFF);
169 	if (ret < 0)
170 		return ret;
171 
172 	return ksz_read32(dev, REG_SW_PORT_INT_STATUS__4, &data32);
173 }
174 
lan937x_port_setup(struct ksz_device * dev,int port,bool cpu_port)175 void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port)
176 {
177 	const u32 *masks = dev->info->masks;
178 	const u16 *regs = dev->info->regs;
179 	struct dsa_switch *ds = dev->ds;
180 	u8 member;
181 
182 	/* enable tag tail for host port */
183 	if (cpu_port)
184 		lan937x_port_cfg(dev, port, REG_PORT_CTRL_0,
185 				 PORT_TAIL_TAG_ENABLE, true);
186 
187 	/* Enable the Port Queue split */
188 	ksz9477_port_queue_split(dev, port);
189 
190 	/* set back pressure for half duplex */
191 	lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_1, PORT_BACK_PRESSURE,
192 			 true);
193 
194 	/* enable 802.1p priority */
195 	lan937x_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_PRIO_ENABLE, true);
196 
197 	if (!dev->info->internal_phy[port])
198 		lan937x_port_cfg(dev, port, regs[P_XMII_CTRL_0],
199 				 masks[P_MII_TX_FLOW_CTRL] |
200 				 masks[P_MII_RX_FLOW_CTRL],
201 				 true);
202 
203 	if (cpu_port)
204 		member = dsa_user_ports(ds);
205 	else
206 		member = BIT(dsa_upstream_port(ds, port));
207 
208 	dev->dev_ops->cfg_port_member(dev, port, member);
209 }
210 
lan937x_config_cpu_port(struct dsa_switch * ds)211 void lan937x_config_cpu_port(struct dsa_switch *ds)
212 {
213 	struct ksz_device *dev = ds->priv;
214 	struct dsa_port *dp;
215 
216 	dsa_switch_for_each_cpu_port(dp, ds) {
217 		if (dev->info->cpu_ports & (1 << dp->index)) {
218 			dev->cpu_port = dp->index;
219 
220 			/* enable cpu port */
221 			lan937x_port_setup(dev, dp->index, true);
222 		}
223 	}
224 
225 	dsa_switch_for_each_user_port(dp, ds) {
226 		ksz_port_stp_state_set(ds, dp->index, BR_STATE_DISABLED);
227 	}
228 }
229 
lan937x_change_mtu(struct ksz_device * dev,int port,int new_mtu)230 int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu)
231 {
232 	struct dsa_switch *ds = dev->ds;
233 	int ret;
234 
235 	new_mtu += VLAN_ETH_HLEN + ETH_FCS_LEN;
236 
237 	if (dsa_is_cpu_port(ds, port))
238 		new_mtu += LAN937X_TAG_LEN;
239 
240 	if (new_mtu >= FR_MIN_SIZE)
241 		ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0,
242 				       PORT_JUMBO_PACKET, true);
243 	else
244 		ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0,
245 				       PORT_JUMBO_PACKET, false);
246 	if (ret < 0) {
247 		dev_err(ds->dev, "failed to enable jumbo\n");
248 		return ret;
249 	}
250 
251 	/* Write the frame size in PORT_MAX_FR_SIZE register */
252 	ret = ksz_pwrite16(dev, port, PORT_MAX_FR_SIZE, new_mtu);
253 	if (ret) {
254 		dev_err(ds->dev, "failed to update mtu for port %d\n", port);
255 		return ret;
256 	}
257 
258 	return 0;
259 }
260 
lan937x_set_ageing_time(struct ksz_device * dev,unsigned int msecs)261 int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs)
262 {
263 	u8 data, mult, value8;
264 	bool in_msec = false;
265 	u32 max_val, value;
266 	u32 secs = msecs;
267 	int ret;
268 
269 #define MAX_TIMER_VAL	((1 << 20) - 1)
270 
271 	/* The aging timer comprises a 3-bit multiplier and a 20-bit second
272 	 * value.  Either of them cannot be zero.  The maximum timer is then
273 	 * 7 * 1048575 = 7340025 seconds.  As this value is too large for
274 	 * practical use it can be interpreted as microseconds, making the
275 	 * maximum timer 7340 seconds with finer control.  This allows for
276 	 * maximum 122 minutes compared to 29 minutes in KSZ9477 switch.
277 	 */
278 	if (msecs % 1000)
279 		in_msec = true;
280 	else
281 		secs /= 1000;
282 	if (!secs)
283 		secs = 1;
284 
285 	/* Return error if too large. */
286 	else if (secs > 7 * MAX_TIMER_VAL)
287 		return -EINVAL;
288 
289 	/* Configure how to interpret the number value. */
290 	ret = ksz_rmw8(dev, REG_SW_LUE_CTRL_2, SW_AGE_CNT_IN_MICROSEC,
291 		       in_msec ? SW_AGE_CNT_IN_MICROSEC : 0);
292 	if (ret < 0)
293 		return ret;
294 
295 	ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value8);
296 	if (ret < 0)
297 		return ret;
298 
299 	/* Check whether there is need to update the multiplier. */
300 	mult = FIELD_GET(SW_AGE_CNT_M, value8);
301 	max_val = MAX_TIMER_VAL;
302 	if (mult > 0) {
303 		/* Try to use the same multiplier already in the register as
304 		 * the hardware default uses multiplier 4 and 75 seconds for
305 		 * 300 seconds.
306 		 */
307 		max_val = DIV_ROUND_UP(secs, mult);
308 		if (max_val > MAX_TIMER_VAL || max_val * mult != secs)
309 			max_val = MAX_TIMER_VAL;
310 	}
311 
312 	data = DIV_ROUND_UP(secs, max_val);
313 	if (mult != data) {
314 		value8 &= ~SW_AGE_CNT_M;
315 		value8 |= FIELD_PREP(SW_AGE_CNT_M, data);
316 		ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value8);
317 		if (ret < 0)
318 			return ret;
319 	}
320 
321 	secs = DIV_ROUND_UP(secs, data);
322 
323 	value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs);
324 
325 	ret = ksz_write8(dev, REG_SW_AGE_PERIOD__1, value);
326 	if (ret < 0)
327 		return ret;
328 
329 	value = FIELD_GET(SW_AGE_PERIOD_19_8_M, secs);
330 
331 	return ksz_write16(dev, REG_SW_AGE_PERIOD__2, value);
332 }
333 
lan937x_set_tune_adj(struct ksz_device * dev,int port,u16 reg,u8 val)334 static void lan937x_set_tune_adj(struct ksz_device *dev, int port,
335 				 u16 reg, u8 val)
336 {
337 	u16 data16;
338 
339 	ksz_pread16(dev, port, reg, &data16);
340 
341 	/* Update tune Adjust */
342 	data16 |= FIELD_PREP(PORT_TUNE_ADJ, val);
343 	ksz_pwrite16(dev, port, reg, data16);
344 
345 	/* write DLL reset to take effect */
346 	data16 |= PORT_DLL_RESET;
347 	ksz_pwrite16(dev, port, reg, data16);
348 }
349 
lan937x_set_rgmii_tx_delay(struct ksz_device * dev,int port)350 static void lan937x_set_rgmii_tx_delay(struct ksz_device *dev, int port)
351 {
352 	u8 val;
353 
354 	/* Apply different codes based on the ports as per characterization
355 	 * results
356 	 */
357 	val = (port == LAN937X_RGMII_1_PORT) ? RGMII_1_TX_DELAY_2NS :
358 		RGMII_2_TX_DELAY_2NS;
359 
360 	lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_5, val);
361 }
362 
lan937x_set_rgmii_rx_delay(struct ksz_device * dev,int port)363 static void lan937x_set_rgmii_rx_delay(struct ksz_device *dev, int port)
364 {
365 	u8 val;
366 
367 	val = (port == LAN937X_RGMII_1_PORT) ? RGMII_1_RX_DELAY_2NS :
368 		RGMII_2_RX_DELAY_2NS;
369 
370 	lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_4, val);
371 }
372 
lan937x_phylink_get_caps(struct ksz_device * dev,int port,struct phylink_config * config)373 void lan937x_phylink_get_caps(struct ksz_device *dev, int port,
374 			      struct phylink_config *config)
375 {
376 	config->mac_capabilities = MAC_100FD;
377 
378 	if (dev->info->supports_rgmii[port]) {
379 		/* MII/RMII/RGMII ports */
380 		config->mac_capabilities |= MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
381 					    MAC_100HD | MAC_10 | MAC_1000FD;
382 	} else if (is_lan937x_tx_phy(dev, port)) {
383 		config->mac_capabilities |= MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
384 					    MAC_100HD | MAC_10;
385 	}
386 }
387 
lan937x_setup_rgmii_delay(struct ksz_device * dev,int port)388 void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port)
389 {
390 	struct ksz_port *p = &dev->ports[port];
391 
392 	if (p->rgmii_tx_val) {
393 		lan937x_set_rgmii_tx_delay(dev, port);
394 		dev_info(dev->dev, "Applied rgmii tx delay for the port %d\n",
395 			 port);
396 	}
397 
398 	if (p->rgmii_rx_val) {
399 		lan937x_set_rgmii_rx_delay(dev, port);
400 		dev_info(dev->dev, "Applied rgmii rx delay for the port %d\n",
401 			 port);
402 	}
403 }
404 
lan937x_tc_cbs_set_cinc(struct ksz_device * dev,int port,u32 val)405 int lan937x_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val)
406 {
407 	return ksz_pwrite32(dev, port, REG_PORT_MTI_CREDIT_INCREMENT, val);
408 }
409 
lan937x_switch_init(struct ksz_device * dev)410 int lan937x_switch_init(struct ksz_device *dev)
411 {
412 	dev->port_mask = (1 << dev->info->port_cnt) - 1;
413 
414 	return 0;
415 }
416 
lan937x_setup(struct dsa_switch * ds)417 int lan937x_setup(struct dsa_switch *ds)
418 {
419 	struct ksz_device *dev = ds->priv;
420 	int ret;
421 
422 	/* enable Indirect Access from SPI to the VPHY registers */
423 	ret = lan937x_enable_spi_indirect_access(dev);
424 	if (ret < 0) {
425 		dev_err(dev->dev, "failed to enable spi indirect access");
426 		return ret;
427 	}
428 
429 	/* The VLAN aware is a global setting. Mixed vlan
430 	 * filterings are not supported.
431 	 */
432 	ds->vlan_filtering_is_global = true;
433 
434 	/* Enable aggressive back off for half duplex & UNH mode */
435 	ret = lan937x_cfg(dev, REG_SW_MAC_CTRL_0, (SW_PAUSE_UNH_MODE |
436 						   SW_NEW_BACKOFF |
437 						   SW_AGGR_BACKOFF), true);
438 	if (ret < 0)
439 		return ret;
440 
441 	/* If NO_EXC_COLLISION_DROP bit is set, the switch will not drop
442 	 * packets when 16 or more collisions occur
443 	 */
444 	ret = lan937x_cfg(dev, REG_SW_MAC_CTRL_1, NO_EXC_COLLISION_DROP, true);
445 	if (ret < 0)
446 		return ret;
447 
448 	/* enable global MIB counter freeze function */
449 	ret = lan937x_cfg(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FREEZE, true);
450 	if (ret < 0)
451 		return ret;
452 
453 	/* disable CLK125 & CLK25, 1: disable, 0: enable */
454 	ret = lan937x_cfg(dev, REG_SW_GLOBAL_OUTPUT_CTRL__1,
455 			  (SW_CLK125_ENB | SW_CLK25_ENB), true);
456 	if (ret < 0)
457 		return ret;
458 
459 	/* Disable global VPHY support. Related to CPU interface only? */
460 	return ksz_rmw32(dev, REG_SW_CFG_STRAP_OVR, SW_VPHY_DISABLE,
461 			 SW_VPHY_DISABLE);
462 }
463 
lan937x_teardown(struct dsa_switch * ds)464 void lan937x_teardown(struct dsa_switch *ds)
465 {
466 
467 }
468 
lan937x_switch_exit(struct ksz_device * dev)469 void lan937x_switch_exit(struct ksz_device *dev)
470 {
471 	lan937x_reset_switch(dev);
472 }
473 
474 MODULE_AUTHOR("Arun Ramadoss <arun.ramadoss@microchip.com>");
475 MODULE_DESCRIPTION("Microchip LAN937x Series Switch DSA Driver");
476 MODULE_LICENSE("GPL");
477