1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip Sparx5 Switch driver
3  *
4  * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
5  */
6 
7 #include <linux/module.h>
8 #include <linux/phy/phy.h>
9 
10 #include "sparx5_main_regs.h"
11 #include "sparx5_main.h"
12 #include "sparx5_port.h"
13 
14 #define SPX5_ETYPE_TAG_C     0x8100
15 #define SPX5_ETYPE_TAG_S     0x88a8
16 
17 #define SPX5_WAIT_US         1000
18 #define SPX5_WAIT_MAX_US     2000
19 
20 enum port_error {
21 	SPX5_PERR_SPEED,
22 	SPX5_PERR_IFTYPE,
23 };
24 
25 #define PAUSE_DISCARD        0xC
26 #define ETH_MAXLEN           (ETH_DATA_LEN + ETH_HLEN + ETH_FCS_LEN)
27 
decode_sgmii_word(u16 lp_abil,struct sparx5_port_status * status)28 static void decode_sgmii_word(u16 lp_abil, struct sparx5_port_status *status)
29 {
30 	status->an_complete = true;
31 	if (!(lp_abil & LPA_SGMII_LINK)) {
32 		status->link = false;
33 		return;
34 	}
35 
36 	switch (lp_abil & LPA_SGMII_SPD_MASK) {
37 	case LPA_SGMII_10:
38 		status->speed = SPEED_10;
39 		break;
40 	case LPA_SGMII_100:
41 		status->speed = SPEED_100;
42 		break;
43 	case LPA_SGMII_1000:
44 		status->speed = SPEED_1000;
45 		break;
46 	default:
47 		status->link = false;
48 		return;
49 	}
50 	if (lp_abil & LPA_SGMII_FULL_DUPLEX)
51 		status->duplex = DUPLEX_FULL;
52 	else
53 		status->duplex = DUPLEX_HALF;
54 }
55 
decode_cl37_word(u16 lp_abil,uint16_t ld_abil,struct sparx5_port_status * status)56 static void decode_cl37_word(u16 lp_abil, uint16_t ld_abil, struct sparx5_port_status *status)
57 {
58 	status->link = !(lp_abil & ADVERTISE_RFAULT) && status->link;
59 	status->an_complete = true;
60 	status->duplex = (ADVERTISE_1000XFULL & lp_abil) ?
61 		DUPLEX_FULL : DUPLEX_UNKNOWN; // 1G HDX not supported
62 
63 	if ((ld_abil & ADVERTISE_1000XPAUSE) &&
64 	    (lp_abil & ADVERTISE_1000XPAUSE)) {
65 		status->pause = MLO_PAUSE_RX | MLO_PAUSE_TX;
66 	} else if ((ld_abil & ADVERTISE_1000XPSE_ASYM) &&
67 		   (lp_abil & ADVERTISE_1000XPSE_ASYM)) {
68 		status->pause |= (lp_abil & ADVERTISE_1000XPAUSE) ?
69 			MLO_PAUSE_TX : 0;
70 		status->pause |= (ld_abil & ADVERTISE_1000XPAUSE) ?
71 			MLO_PAUSE_RX : 0;
72 	} else {
73 		status->pause = MLO_PAUSE_NONE;
74 	}
75 }
76 
sparx5_get_dev2g5_status(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_status * status)77 static int sparx5_get_dev2g5_status(struct sparx5 *sparx5,
78 				    struct sparx5_port *port,
79 				    struct sparx5_port_status *status)
80 {
81 	u32 portno = port->portno;
82 	u16 lp_adv, ld_adv;
83 	u32 value;
84 
85 	/* Get PCS Link down sticky */
86 	value = spx5_rd(sparx5, DEV2G5_PCS1G_STICKY(portno));
87 	status->link_down = DEV2G5_PCS1G_STICKY_LINK_DOWN_STICKY_GET(value);
88 	if (status->link_down)	/* Clear the sticky */
89 		spx5_wr(value, sparx5, DEV2G5_PCS1G_STICKY(portno));
90 
91 	/* Get both current Link and Sync status */
92 	value = spx5_rd(sparx5, DEV2G5_PCS1G_LINK_STATUS(portno));
93 	status->link = DEV2G5_PCS1G_LINK_STATUS_LINK_STATUS_GET(value) &&
94 		       DEV2G5_PCS1G_LINK_STATUS_SYNC_STATUS_GET(value);
95 
96 	if (port->conf.portmode == PHY_INTERFACE_MODE_1000BASEX)
97 		status->speed = SPEED_1000;
98 	else if (port->conf.portmode == PHY_INTERFACE_MODE_2500BASEX)
99 		status->speed = SPEED_2500;
100 
101 	status->duplex = DUPLEX_FULL;
102 
103 	/* Get PCS ANEG status register */
104 	value = spx5_rd(sparx5, DEV2G5_PCS1G_ANEG_STATUS(portno));
105 
106 	/* Aneg complete provides more information  */
107 	if (DEV2G5_PCS1G_ANEG_STATUS_ANEG_COMPLETE_GET(value)) {
108 		lp_adv = DEV2G5_PCS1G_ANEG_STATUS_LP_ADV_ABILITY_GET(value);
109 		if (port->conf.portmode == PHY_INTERFACE_MODE_SGMII) {
110 			decode_sgmii_word(lp_adv, status);
111 		} else {
112 			value = spx5_rd(sparx5, DEV2G5_PCS1G_ANEG_CFG(portno));
113 			ld_adv = DEV2G5_PCS1G_ANEG_CFG_ADV_ABILITY_GET(value);
114 			decode_cl37_word(lp_adv, ld_adv, status);
115 		}
116 	}
117 	return 0;
118 }
119 
sparx5_get_sfi_status(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_status * status)120 static int sparx5_get_sfi_status(struct sparx5 *sparx5,
121 				 struct sparx5_port *port,
122 				 struct sparx5_port_status *status)
123 {
124 	bool high_speed_dev = sparx5_is_baser(port->conf.portmode);
125 	u32 portno = port->portno;
126 	u32 value, dev, tinst;
127 	void __iomem *inst;
128 
129 	if (!high_speed_dev) {
130 		netdev_err(port->ndev, "error: low speed and SFI mode\n");
131 		return -EINVAL;
132 	}
133 
134 	dev = sparx5_to_high_dev(portno);
135 	tinst = sparx5_port_dev_index(portno);
136 	inst = spx5_inst_get(sparx5, dev, tinst);
137 
138 	value = spx5_inst_rd(inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
139 	if (value != DEV10G_MAC_TX_MONITOR_STICKY_IDLE_STATE_STICKY) {
140 		/* The link is or has been down. Clear the sticky bit */
141 		status->link_down = 1;
142 		spx5_inst_wr(0xffffffff, inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
143 		value = spx5_inst_rd(inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
144 	}
145 	status->link = (value == DEV10G_MAC_TX_MONITOR_STICKY_IDLE_STATE_STICKY);
146 	status->duplex = DUPLEX_FULL;
147 	if (port->conf.portmode == PHY_INTERFACE_MODE_5GBASER)
148 		status->speed = SPEED_5000;
149 	else if (port->conf.portmode == PHY_INTERFACE_MODE_10GBASER)
150 		status->speed = SPEED_10000;
151 	else
152 		status->speed = SPEED_25000;
153 
154 	return 0;
155 }
156 
157 /* Get link status of 1000Base-X/in-band and SFI ports.
158  */
sparx5_get_port_status(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_status * status)159 int sparx5_get_port_status(struct sparx5 *sparx5,
160 			   struct sparx5_port *port,
161 			   struct sparx5_port_status *status)
162 {
163 	memset(status, 0, sizeof(*status));
164 	status->speed = port->conf.speed;
165 	if (port->conf.power_down) {
166 		status->link = false;
167 		return 0;
168 	}
169 	switch (port->conf.portmode) {
170 	case PHY_INTERFACE_MODE_SGMII:
171 	case PHY_INTERFACE_MODE_QSGMII:
172 	case PHY_INTERFACE_MODE_1000BASEX:
173 	case PHY_INTERFACE_MODE_2500BASEX:
174 		return sparx5_get_dev2g5_status(sparx5, port, status);
175 	case PHY_INTERFACE_MODE_5GBASER:
176 	case PHY_INTERFACE_MODE_10GBASER:
177 	case PHY_INTERFACE_MODE_25GBASER:
178 		return sparx5_get_sfi_status(sparx5, port, status);
179 	case PHY_INTERFACE_MODE_NA:
180 		return 0;
181 	default:
182 		netdev_err(port->ndev, "Status not supported");
183 		return -ENODEV;
184 	}
185 	return 0;
186 }
187 
sparx5_port_error(struct sparx5_port * port,struct sparx5_port_config * conf,enum port_error errtype)188 static int sparx5_port_error(struct sparx5_port *port,
189 			     struct sparx5_port_config *conf,
190 			     enum port_error errtype)
191 {
192 	switch (errtype) {
193 	case SPX5_PERR_SPEED:
194 		netdev_err(port->ndev,
195 			   "Interface does not support speed: %u: for %s\n",
196 			   conf->speed, phy_modes(conf->portmode));
197 		break;
198 	case SPX5_PERR_IFTYPE:
199 		netdev_err(port->ndev,
200 			   "Switch port does not support interface type: %s\n",
201 			   phy_modes(conf->portmode));
202 		break;
203 	default:
204 		netdev_err(port->ndev,
205 			   "Interface configuration error\n");
206 	}
207 
208 	return -EINVAL;
209 }
210 
sparx5_port_verify_speed(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)211 static int sparx5_port_verify_speed(struct sparx5 *sparx5,
212 				    struct sparx5_port *port,
213 				    struct sparx5_port_config *conf)
214 {
215 	if ((sparx5_port_is_2g5(port->portno) &&
216 	     conf->speed > SPEED_2500) ||
217 	    (sparx5_port_is_5g(port->portno)  &&
218 	     conf->speed > SPEED_5000) ||
219 	    (sparx5_port_is_10g(port->portno) &&
220 	     conf->speed > SPEED_10000))
221 		return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
222 
223 	switch (conf->portmode) {
224 	case PHY_INTERFACE_MODE_NA:
225 		return -EINVAL;
226 	case PHY_INTERFACE_MODE_1000BASEX:
227 		if (conf->speed != SPEED_1000 ||
228 		    sparx5_port_is_2g5(port->portno))
229 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
230 		if (sparx5_port_is_2g5(port->portno))
231 			return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
232 		break;
233 	case PHY_INTERFACE_MODE_2500BASEX:
234 		if (conf->speed != SPEED_2500 ||
235 		    sparx5_port_is_2g5(port->portno))
236 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
237 		break;
238 	case PHY_INTERFACE_MODE_QSGMII:
239 		if (port->portno > 47)
240 			return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
241 		fallthrough;
242 	case PHY_INTERFACE_MODE_SGMII:
243 		if (conf->speed != SPEED_1000 &&
244 		    conf->speed != SPEED_100 &&
245 		    conf->speed != SPEED_10 &&
246 		    conf->speed != SPEED_2500)
247 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
248 		break;
249 	case PHY_INTERFACE_MODE_5GBASER:
250 	case PHY_INTERFACE_MODE_10GBASER:
251 	case PHY_INTERFACE_MODE_25GBASER:
252 		if ((conf->speed != SPEED_5000 &&
253 		     conf->speed != SPEED_10000 &&
254 		     conf->speed != SPEED_25000))
255 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
256 		break;
257 	default:
258 		return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
259 	}
260 	return 0;
261 }
262 
sparx5_dev_change(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)263 static bool sparx5_dev_change(struct sparx5 *sparx5,
264 			      struct sparx5_port *port,
265 			      struct sparx5_port_config *conf)
266 {
267 	return sparx5_is_baser(port->conf.portmode) ^
268 		sparx5_is_baser(conf->portmode);
269 }
270 
sparx5_port_flush_poll(struct sparx5 * sparx5,u32 portno)271 static int sparx5_port_flush_poll(struct sparx5 *sparx5, u32 portno)
272 {
273 	u32  value, resource, prio, delay_cnt = 0;
274 	bool poll_src = true;
275 	char *mem = "";
276 
277 	/* Resource == 0: Memory tracked per source (SRC-MEM)
278 	 * Resource == 1: Frame references tracked per source (SRC-REF)
279 	 * Resource == 2: Memory tracked per destination (DST-MEM)
280 	 * Resource == 3: Frame references tracked per destination. (DST-REF)
281 	 */
282 	while (1) {
283 		bool empty = true;
284 
285 		for (resource = 0; resource < (poll_src ? 2 : 1); resource++) {
286 			u32 base;
287 
288 			base = (resource == 0 ? 2048 : 0) + SPX5_PRIOS * portno;
289 			for (prio = 0; prio < SPX5_PRIOS; prio++) {
290 				value = spx5_rd(sparx5,
291 						QRES_RES_STAT(base + prio));
292 				if (value) {
293 					mem = resource == 0 ?
294 						"DST-MEM" : "SRC-MEM";
295 					empty = false;
296 				}
297 			}
298 		}
299 
300 		if (empty)
301 			break;
302 
303 		if (delay_cnt++ == 2000) {
304 			dev_err(sparx5->dev,
305 				"Flush timeout port %u. %s queue not empty\n",
306 				portno, mem);
307 			return -EINVAL;
308 		}
309 
310 		usleep_range(SPX5_WAIT_US, SPX5_WAIT_MAX_US);
311 	}
312 	return 0;
313 }
314 
sparx5_port_disable(struct sparx5 * sparx5,struct sparx5_port * port,bool high_spd_dev)315 static int sparx5_port_disable(struct sparx5 *sparx5, struct sparx5_port *port, bool high_spd_dev)
316 {
317 	u32 tinst = high_spd_dev ?
318 		    sparx5_port_dev_index(port->portno) : port->portno;
319 	u32 dev = high_spd_dev ?
320 		  sparx5_to_high_dev(port->portno) : TARGET_DEV2G5;
321 	void __iomem *devinst = spx5_inst_get(sparx5, dev, tinst);
322 	u32 spd = port->conf.speed;
323 	u32 spd_prm;
324 	int err;
325 
326 	if (high_spd_dev) {
327 		/* 1: Reset the PCS Rx clock domain  */
328 		spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_RX_RST,
329 			      DEV10G_DEV_RST_CTRL_PCS_RX_RST,
330 			      devinst,
331 			      DEV10G_DEV_RST_CTRL(0));
332 
333 		/* 2: Disable MAC frame reception */
334 		spx5_inst_rmw(0,
335 			      DEV10G_MAC_ENA_CFG_RX_ENA,
336 			      devinst,
337 			      DEV10G_MAC_ENA_CFG(0));
338 	} else {
339 		/* 1: Reset the PCS Rx clock domain  */
340 		spx5_inst_rmw(DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
341 			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
342 			      devinst,
343 			      DEV2G5_DEV_RST_CTRL(0));
344 		/* 2: Disable MAC frame reception */
345 		spx5_inst_rmw(0,
346 			      DEV2G5_MAC_ENA_CFG_RX_ENA,
347 			      devinst,
348 			      DEV2G5_MAC_ENA_CFG(0));
349 	}
350 	/* 3: Disable traffic being sent to or from switch port->portno */
351 	spx5_rmw(0,
352 		 QFWD_SWITCH_PORT_MODE_PORT_ENA,
353 		 sparx5,
354 		 QFWD_SWITCH_PORT_MODE(port->portno));
355 
356 	/* 4: Disable dequeuing from the egress queues  */
357 	spx5_rmw(HSCH_PORT_MODE_DEQUEUE_DIS,
358 		 HSCH_PORT_MODE_DEQUEUE_DIS,
359 		 sparx5,
360 		 HSCH_PORT_MODE(port->portno));
361 
362 	/* 5: Disable Flowcontrol */
363 	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_STOP_SET(0xFFF - 1),
364 		 QSYS_PAUSE_CFG_PAUSE_STOP,
365 		 sparx5,
366 		 QSYS_PAUSE_CFG(port->portno));
367 
368 	spd_prm = spd == SPEED_10 ? 1000 : spd == SPEED_100 ? 100 : 10;
369 	/* 6: Wait while the last frame is exiting the queues */
370 	usleep_range(8 * spd_prm, 10 * spd_prm);
371 
372 	/* 7: Flush the queues accociated with the port->portno */
373 	spx5_rmw(HSCH_FLUSH_CTRL_FLUSH_PORT_SET(port->portno) |
374 		 HSCH_FLUSH_CTRL_FLUSH_DST_SET(1) |
375 		 HSCH_FLUSH_CTRL_FLUSH_SRC_SET(1) |
376 		 HSCH_FLUSH_CTRL_FLUSH_ENA_SET(1),
377 		 HSCH_FLUSH_CTRL_FLUSH_PORT |
378 		 HSCH_FLUSH_CTRL_FLUSH_DST |
379 		 HSCH_FLUSH_CTRL_FLUSH_SRC |
380 		 HSCH_FLUSH_CTRL_FLUSH_ENA,
381 		 sparx5,
382 		 HSCH_FLUSH_CTRL);
383 
384 	/* 8: Enable dequeuing from the egress queues */
385 	spx5_rmw(0,
386 		 HSCH_PORT_MODE_DEQUEUE_DIS,
387 		 sparx5,
388 		 HSCH_PORT_MODE(port->portno));
389 
390 	/* 9: Wait until flushing is complete */
391 	err = sparx5_port_flush_poll(sparx5, port->portno);
392 	if (err)
393 		return err;
394 
395 	/* 10: Reset the  MAC clock domain */
396 	if (high_spd_dev) {
397 		spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_TX_RST_SET(1) |
398 			      DEV10G_DEV_RST_CTRL_MAC_RX_RST_SET(1) |
399 			      DEV10G_DEV_RST_CTRL_MAC_TX_RST_SET(1),
400 			      DEV10G_DEV_RST_CTRL_PCS_TX_RST |
401 			      DEV10G_DEV_RST_CTRL_MAC_RX_RST |
402 			      DEV10G_DEV_RST_CTRL_MAC_TX_RST,
403 			      devinst,
404 			      DEV10G_DEV_RST_CTRL(0));
405 
406 	} else {
407 		spx5_inst_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(3) |
408 			      DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(1) |
409 			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST_SET(1) |
410 			      DEV2G5_DEV_RST_CTRL_MAC_TX_RST_SET(1) |
411 			      DEV2G5_DEV_RST_CTRL_MAC_RX_RST_SET(1),
412 			      DEV2G5_DEV_RST_CTRL_SPEED_SEL |
413 			      DEV2G5_DEV_RST_CTRL_PCS_TX_RST |
414 			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST |
415 			      DEV2G5_DEV_RST_CTRL_MAC_TX_RST |
416 			      DEV2G5_DEV_RST_CTRL_MAC_RX_RST,
417 			      devinst,
418 			      DEV2G5_DEV_RST_CTRL(0));
419 	}
420 	/* 11: Clear flushing */
421 	spx5_rmw(HSCH_FLUSH_CTRL_FLUSH_PORT_SET(port->portno) |
422 		 HSCH_FLUSH_CTRL_FLUSH_ENA_SET(0),
423 		 HSCH_FLUSH_CTRL_FLUSH_PORT |
424 		 HSCH_FLUSH_CTRL_FLUSH_ENA,
425 		 sparx5,
426 		 HSCH_FLUSH_CTRL);
427 
428 	if (high_spd_dev) {
429 		u32 pcs = sparx5_to_pcs_dev(port->portno);
430 		void __iomem *pcsinst = spx5_inst_get(sparx5, pcs, tinst);
431 
432 		/* 12: Disable 5G/10G/25 BaseR PCS */
433 		spx5_inst_rmw(PCS10G_BR_PCS_CFG_PCS_ENA_SET(0),
434 			      PCS10G_BR_PCS_CFG_PCS_ENA,
435 			      pcsinst,
436 			      PCS10G_BR_PCS_CFG(0));
437 
438 		if (sparx5_port_is_25g(port->portno))
439 			/* Disable 25G PCS */
440 			spx5_rmw(DEV25G_PCS25G_CFG_PCS25G_ENA_SET(0),
441 				 DEV25G_PCS25G_CFG_PCS25G_ENA,
442 				 sparx5,
443 				 DEV25G_PCS25G_CFG(tinst));
444 	} else {
445 		/* 12: Disable 1G PCS */
446 		spx5_rmw(DEV2G5_PCS1G_CFG_PCS_ENA_SET(0),
447 			 DEV2G5_PCS1G_CFG_PCS_ENA,
448 			 sparx5,
449 			 DEV2G5_PCS1G_CFG(port->portno));
450 	}
451 
452 	/* The port is now flushed and disabled  */
453 	return 0;
454 }
455 
sparx5_port_fifo_sz(struct sparx5 * sparx5,u32 portno,u32 speed)456 static int sparx5_port_fifo_sz(struct sparx5 *sparx5,
457 			       u32 portno, u32 speed)
458 {
459 	u32 sys_clk = sparx5_clk_period(sparx5->coreclock);
460 	const u32 taxi_dist[SPX5_PORTS_ALL] = {
461 		6, 8, 10, 6, 8, 10, 6, 8, 10, 6, 8, 10,
462 		4, 4, 4, 4,
463 		11, 12, 13, 14, 15, 16, 17, 18,
464 		11, 12, 13, 14, 15, 16, 17, 18,
465 		11, 12, 13, 14, 15, 16, 17, 18,
466 		11, 12, 13, 14, 15, 16, 17, 18,
467 		4, 6, 8, 4, 6, 8, 6, 8,
468 		2, 2, 2, 2, 2, 2, 2, 4, 2
469 	};
470 	u32 mac_per    = 6400, tmp1, tmp2, tmp3;
471 	u32 fifo_width = 16;
472 	u32 mac_width  = 8;
473 	u32 addition   = 0;
474 
475 	switch (speed) {
476 	case SPEED_25000:
477 		return 0;
478 	case SPEED_10000:
479 		mac_per = 6400;
480 		mac_width = 8;
481 		addition = 1;
482 		break;
483 	case SPEED_5000:
484 		mac_per = 12800;
485 		mac_width = 8;
486 		addition = 0;
487 		break;
488 	case SPEED_2500:
489 		mac_per = 3200;
490 		mac_width = 1;
491 		addition = 0;
492 		break;
493 	case SPEED_1000:
494 		mac_per =  8000;
495 		mac_width = 1;
496 		addition = 0;
497 		break;
498 	case SPEED_100:
499 	case SPEED_10:
500 		return 1;
501 	default:
502 		break;
503 	}
504 
505 	tmp1 = 1000 * mac_width / fifo_width;
506 	tmp2 = 3000 + ((12000 + 2 * taxi_dist[portno] * 1000)
507 		       * sys_clk / mac_per);
508 	tmp3 = tmp1 * tmp2 / 1000;
509 	return  (tmp3 + 2000 + 999) / 1000 + addition;
510 }
511 
512 /* Configure port muxing:
513  * QSGMII:     4x2G5 devices
514  */
sparx5_port_mux_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)515 static int sparx5_port_mux_set(struct sparx5 *sparx5,
516 			       struct sparx5_port *port,
517 			       struct sparx5_port_config *conf)
518 {
519 	u32 portno = port->portno;
520 	u32 inst;
521 
522 	if (port->conf.portmode == conf->portmode)
523 		return 0; /* Nothing to do */
524 
525 	switch (conf->portmode) {
526 	case PHY_INTERFACE_MODE_QSGMII: /* QSGMII: 4x2G5 devices. Mode Q'  */
527 		inst = (portno - portno % 4) / 4;
528 		spx5_rmw(BIT(inst),
529 			 BIT(inst),
530 			 sparx5,
531 			 PORT_CONF_QSGMII_ENA);
532 
533 		if ((portno / 4 % 2) == 0) {
534 			/* Affects d0-d3,d8-d11..d40-d43 */
535 			spx5_rmw(PORT_CONF_USGMII_CFG_BYPASS_SCRAM_SET(1) |
536 				 PORT_CONF_USGMII_CFG_BYPASS_DESCRAM_SET(1) |
537 				 PORT_CONF_USGMII_CFG_QUAD_MODE_SET(1),
538 				 PORT_CONF_USGMII_CFG_BYPASS_SCRAM |
539 				 PORT_CONF_USGMII_CFG_BYPASS_DESCRAM |
540 				 PORT_CONF_USGMII_CFG_QUAD_MODE,
541 				 sparx5,
542 				 PORT_CONF_USGMII_CFG((portno / 8)));
543 		}
544 		break;
545 	default:
546 		break;
547 	}
548 	return 0;
549 }
550 
sparx5_port_max_tags_set(struct sparx5 * sparx5,struct sparx5_port * port)551 static int sparx5_port_max_tags_set(struct sparx5 *sparx5,
552 				    struct sparx5_port *port)
553 {
554 	enum sparx5_port_max_tags max_tags    = port->max_vlan_tags;
555 	int tag_ct          = max_tags == SPX5_PORT_MAX_TAGS_ONE ? 1 :
556 			      max_tags == SPX5_PORT_MAX_TAGS_TWO ? 2 : 0;
557 	bool dtag           = max_tags == SPX5_PORT_MAX_TAGS_TWO;
558 	enum sparx5_vlan_port_type vlan_type  = port->vlan_type;
559 	bool dotag          = max_tags != SPX5_PORT_MAX_TAGS_NONE;
560 	u32 dev             = sparx5_to_high_dev(port->portno);
561 	u32 tinst           = sparx5_port_dev_index(port->portno);
562 	void __iomem *inst  = spx5_inst_get(sparx5, dev, tinst);
563 	u32 etype;
564 
565 	etype = (vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ?
566 		 port->custom_etype :
567 		 vlan_type == SPX5_VLAN_PORT_TYPE_C ?
568 		 SPX5_ETYPE_TAG_C : SPX5_ETYPE_TAG_S);
569 
570 	spx5_wr(DEV2G5_MAC_TAGS_CFG_TAG_ID_SET(etype) |
571 		DEV2G5_MAC_TAGS_CFG_PB_ENA_SET(dtag) |
572 		DEV2G5_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(dotag) |
573 		DEV2G5_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(dotag),
574 		sparx5,
575 		DEV2G5_MAC_TAGS_CFG(port->portno));
576 
577 	if (sparx5_port_is_2g5(port->portno))
578 		return 0;
579 
580 	spx5_inst_rmw(DEV10G_MAC_TAGS_CFG_TAG_ID_SET(etype) |
581 		      DEV10G_MAC_TAGS_CFG_TAG_ENA_SET(dotag),
582 		      DEV10G_MAC_TAGS_CFG_TAG_ID |
583 		      DEV10G_MAC_TAGS_CFG_TAG_ENA,
584 		      inst,
585 		      DEV10G_MAC_TAGS_CFG(0, 0));
586 
587 	spx5_inst_rmw(DEV10G_MAC_NUM_TAGS_CFG_NUM_TAGS_SET(tag_ct),
588 		      DEV10G_MAC_NUM_TAGS_CFG_NUM_TAGS,
589 		      inst,
590 		      DEV10G_MAC_NUM_TAGS_CFG(0));
591 
592 	spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_TAG_CHK_SET(dotag),
593 		      DEV10G_MAC_MAXLEN_CFG_MAX_LEN_TAG_CHK,
594 		      inst,
595 		      DEV10G_MAC_MAXLEN_CFG(0));
596 	return 0;
597 }
598 
sparx5_port_fwd_urg(struct sparx5 * sparx5,u32 speed)599 int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed)
600 {
601 	u32 clk_period_ps = 1600; /* 625Mhz for now */
602 	u32 urg = 672000;
603 
604 	switch (speed) {
605 	case SPEED_10:
606 	case SPEED_100:
607 	case SPEED_1000:
608 		urg = 672000;
609 		break;
610 	case SPEED_2500:
611 		urg = 270000;
612 		break;
613 	case SPEED_5000:
614 		urg = 135000;
615 		break;
616 	case SPEED_10000:
617 		urg = 67200;
618 		break;
619 	case SPEED_25000:
620 		urg = 27000;
621 		break;
622 	}
623 	return urg / clk_period_ps - 1;
624 }
625 
sparx5_wm_enc(u16 value)626 static u16 sparx5_wm_enc(u16 value)
627 {
628 	if (value >= 2048)
629 		return 2048 + value / 16;
630 
631 	return value;
632 }
633 
sparx5_port_fc_setup(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)634 static int sparx5_port_fc_setup(struct sparx5 *sparx5,
635 				struct sparx5_port *port,
636 				struct sparx5_port_config *conf)
637 {
638 	bool fc_obey = conf->pause & MLO_PAUSE_RX ? 1 : 0;
639 	u32 pause_stop = 0xFFF - 1; /* FC gen disabled */
640 
641 	if (conf->pause & MLO_PAUSE_TX)
642 		pause_stop = sparx5_wm_enc(4  * (ETH_MAXLEN /
643 						 SPX5_BUFFER_CELL_SZ));
644 
645 	/* Set HDX flowcontrol */
646 	spx5_rmw(DSM_MAC_CFG_HDX_BACKPREASSURE_SET(conf->duplex == DUPLEX_HALF),
647 		 DSM_MAC_CFG_HDX_BACKPREASSURE,
648 		 sparx5,
649 		 DSM_MAC_CFG(port->portno));
650 
651 	/* Obey flowcontrol  */
652 	spx5_rmw(DSM_RX_PAUSE_CFG_RX_PAUSE_EN_SET(fc_obey),
653 		 DSM_RX_PAUSE_CFG_RX_PAUSE_EN,
654 		 sparx5,
655 		 DSM_RX_PAUSE_CFG(port->portno));
656 
657 	/* Disable forward pressure */
658 	spx5_rmw(QSYS_FWD_PRESSURE_FWD_PRESSURE_DIS_SET(fc_obey),
659 		 QSYS_FWD_PRESSURE_FWD_PRESSURE_DIS,
660 		 sparx5,
661 		 QSYS_FWD_PRESSURE(port->portno));
662 
663 	/* Generate pause frames */
664 	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop),
665 		 QSYS_PAUSE_CFG_PAUSE_STOP,
666 		 sparx5,
667 		 QSYS_PAUSE_CFG(port->portno));
668 
669 	return 0;
670 }
671 
sparx5_get_aneg_word(struct sparx5_port_config * conf)672 static u16 sparx5_get_aneg_word(struct sparx5_port_config *conf)
673 {
674 	if (conf->portmode == PHY_INTERFACE_MODE_1000BASEX) /* cl-37 aneg */
675 		return (conf->pause_adv | ADVERTISE_LPACK | ADVERTISE_1000XFULL);
676 	else
677 		return 1; /* Enable SGMII Aneg */
678 }
679 
sparx5_serdes_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)680 int sparx5_serdes_set(struct sparx5 *sparx5,
681 		      struct sparx5_port *port,
682 		      struct sparx5_port_config *conf)
683 {
684 	int portmode, err, speed = conf->speed;
685 
686 	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII &&
687 	    ((port->portno % 4) != 0)) {
688 		return 0;
689 	}
690 	if (sparx5_is_baser(conf->portmode)) {
691 		if (conf->portmode == PHY_INTERFACE_MODE_25GBASER)
692 			speed = SPEED_25000;
693 		else if (conf->portmode == PHY_INTERFACE_MODE_10GBASER)
694 			speed = SPEED_10000;
695 		else
696 			speed = SPEED_5000;
697 	}
698 
699 	err = phy_set_media(port->serdes, conf->media);
700 	if (err)
701 		return err;
702 	if (speed > 0) {
703 		err = phy_set_speed(port->serdes, speed);
704 		if (err)
705 			return err;
706 	}
707 	if (conf->serdes_reset) {
708 		err = phy_reset(port->serdes);
709 		if (err)
710 			return err;
711 	}
712 
713 	/* Configure SerDes with port parameters
714 	 * For BaseR, the serdes driver supports 10GGBASE-R and speed 5G/10G/25G
715 	 */
716 	portmode = conf->portmode;
717 	if (sparx5_is_baser(conf->portmode))
718 		portmode = PHY_INTERFACE_MODE_10GBASER;
719 	err = phy_set_mode_ext(port->serdes, PHY_MODE_ETHERNET, portmode);
720 	if (err)
721 		return err;
722 	conf->serdes_reset = false;
723 	return err;
724 }
725 
sparx5_port_pcs_low_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)726 static int sparx5_port_pcs_low_set(struct sparx5 *sparx5,
727 				   struct sparx5_port *port,
728 				   struct sparx5_port_config *conf)
729 {
730 	bool sgmii = false, inband_aneg = false;
731 	int err;
732 
733 	if (port->conf.inband) {
734 		if (conf->portmode == PHY_INTERFACE_MODE_SGMII ||
735 		    conf->portmode == PHY_INTERFACE_MODE_QSGMII)
736 			inband_aneg = true; /* Cisco-SGMII in-band-aneg */
737 		else if (conf->portmode == PHY_INTERFACE_MODE_1000BASEX &&
738 			 conf->autoneg)
739 			inband_aneg = true; /* Clause-37 in-band-aneg */
740 
741 		err = sparx5_serdes_set(sparx5, port, conf);
742 		if (err)
743 			return -EINVAL;
744 	} else {
745 		sgmii = true; /* Phy is connected to the MAC */
746 	}
747 
748 	/* Choose SGMII or 1000BaseX/2500BaseX PCS mode */
749 	spx5_rmw(DEV2G5_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(sgmii),
750 		 DEV2G5_PCS1G_MODE_CFG_SGMII_MODE_ENA,
751 		 sparx5,
752 		 DEV2G5_PCS1G_MODE_CFG(port->portno));
753 
754 	/* Enable PCS */
755 	spx5_wr(DEV2G5_PCS1G_CFG_PCS_ENA_SET(1),
756 		sparx5,
757 		DEV2G5_PCS1G_CFG(port->portno));
758 
759 	if (inband_aneg) {
760 		u16 abil = sparx5_get_aneg_word(conf);
761 
762 		/* Enable in-band aneg */
763 		spx5_wr(DEV2G5_PCS1G_ANEG_CFG_ADV_ABILITY_SET(abil) |
764 			DEV2G5_PCS1G_ANEG_CFG_SW_RESOLVE_ENA_SET(1) |
765 			DEV2G5_PCS1G_ANEG_CFG_ANEG_ENA_SET(1) |
766 			DEV2G5_PCS1G_ANEG_CFG_ANEG_RESTART_ONE_SHOT_SET(1),
767 			sparx5,
768 			DEV2G5_PCS1G_ANEG_CFG(port->portno));
769 	} else {
770 		spx5_wr(0, sparx5, DEV2G5_PCS1G_ANEG_CFG(port->portno));
771 	}
772 
773 	/* Take PCS out of reset */
774 	spx5_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(2) |
775 		 DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(0) |
776 		 DEV2G5_DEV_RST_CTRL_PCS_RX_RST_SET(0),
777 		 DEV2G5_DEV_RST_CTRL_SPEED_SEL |
778 		 DEV2G5_DEV_RST_CTRL_PCS_TX_RST |
779 		 DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
780 		 sparx5,
781 		 DEV2G5_DEV_RST_CTRL(port->portno));
782 
783 	return 0;
784 }
785 
sparx5_port_pcs_high_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)786 static int sparx5_port_pcs_high_set(struct sparx5 *sparx5,
787 				    struct sparx5_port *port,
788 				    struct sparx5_port_config *conf)
789 {
790 	u32 clk_spd = conf->portmode == PHY_INTERFACE_MODE_5GBASER ? 1 : 0;
791 	u32 pix = sparx5_port_dev_index(port->portno);
792 	u32 dev = sparx5_to_high_dev(port->portno);
793 	u32 pcs = sparx5_to_pcs_dev(port->portno);
794 	void __iomem *devinst;
795 	void __iomem *pcsinst;
796 	int err;
797 
798 	devinst = spx5_inst_get(sparx5, dev, pix);
799 	pcsinst = spx5_inst_get(sparx5, pcs, pix);
800 
801 	/*  SFI : No in-band-aneg. Speeds 5G/10G/25G */
802 	err = sparx5_serdes_set(sparx5, port, conf);
803 	if (err)
804 		return -EINVAL;
805 	if (conf->portmode == PHY_INTERFACE_MODE_25GBASER) {
806 		/* Enable PCS for 25G device, speed 25G */
807 		spx5_rmw(DEV25G_PCS25G_CFG_PCS25G_ENA_SET(1),
808 			 DEV25G_PCS25G_CFG_PCS25G_ENA,
809 			 sparx5,
810 			 DEV25G_PCS25G_CFG(pix));
811 	} else {
812 		/* Enable PCS for 5G/10G/25G devices, speed 5G/10G */
813 		spx5_inst_rmw(PCS10G_BR_PCS_CFG_PCS_ENA_SET(1),
814 			      PCS10G_BR_PCS_CFG_PCS_ENA,
815 			      pcsinst,
816 			      PCS10G_BR_PCS_CFG(0));
817 	}
818 
819 	/* Enable 5G/10G/25G MAC module */
820 	spx5_inst_wr(DEV10G_MAC_ENA_CFG_RX_ENA_SET(1) |
821 		     DEV10G_MAC_ENA_CFG_TX_ENA_SET(1),
822 		     devinst,
823 		     DEV10G_MAC_ENA_CFG(0));
824 
825 	/* Take the device out of reset */
826 	spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_RX_RST_SET(0) |
827 		      DEV10G_DEV_RST_CTRL_PCS_TX_RST_SET(0) |
828 		      DEV10G_DEV_RST_CTRL_MAC_RX_RST_SET(0) |
829 		      DEV10G_DEV_RST_CTRL_MAC_TX_RST_SET(0) |
830 		      DEV10G_DEV_RST_CTRL_SPEED_SEL_SET(clk_spd),
831 		      DEV10G_DEV_RST_CTRL_PCS_RX_RST |
832 		      DEV10G_DEV_RST_CTRL_PCS_TX_RST |
833 		      DEV10G_DEV_RST_CTRL_MAC_RX_RST |
834 		      DEV10G_DEV_RST_CTRL_MAC_TX_RST |
835 		      DEV10G_DEV_RST_CTRL_SPEED_SEL,
836 		      devinst,
837 		      DEV10G_DEV_RST_CTRL(0));
838 
839 	return 0;
840 }
841 
842 /* Switch between 1G/2500 and 5G/10G/25G devices */
sparx5_dev_switch(struct sparx5 * sparx5,int port,bool hsd)843 static void sparx5_dev_switch(struct sparx5 *sparx5, int port, bool hsd)
844 {
845 	int bt_indx = BIT(sparx5_port_dev_index(port));
846 
847 	if (sparx5_port_is_5g(port)) {
848 		spx5_rmw(hsd ? 0 : bt_indx,
849 			 bt_indx,
850 			 sparx5,
851 			 PORT_CONF_DEV5G_MODES);
852 	} else if (sparx5_port_is_10g(port)) {
853 		spx5_rmw(hsd ? 0 : bt_indx,
854 			 bt_indx,
855 			 sparx5,
856 			 PORT_CONF_DEV10G_MODES);
857 	} else if (sparx5_port_is_25g(port)) {
858 		spx5_rmw(hsd ? 0 : bt_indx,
859 			 bt_indx,
860 			 sparx5,
861 			 PORT_CONF_DEV25G_MODES);
862 	}
863 }
864 
865 /* Configure speed/duplex dependent registers */
sparx5_port_config_low_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)866 static int sparx5_port_config_low_set(struct sparx5 *sparx5,
867 				      struct sparx5_port *port,
868 				      struct sparx5_port_config *conf)
869 {
870 	u32 clk_spd, gig_mode, tx_gap, hdx_gap_1, hdx_gap_2;
871 	bool fdx = conf->duplex == DUPLEX_FULL;
872 	int spd = conf->speed;
873 
874 	clk_spd = spd == SPEED_10 ? 0 : spd == SPEED_100 ? 1 : 2;
875 	gig_mode = spd == SPEED_1000 || spd == SPEED_2500;
876 	tx_gap = spd == SPEED_1000 ? 4 : fdx ? 6 : 5;
877 	hdx_gap_1 = spd == SPEED_1000 ? 0 : spd == SPEED_100 ? 1 : 2;
878 	hdx_gap_2 = spd == SPEED_1000 ? 0 : spd == SPEED_100 ? 4 : 1;
879 
880 	/* GIG/FDX mode */
881 	spx5_rmw(DEV2G5_MAC_MODE_CFG_GIGA_MODE_ENA_SET(gig_mode) |
882 		 DEV2G5_MAC_MODE_CFG_FDX_ENA_SET(fdx),
883 		 DEV2G5_MAC_MODE_CFG_GIGA_MODE_ENA |
884 		 DEV2G5_MAC_MODE_CFG_FDX_ENA,
885 		 sparx5,
886 		 DEV2G5_MAC_MODE_CFG(port->portno));
887 
888 	/* Set MAC IFG Gaps */
889 	spx5_wr(DEV2G5_MAC_IFG_CFG_TX_IFG_SET(tx_gap) |
890 		DEV2G5_MAC_IFG_CFG_RX_IFG1_SET(hdx_gap_1) |
891 		DEV2G5_MAC_IFG_CFG_RX_IFG2_SET(hdx_gap_2),
892 		sparx5,
893 		DEV2G5_MAC_IFG_CFG(port->portno));
894 
895 	/* Disabling frame aging when in HDX (due to HDX issue) */
896 	spx5_rmw(HSCH_PORT_MODE_AGE_DIS_SET(fdx == 0),
897 		 HSCH_PORT_MODE_AGE_DIS,
898 		 sparx5,
899 		 HSCH_PORT_MODE(port->portno));
900 
901 	/* Enable MAC module */
902 	spx5_wr(DEV2G5_MAC_ENA_CFG_RX_ENA |
903 		DEV2G5_MAC_ENA_CFG_TX_ENA,
904 		sparx5,
905 		DEV2G5_MAC_ENA_CFG(port->portno));
906 
907 	/* Select speed and take MAC out of reset */
908 	spx5_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(clk_spd) |
909 		 DEV2G5_DEV_RST_CTRL_MAC_TX_RST_SET(0) |
910 		 DEV2G5_DEV_RST_CTRL_MAC_RX_RST_SET(0),
911 		 DEV2G5_DEV_RST_CTRL_SPEED_SEL |
912 		 DEV2G5_DEV_RST_CTRL_MAC_TX_RST |
913 		 DEV2G5_DEV_RST_CTRL_MAC_RX_RST,
914 		 sparx5,
915 		 DEV2G5_DEV_RST_CTRL(port->portno));
916 
917 	return 0;
918 }
919 
sparx5_port_pcs_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)920 int sparx5_port_pcs_set(struct sparx5 *sparx5,
921 			struct sparx5_port *port,
922 			struct sparx5_port_config *conf)
923 
924 {
925 	bool high_speed_dev = sparx5_is_baser(conf->portmode);
926 	int err;
927 
928 	if (sparx5_dev_change(sparx5, port, conf)) {
929 		/* switch device */
930 		sparx5_dev_switch(sparx5, port->portno, high_speed_dev);
931 
932 		/* Disable the not-in-use device */
933 		err = sparx5_port_disable(sparx5, port, !high_speed_dev);
934 		if (err)
935 			return err;
936 	}
937 	/* Disable the port before re-configuring */
938 	err = sparx5_port_disable(sparx5, port, high_speed_dev);
939 	if (err)
940 		return -EINVAL;
941 
942 	if (high_speed_dev)
943 		err = sparx5_port_pcs_high_set(sparx5, port, conf);
944 	else
945 		err = sparx5_port_pcs_low_set(sparx5, port, conf);
946 
947 	if (err)
948 		return -EINVAL;
949 
950 	if (port->conf.inband) {
951 		/* Enable/disable 1G counters in ASM */
952 		spx5_rmw(ASM_PORT_CFG_CSC_STAT_DIS_SET(high_speed_dev),
953 			 ASM_PORT_CFG_CSC_STAT_DIS,
954 			 sparx5,
955 			 ASM_PORT_CFG(port->portno));
956 
957 		/* Enable/disable 1G counters in DSM */
958 		spx5_rmw(DSM_BUF_CFG_CSC_STAT_DIS_SET(high_speed_dev),
959 			 DSM_BUF_CFG_CSC_STAT_DIS,
960 			 sparx5,
961 			 DSM_BUF_CFG(port->portno));
962 	}
963 
964 	port->conf = *conf;
965 
966 	return 0;
967 }
968 
sparx5_port_config(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)969 int sparx5_port_config(struct sparx5 *sparx5,
970 		       struct sparx5_port *port,
971 		       struct sparx5_port_config *conf)
972 {
973 	bool high_speed_dev = sparx5_is_baser(conf->portmode);
974 	int err, urgency, stop_wm;
975 
976 	err = sparx5_port_verify_speed(sparx5, port, conf);
977 	if (err)
978 		return err;
979 
980 	/* high speed device is already configured */
981 	if (!high_speed_dev)
982 		sparx5_port_config_low_set(sparx5, port, conf);
983 
984 	/* Configure flow control */
985 	err = sparx5_port_fc_setup(sparx5, port, conf);
986 	if (err)
987 		return err;
988 
989 	/* Set the DSM stop watermark */
990 	stop_wm = sparx5_port_fifo_sz(sparx5, port->portno, conf->speed);
991 	spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM_SET(stop_wm),
992 		 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM,
993 		 sparx5,
994 		 DSM_DEV_TX_STOP_WM_CFG(port->portno));
995 
996 	/* Enable port in queue system */
997 	urgency = sparx5_port_fwd_urg(sparx5, conf->speed);
998 	spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(1) |
999 		 QFWD_SWITCH_PORT_MODE_FWD_URGENCY_SET(urgency),
1000 		 QFWD_SWITCH_PORT_MODE_PORT_ENA |
1001 		 QFWD_SWITCH_PORT_MODE_FWD_URGENCY,
1002 		 sparx5,
1003 		 QFWD_SWITCH_PORT_MODE(port->portno));
1004 
1005 	/* Save the new values */
1006 	port->conf = *conf;
1007 
1008 	return 0;
1009 }
1010 
1011 /* Initialize port config to default */
sparx5_port_init(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)1012 int sparx5_port_init(struct sparx5 *sparx5,
1013 		     struct sparx5_port *port,
1014 		     struct sparx5_port_config *conf)
1015 {
1016 	u32 pause_start = sparx5_wm_enc(6  * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
1017 	u32 atop = sparx5_wm_enc(20 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
1018 	u32 devhigh = sparx5_to_high_dev(port->portno);
1019 	u32 pix = sparx5_port_dev_index(port->portno);
1020 	u32 pcs = sparx5_to_pcs_dev(port->portno);
1021 	bool sd_pol = port->signd_active_high;
1022 	bool sd_sel = !port->signd_internal;
1023 	bool sd_ena = port->signd_enable;
1024 	u32 pause_stop = 0xFFF - 1; /* FC generate disabled */
1025 	void __iomem *devinst;
1026 	void __iomem *pcsinst;
1027 	int err;
1028 
1029 	devinst = spx5_inst_get(sparx5, devhigh, pix);
1030 	pcsinst = spx5_inst_get(sparx5, pcs, pix);
1031 
1032 	/* Set the mux port mode  */
1033 	err = sparx5_port_mux_set(sparx5, port, conf);
1034 	if (err)
1035 		return err;
1036 
1037 	/* Configure MAC vlan awareness */
1038 	err = sparx5_port_max_tags_set(sparx5, port);
1039 	if (err)
1040 		return err;
1041 
1042 	/* Set Max Length */
1043 	spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
1044 		 DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
1045 		 sparx5,
1046 		 DEV2G5_MAC_MAXLEN_CFG(port->portno));
1047 
1048 	/* 1G/2G5: Signal Detect configuration */
1049 	spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
1050 		DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
1051 		DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
1052 		sparx5,
1053 		DEV2G5_PCS1G_SD_CFG(port->portno));
1054 
1055 	/* Set Pause WM hysteresis */
1056 	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_START_SET(pause_start) |
1057 		 QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop) |
1058 		 QSYS_PAUSE_CFG_PAUSE_ENA_SET(1),
1059 		 QSYS_PAUSE_CFG_PAUSE_START |
1060 		 QSYS_PAUSE_CFG_PAUSE_STOP |
1061 		 QSYS_PAUSE_CFG_PAUSE_ENA,
1062 		 sparx5,
1063 		 QSYS_PAUSE_CFG(port->portno));
1064 
1065 	/* Port ATOP. Frames are tail dropped when this WM is hit */
1066 	spx5_wr(QSYS_ATOP_ATOP_SET(atop),
1067 		sparx5,
1068 		QSYS_ATOP(port->portno));
1069 
1070 	/* Discard pause frame 01-80-C2-00-00-01 */
1071 	spx5_wr(PAUSE_DISCARD, sparx5, ANA_CL_CAPTURE_BPDU_CFG(port->portno));
1072 
1073 	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII ||
1074 	    conf->portmode == PHY_INTERFACE_MODE_SGMII) {
1075 		err = sparx5_serdes_set(sparx5, port, conf);
1076 		if (err)
1077 			return err;
1078 
1079 		if (!sparx5_port_is_2g5(port->portno))
1080 			/* Enable shadow device */
1081 			spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA_SET(1),
1082 				 DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA,
1083 				 sparx5,
1084 				 DSM_DEV_TX_STOP_WM_CFG(port->portno));
1085 
1086 		sparx5_dev_switch(sparx5, port->portno, false);
1087 	}
1088 	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII) {
1089 		// All ports must be PCS enabled in QSGMII mode
1090 		spx5_rmw(DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(0),
1091 			 DEV2G5_DEV_RST_CTRL_PCS_TX_RST,
1092 			 sparx5,
1093 			 DEV2G5_DEV_RST_CTRL(port->portno));
1094 	}
1095 	/* Default IFGs for 1G */
1096 	spx5_wr(DEV2G5_MAC_IFG_CFG_TX_IFG_SET(6) |
1097 		DEV2G5_MAC_IFG_CFG_RX_IFG1_SET(0) |
1098 		DEV2G5_MAC_IFG_CFG_RX_IFG2_SET(0),
1099 		sparx5,
1100 		DEV2G5_MAC_IFG_CFG(port->portno));
1101 
1102 	if (sparx5_port_is_2g5(port->portno))
1103 		return 0; /* Low speed device only - return */
1104 
1105 	/* Now setup the high speed device */
1106 	if (conf->portmode == PHY_INTERFACE_MODE_NA)
1107 		conf->portmode = PHY_INTERFACE_MODE_10GBASER;
1108 
1109 	if (sparx5_is_baser(conf->portmode))
1110 		sparx5_dev_switch(sparx5, port->portno, true);
1111 
1112 	/* Set Max Length */
1113 	spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
1114 		      DEV10G_MAC_MAXLEN_CFG_MAX_LEN,
1115 		      devinst,
1116 		      DEV10G_MAC_ENA_CFG(0));
1117 
1118 	/* Handle Signal Detect in 10G PCS */
1119 	spx5_inst_wr(PCS10G_BR_PCS_SD_CFG_SD_POL_SET(sd_pol) |
1120 		     PCS10G_BR_PCS_SD_CFG_SD_SEL_SET(sd_sel) |
1121 		     PCS10G_BR_PCS_SD_CFG_SD_ENA_SET(sd_ena),
1122 		     pcsinst,
1123 		     PCS10G_BR_PCS_SD_CFG(0));
1124 
1125 	if (sparx5_port_is_25g(port->portno)) {
1126 		/* Handle Signal Detect in 25G PCS */
1127 		spx5_wr(DEV25G_PCS25G_SD_CFG_SD_POL_SET(sd_pol) |
1128 			DEV25G_PCS25G_SD_CFG_SD_SEL_SET(sd_sel) |
1129 			DEV25G_PCS25G_SD_CFG_SD_ENA_SET(sd_ena),
1130 			sparx5,
1131 			DEV25G_PCS25G_SD_CFG(pix));
1132 	}
1133 
1134 	return 0;
1135 }
1136 
sparx5_port_enable(struct sparx5_port * port,bool enable)1137 void sparx5_port_enable(struct sparx5_port *port, bool enable)
1138 {
1139 	struct sparx5 *sparx5 = port->sparx5;
1140 
1141 	/* Enable port for frame transfer? */
1142 	spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(enable),
1143 		 QFWD_SWITCH_PORT_MODE_PORT_ENA,
1144 		 sparx5,
1145 		 QFWD_SWITCH_PORT_MODE(port->portno));
1146 }
1147