xref: /linux/drivers/net/ethernet/microchip/sparx5/sparx5_port.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
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 #include <net/dcbnl.h>
10 
11 #include "sparx5_main_regs.h"
12 #include "sparx5_main.h"
13 #include "sparx5_port.h"
14 #include "sparx5_qos.h"
15 
16 #define SPX5_ETYPE_TAG_C     0x8100
17 #define SPX5_ETYPE_TAG_S     0x88a8
18 
19 #define SPX5_WAIT_US         1000
20 #define SPX5_WAIT_MAX_US     2000
21 
22 enum port_error {
23 	SPX5_PERR_SPEED,
24 	SPX5_PERR_IFTYPE,
25 };
26 
27 #define PAUSE_DISCARD        0xC
28 #define ETH_MAXLEN           (ETH_DATA_LEN + ETH_HLEN + ETH_FCS_LEN)
29 
decode_sgmii_word(u16 lp_abil,struct sparx5_port_status * status)30 static void decode_sgmii_word(u16 lp_abil, struct sparx5_port_status *status)
31 {
32 	status->an_complete = true;
33 	if (!(lp_abil & LPA_SGMII_LINK)) {
34 		status->link = false;
35 		return;
36 	}
37 
38 	switch (lp_abil & LPA_SGMII_SPD_MASK) {
39 	case LPA_SGMII_10:
40 		status->speed = SPEED_10;
41 		break;
42 	case LPA_SGMII_100:
43 		status->speed = SPEED_100;
44 		break;
45 	case LPA_SGMII_1000:
46 		status->speed = SPEED_1000;
47 		break;
48 	default:
49 		status->link = false;
50 		return;
51 	}
52 	if (lp_abil & LPA_SGMII_FULL_DUPLEX)
53 		status->duplex = DUPLEX_FULL;
54 	else
55 		status->duplex = DUPLEX_HALF;
56 }
57 
decode_cl37_word(u16 lp_abil,uint16_t ld_abil,struct sparx5_port_status * status)58 static void decode_cl37_word(u16 lp_abil, uint16_t ld_abil, struct sparx5_port_status *status)
59 {
60 	status->link = !(lp_abil & ADVERTISE_RFAULT) && status->link;
61 	status->an_complete = true;
62 	status->duplex = (ADVERTISE_1000XFULL & lp_abil) ?
63 		DUPLEX_FULL : DUPLEX_UNKNOWN; // 1G HDX not supported
64 
65 	if ((ld_abil & ADVERTISE_1000XPAUSE) &&
66 	    (lp_abil & ADVERTISE_1000XPAUSE)) {
67 		status->pause = MLO_PAUSE_RX | MLO_PAUSE_TX;
68 	} else if ((ld_abil & ADVERTISE_1000XPSE_ASYM) &&
69 		   (lp_abil & ADVERTISE_1000XPSE_ASYM)) {
70 		status->pause |= (lp_abil & ADVERTISE_1000XPAUSE) ?
71 			MLO_PAUSE_TX : 0;
72 		status->pause |= (ld_abil & ADVERTISE_1000XPAUSE) ?
73 			MLO_PAUSE_RX : 0;
74 	} else {
75 		status->pause = MLO_PAUSE_NONE;
76 	}
77 }
78 
sparx5_get_dev2g5_status(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_status * status)79 static int sparx5_get_dev2g5_status(struct sparx5 *sparx5,
80 				    struct sparx5_port *port,
81 				    struct sparx5_port_status *status)
82 {
83 	u32 portno = port->portno;
84 	u16 lp_adv, ld_adv;
85 	u32 value;
86 
87 	/* Get PCS Link down sticky */
88 	value = spx5_rd(sparx5, DEV2G5_PCS1G_STICKY(portno));
89 	status->link_down = DEV2G5_PCS1G_STICKY_LINK_DOWN_STICKY_GET(value);
90 	if (status->link_down)	/* Clear the sticky */
91 		spx5_wr(value, sparx5, DEV2G5_PCS1G_STICKY(portno));
92 
93 	/* Get both current Link and Sync status */
94 	value = spx5_rd(sparx5, DEV2G5_PCS1G_LINK_STATUS(portno));
95 	status->link = DEV2G5_PCS1G_LINK_STATUS_LINK_STATUS_GET(value) &&
96 		       DEV2G5_PCS1G_LINK_STATUS_SYNC_STATUS_GET(value);
97 
98 	if (port->conf.portmode == PHY_INTERFACE_MODE_1000BASEX)
99 		status->speed = SPEED_1000;
100 	else if (port->conf.portmode == PHY_INTERFACE_MODE_2500BASEX)
101 		status->speed = SPEED_2500;
102 
103 	status->duplex = DUPLEX_FULL;
104 
105 	/* Get PCS ANEG status register */
106 	value = spx5_rd(sparx5, DEV2G5_PCS1G_ANEG_STATUS(portno));
107 
108 	/* Aneg complete provides more information  */
109 	if (DEV2G5_PCS1G_ANEG_STATUS_ANEG_COMPLETE_GET(value)) {
110 		lp_adv = DEV2G5_PCS1G_ANEG_STATUS_LP_ADV_ABILITY_GET(value);
111 		if (port->conf.portmode == PHY_INTERFACE_MODE_SGMII) {
112 			decode_sgmii_word(lp_adv, status);
113 		} else {
114 			value = spx5_rd(sparx5, DEV2G5_PCS1G_ANEG_CFG(portno));
115 			ld_adv = DEV2G5_PCS1G_ANEG_CFG_ADV_ABILITY_GET(value);
116 			decode_cl37_word(lp_adv, ld_adv, status);
117 		}
118 	}
119 	return 0;
120 }
121 
sparx5_get_sfi_status(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_status * status)122 static int sparx5_get_sfi_status(struct sparx5 *sparx5,
123 				 struct sparx5_port *port,
124 				 struct sparx5_port_status *status)
125 {
126 	bool high_speed_dev = sparx5_is_baser(port->conf.portmode);
127 	u32 portno = port->portno;
128 	u32 value, dev, tinst;
129 	void __iomem *inst;
130 
131 	if (!high_speed_dev) {
132 		netdev_err(port->ndev, "error: low speed and SFI mode\n");
133 		return -EINVAL;
134 	}
135 
136 	dev = sparx5_to_high_dev(sparx5, portno);
137 	tinst = sparx5_port_dev_index(sparx5, portno);
138 	inst = spx5_inst_get(sparx5, dev, tinst);
139 
140 	value = spx5_inst_rd(inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
141 	if (value != DEV10G_MAC_TX_MONITOR_STICKY_IDLE_STATE_STICKY) {
142 		/* The link is or has been down. Clear the sticky bit */
143 		status->link_down = 1;
144 		spx5_inst_wr(0xffffffff, inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
145 		value = spx5_inst_rd(inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
146 	}
147 	status->link = (value == DEV10G_MAC_TX_MONITOR_STICKY_IDLE_STATE_STICKY);
148 	status->duplex = DUPLEX_FULL;
149 	if (port->conf.portmode == PHY_INTERFACE_MODE_5GBASER)
150 		status->speed = SPEED_5000;
151 	else if (port->conf.portmode == PHY_INTERFACE_MODE_10GBASER)
152 		status->speed = SPEED_10000;
153 	else
154 		status->speed = SPEED_25000;
155 
156 	return 0;
157 }
158 
159 /* Get link status of 1000Base-X/in-band and SFI ports.
160  */
sparx5_get_port_status(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_status * status)161 int sparx5_get_port_status(struct sparx5 *sparx5,
162 			   struct sparx5_port *port,
163 			   struct sparx5_port_status *status)
164 {
165 	memset(status, 0, sizeof(*status));
166 	status->speed = port->conf.speed;
167 	if (port->conf.power_down) {
168 		status->link = false;
169 		return 0;
170 	}
171 	switch (port->conf.portmode) {
172 	case PHY_INTERFACE_MODE_SGMII:
173 	case PHY_INTERFACE_MODE_QSGMII:
174 	case PHY_INTERFACE_MODE_1000BASEX:
175 	case PHY_INTERFACE_MODE_2500BASEX:
176 		return sparx5_get_dev2g5_status(sparx5, port, status);
177 	case PHY_INTERFACE_MODE_5GBASER:
178 	case PHY_INTERFACE_MODE_10GBASER:
179 	case PHY_INTERFACE_MODE_25GBASER:
180 		return sparx5_get_sfi_status(sparx5, port, status);
181 	case PHY_INTERFACE_MODE_NA:
182 		return 0;
183 	default:
184 		netdev_err(port->ndev, "Status not supported");
185 		return -ENODEV;
186 	}
187 	return 0;
188 }
189 
sparx5_port_error(struct sparx5_port * port,struct sparx5_port_config * conf,enum port_error errtype)190 static int sparx5_port_error(struct sparx5_port *port,
191 			     struct sparx5_port_config *conf,
192 			     enum port_error errtype)
193 {
194 	switch (errtype) {
195 	case SPX5_PERR_SPEED:
196 		netdev_err(port->ndev,
197 			   "Interface does not support speed: %u: for %s\n",
198 			   conf->speed, phy_modes(conf->portmode));
199 		break;
200 	case SPX5_PERR_IFTYPE:
201 		netdev_err(port->ndev,
202 			   "Switch port does not support interface type: %s\n",
203 			   phy_modes(conf->portmode));
204 		break;
205 	default:
206 		netdev_err(port->ndev,
207 			   "Interface configuration error\n");
208 	}
209 
210 	return -EINVAL;
211 }
212 
sparx5_port_verify_speed(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)213 static int sparx5_port_verify_speed(struct sparx5 *sparx5,
214 				    struct sparx5_port *port,
215 				    struct sparx5_port_config *conf)
216 {
217 	const struct sparx5_ops *ops = sparx5->data->ops;
218 
219 	if ((ops->is_port_2g5(port->portno) &&
220 	     conf->speed > SPEED_2500) ||
221 	    (ops->is_port_5g(port->portno)  &&
222 	     conf->speed > SPEED_5000) ||
223 	    (ops->is_port_10g(port->portno) &&
224 	     conf->speed > SPEED_10000))
225 		return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
226 
227 	switch (conf->portmode) {
228 	case PHY_INTERFACE_MODE_NA:
229 		return -EINVAL;
230 	case PHY_INTERFACE_MODE_1000BASEX:
231 		if (conf->speed != SPEED_1000 ||
232 		    ops->is_port_2g5(port->portno))
233 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
234 		if (ops->is_port_2g5(port->portno))
235 			return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
236 		break;
237 	case PHY_INTERFACE_MODE_2500BASEX:
238 		if (conf->speed != SPEED_2500 ||
239 		    ops->is_port_2g5(port->portno))
240 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
241 		break;
242 	case PHY_INTERFACE_MODE_QSGMII:
243 		if (port->portno > 47)
244 			return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
245 		fallthrough;
246 	case PHY_INTERFACE_MODE_SGMII:
247 		if (conf->speed != SPEED_1000 &&
248 		    conf->speed != SPEED_100 &&
249 		    conf->speed != SPEED_10 &&
250 		    conf->speed != SPEED_2500)
251 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
252 		break;
253 	case PHY_INTERFACE_MODE_5GBASER:
254 	case PHY_INTERFACE_MODE_10GBASER:
255 	case PHY_INTERFACE_MODE_25GBASER:
256 		if ((conf->speed != SPEED_5000 &&
257 		     conf->speed != SPEED_10000 &&
258 		     conf->speed != SPEED_25000))
259 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
260 		break;
261 	case PHY_INTERFACE_MODE_RGMII:
262 	case PHY_INTERFACE_MODE_RGMII_ID:
263 	case PHY_INTERFACE_MODE_RGMII_TXID:
264 	case PHY_INTERFACE_MODE_RGMII_RXID:
265 		if (conf->speed != SPEED_1000 &&
266 		    conf->speed != SPEED_100 &&
267 		    conf->speed != SPEED_10)
268 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
269 		break;
270 	default:
271 		return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
272 	}
273 	return 0;
274 }
275 
sparx5_dev_change(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)276 static bool sparx5_dev_change(struct sparx5 *sparx5,
277 			      struct sparx5_port *port,
278 			      struct sparx5_port_config *conf)
279 {
280 	return sparx5_is_baser(port->conf.portmode) ^
281 		sparx5_is_baser(conf->portmode);
282 }
283 
sparx5_port_flush_poll(struct sparx5 * sparx5,u32 portno)284 static int sparx5_port_flush_poll(struct sparx5 *sparx5, u32 portno)
285 {
286 	u32  value, resource, prio, delay_cnt = 0;
287 	bool poll_src = true;
288 	char *mem = "";
289 
290 	/* Resource == 0: Memory tracked per source (SRC-MEM)
291 	 * Resource == 1: Frame references tracked per source (SRC-REF)
292 	 * Resource == 2: Memory tracked per destination (DST-MEM)
293 	 * Resource == 3: Frame references tracked per destination. (DST-REF)
294 	 */
295 	while (1) {
296 		bool empty = true;
297 
298 		for (resource = 0; resource < (poll_src ? 2 : 1); resource++) {
299 			u32 base;
300 
301 			base = (resource == 0 ? 2048 : 0) + SPX5_PRIOS * portno;
302 			for (prio = 0; prio < SPX5_PRIOS; prio++) {
303 				value = spx5_rd(sparx5,
304 						QRES_RES_STAT(base + prio));
305 				if (value) {
306 					mem = resource == 0 ?
307 						"DST-MEM" : "SRC-MEM";
308 					empty = false;
309 				}
310 			}
311 		}
312 
313 		if (empty)
314 			break;
315 
316 		if (delay_cnt++ == 2000) {
317 			dev_err(sparx5->dev,
318 				"Flush timeout port %u. %s queue not empty\n",
319 				portno, mem);
320 			return -EINVAL;
321 		}
322 
323 		usleep_range(SPX5_WAIT_US, SPX5_WAIT_MAX_US);
324 	}
325 	return 0;
326 }
327 
sparx5_port_disable(struct sparx5 * sparx5,struct sparx5_port * port,bool high_spd_dev)328 static int sparx5_port_disable(struct sparx5 *sparx5, struct sparx5_port *port, bool high_spd_dev)
329 {
330 	u32 tinst = high_spd_dev ?
331 		    sparx5_port_dev_index(sparx5, port->portno) : port->portno;
332 	u32 dev = high_spd_dev ?
333 		  sparx5_to_high_dev(sparx5, port->portno) : TARGET_DEV2G5;
334 	void __iomem *devinst = spx5_inst_get(sparx5, dev, tinst);
335 	const struct sparx5_ops *ops = sparx5->data->ops;
336 	u32 spd = port->conf.speed;
337 	u32 spd_prm;
338 	int err;
339 
340 	if (high_spd_dev) {
341 		/* 1: Reset the PCS Rx clock domain  */
342 		spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_RX_RST,
343 			      DEV10G_DEV_RST_CTRL_PCS_RX_RST,
344 			      devinst,
345 			      DEV10G_DEV_RST_CTRL(0));
346 
347 		/* 2: Disable MAC frame reception */
348 		spx5_inst_rmw(0,
349 			      DEV10G_MAC_ENA_CFG_RX_ENA,
350 			      devinst,
351 			      DEV10G_MAC_ENA_CFG(0));
352 	} else {
353 		/* 1: Reset the PCS Rx clock domain  */
354 		spx5_inst_rmw(DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
355 			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
356 			      devinst,
357 			      DEV2G5_DEV_RST_CTRL(0));
358 		/* 2: Disable MAC frame reception */
359 		spx5_inst_rmw(0,
360 			      DEV2G5_MAC_ENA_CFG_RX_ENA,
361 			      devinst,
362 			      DEV2G5_MAC_ENA_CFG(0));
363 	}
364 	/* 3: Disable traffic being sent to or from switch port->portno */
365 	spx5_rmw(0,
366 		 QFWD_SWITCH_PORT_MODE_PORT_ENA,
367 		 sparx5,
368 		 QFWD_SWITCH_PORT_MODE(port->portno));
369 
370 	/* 4: Disable dequeuing from the egress queues  */
371 	spx5_rmw(HSCH_PORT_MODE_DEQUEUE_DIS,
372 		 HSCH_PORT_MODE_DEQUEUE_DIS,
373 		 sparx5,
374 		 HSCH_PORT_MODE(port->portno));
375 
376 	/* 5: Disable Flowcontrol */
377 	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_STOP_SET(0xFFF - 1),
378 		 QSYS_PAUSE_CFG_PAUSE_STOP,
379 		 sparx5,
380 		 QSYS_PAUSE_CFG(port->portno));
381 
382 	spd_prm = spd == SPEED_10 ? 1000 : spd == SPEED_100 ? 100 : 10;
383 	/* 6: Wait while the last frame is exiting the queues */
384 	usleep_range(8 * spd_prm, 10 * spd_prm);
385 
386 	/* 7: Flush the queues associated with the port->portno */
387 	spx5_rmw(HSCH_FLUSH_CTRL_FLUSH_PORT_SET(port->portno) |
388 		 HSCH_FLUSH_CTRL_FLUSH_DST_SET(1) |
389 		 HSCH_FLUSH_CTRL_FLUSH_SRC_SET(1) |
390 		 HSCH_FLUSH_CTRL_FLUSH_ENA_SET(1),
391 		 HSCH_FLUSH_CTRL_FLUSH_PORT |
392 		 HSCH_FLUSH_CTRL_FLUSH_DST |
393 		 HSCH_FLUSH_CTRL_FLUSH_SRC |
394 		 HSCH_FLUSH_CTRL_FLUSH_ENA,
395 		 sparx5,
396 		 HSCH_FLUSH_CTRL);
397 
398 	/* 8: Enable dequeuing from the egress queues */
399 	spx5_rmw(0,
400 		 HSCH_PORT_MODE_DEQUEUE_DIS,
401 		 sparx5,
402 		 HSCH_PORT_MODE(port->portno));
403 
404 	/* 9: Wait until flushing is complete */
405 	err = sparx5_port_flush_poll(sparx5, port->portno);
406 	if (err)
407 		return err;
408 
409 	/* 10: Reset the  MAC clock domain */
410 	if (high_spd_dev) {
411 		spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_TX_RST_SET(1) |
412 			      DEV10G_DEV_RST_CTRL_MAC_RX_RST_SET(1) |
413 			      DEV10G_DEV_RST_CTRL_MAC_TX_RST_SET(1),
414 			      DEV10G_DEV_RST_CTRL_PCS_TX_RST |
415 			      DEV10G_DEV_RST_CTRL_MAC_RX_RST |
416 			      DEV10G_DEV_RST_CTRL_MAC_TX_RST,
417 			      devinst,
418 			      DEV10G_DEV_RST_CTRL(0));
419 
420 	} else {
421 		spx5_inst_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(3) |
422 			      DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(1) |
423 			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST_SET(1) |
424 			      DEV2G5_DEV_RST_CTRL_MAC_TX_RST_SET(1) |
425 			      DEV2G5_DEV_RST_CTRL_MAC_RX_RST_SET(1),
426 			      DEV2G5_DEV_RST_CTRL_SPEED_SEL |
427 			      DEV2G5_DEV_RST_CTRL_PCS_TX_RST |
428 			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST |
429 			      DEV2G5_DEV_RST_CTRL_MAC_TX_RST |
430 			      DEV2G5_DEV_RST_CTRL_MAC_RX_RST,
431 			      devinst,
432 			      DEV2G5_DEV_RST_CTRL(0));
433 	}
434 	/* 11: Clear flushing */
435 	spx5_rmw(HSCH_FLUSH_CTRL_FLUSH_PORT_SET(port->portno) |
436 		 HSCH_FLUSH_CTRL_FLUSH_ENA_SET(0),
437 		 HSCH_FLUSH_CTRL_FLUSH_PORT |
438 		 HSCH_FLUSH_CTRL_FLUSH_ENA,
439 		 sparx5,
440 		 HSCH_FLUSH_CTRL);
441 
442 	if (high_spd_dev) {
443 		u32 pcs = sparx5_to_pcs_dev(sparx5, port->portno);
444 		void __iomem *pcsinst = spx5_inst_get(sparx5, pcs, tinst);
445 
446 		/* 12: Disable 5G/10G/25 BaseR PCS */
447 		spx5_inst_rmw(PCS10G_BR_PCS_CFG_PCS_ENA_SET(0),
448 			      PCS10G_BR_PCS_CFG_PCS_ENA,
449 			      pcsinst,
450 			      PCS10G_BR_PCS_CFG(0));
451 
452 		if (ops->is_port_25g(port->portno))
453 			/* Disable 25G PCS */
454 			spx5_rmw(DEV25G_PCS25G_CFG_PCS25G_ENA_SET(0),
455 				 DEV25G_PCS25G_CFG_PCS25G_ENA,
456 				 sparx5,
457 				 DEV25G_PCS25G_CFG(tinst));
458 	} else {
459 		/* 12: Disable 1G PCS */
460 		spx5_rmw(DEV2G5_PCS1G_CFG_PCS_ENA_SET(0),
461 			 DEV2G5_PCS1G_CFG_PCS_ENA,
462 			 sparx5,
463 			 DEV2G5_PCS1G_CFG(port->portno));
464 	}
465 
466 	/* The port is now flushed and disabled  */
467 	return 0;
468 }
469 
sparx5_port_fifo_sz(struct sparx5 * sparx5,u32 portno,u32 speed)470 static int sparx5_port_fifo_sz(struct sparx5 *sparx5,
471 			       u32 portno, u32 speed)
472 {
473 	u32 sys_clk = sparx5_clk_period(sparx5->coreclock);
474 	const u32 taxi_dist[SPX5_PORTS_ALL] = {
475 		6, 8, 10, 6, 8, 10, 6, 8, 10, 6, 8, 10,
476 		4, 4, 4, 4,
477 		11, 12, 13, 14, 15, 16, 17, 18,
478 		11, 12, 13, 14, 15, 16, 17, 18,
479 		11, 12, 13, 14, 15, 16, 17, 18,
480 		11, 12, 13, 14, 15, 16, 17, 18,
481 		4, 6, 8, 4, 6, 8, 6, 8,
482 		2, 2, 2, 2, 2, 2, 2, 4, 2
483 	};
484 	u32 mac_per    = 6400, tmp1, tmp2, tmp3;
485 	u32 fifo_width = 16;
486 	u32 mac_width  = 8;
487 	u32 addition   = 0;
488 
489 	if (!is_sparx5(sparx5))
490 		return 0;
491 
492 	switch (speed) {
493 	case SPEED_25000:
494 		return 0;
495 	case SPEED_10000:
496 		mac_per = 6400;
497 		mac_width = 8;
498 		addition = 1;
499 		break;
500 	case SPEED_5000:
501 		mac_per = 12800;
502 		mac_width = 8;
503 		addition = 0;
504 		break;
505 	case SPEED_2500:
506 		mac_per = 3200;
507 		mac_width = 1;
508 		addition = 0;
509 		break;
510 	case SPEED_1000:
511 		mac_per =  8000;
512 		mac_width = 1;
513 		addition = 0;
514 		break;
515 	case SPEED_100:
516 	case SPEED_10:
517 		return 1;
518 	default:
519 		break;
520 	}
521 
522 	tmp1 = 1000 * mac_width / fifo_width;
523 	tmp2 = 3000 + ((12000 + 2 * taxi_dist[portno] * 1000)
524 		       * sys_clk / mac_per);
525 	tmp3 = tmp1 * tmp2 / 1000;
526 	return  (tmp3 + 2000 + 999) / 1000 + addition;
527 }
528 
529 /* Configure port muxing:
530  * QSGMII:     4x2G5 devices
531  */
sparx5_port_mux_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)532 int sparx5_port_mux_set(struct sparx5 *sparx5, struct sparx5_port *port,
533 			struct sparx5_port_config *conf)
534 {
535 	u32 portno = port->portno;
536 	u32 inst;
537 
538 	if (port->conf.portmode == conf->portmode)
539 		return 0; /* Nothing to do */
540 
541 	switch (conf->portmode) {
542 	case PHY_INTERFACE_MODE_QSGMII: /* QSGMII: 4x2G5 devices. Mode Q'  */
543 		inst = (portno - portno % 4) / 4;
544 		spx5_rmw(BIT(inst),
545 			 BIT(inst),
546 			 sparx5,
547 			 PORT_CONF_QSGMII_ENA);
548 
549 		if ((portno / 4 % 2) == 0) {
550 			/* Affects d0-d3,d8-d11..d40-d43 */
551 			spx5_rmw(PORT_CONF_USGMII_CFG_BYPASS_SCRAM_SET(1) |
552 				 PORT_CONF_USGMII_CFG_BYPASS_DESCRAM_SET(1) |
553 				 PORT_CONF_USGMII_CFG_QUAD_MODE_SET(1),
554 				 PORT_CONF_USGMII_CFG_BYPASS_SCRAM |
555 				 PORT_CONF_USGMII_CFG_BYPASS_DESCRAM |
556 				 PORT_CONF_USGMII_CFG_QUAD_MODE,
557 				 sparx5,
558 				 PORT_CONF_USGMII_CFG((portno / 8)));
559 		}
560 		break;
561 	default:
562 		break;
563 	}
564 	return 0;
565 }
566 
sparx5_port_max_tags_set(struct sparx5 * sparx5,struct sparx5_port * port)567 static int sparx5_port_max_tags_set(struct sparx5 *sparx5,
568 				    struct sparx5_port *port)
569 {
570 	enum sparx5_port_max_tags max_tags    = port->max_vlan_tags;
571 	int tag_ct          = max_tags == SPX5_PORT_MAX_TAGS_ONE ? 1 :
572 			      max_tags == SPX5_PORT_MAX_TAGS_TWO ? 2 : 0;
573 	bool dtag           = max_tags == SPX5_PORT_MAX_TAGS_TWO;
574 	enum sparx5_vlan_port_type vlan_type  = port->vlan_type;
575 	bool dotag          = max_tags != SPX5_PORT_MAX_TAGS_NONE;
576 	u32 dev             = sparx5_to_high_dev(sparx5, port->portno);
577 	u32 tinst           = sparx5_port_dev_index(sparx5, port->portno);
578 	void __iomem *inst  = spx5_inst_get(sparx5, dev, tinst);
579 	const struct sparx5_ops *ops = sparx5->data->ops;
580 	u32 etype;
581 
582 	etype = (vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ?
583 		 port->custom_etype :
584 		 vlan_type == SPX5_VLAN_PORT_TYPE_C ?
585 		 SPX5_ETYPE_TAG_C : SPX5_ETYPE_TAG_S);
586 
587 	spx5_wr(DEV2G5_MAC_TAGS_CFG_TAG_ID_SET(etype) |
588 		DEV2G5_MAC_TAGS_CFG_PB_ENA_SET(dtag) |
589 		DEV2G5_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(dotag) |
590 		DEV2G5_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(dotag),
591 		sparx5,
592 		DEV2G5_MAC_TAGS_CFG(port->portno));
593 
594 	if (ops->is_port_2g5(port->portno))
595 		return 0;
596 
597 	spx5_inst_rmw(DEV10G_MAC_TAGS_CFG_TAG_ID_SET(etype) |
598 		      DEV10G_MAC_TAGS_CFG_TAG_ENA_SET(dotag),
599 		      DEV10G_MAC_TAGS_CFG_TAG_ID |
600 		      DEV10G_MAC_TAGS_CFG_TAG_ENA,
601 		      inst,
602 		      DEV10G_MAC_TAGS_CFG(0, 0));
603 
604 	spx5_inst_rmw(DEV10G_MAC_NUM_TAGS_CFG_NUM_TAGS_SET(tag_ct),
605 		      DEV10G_MAC_NUM_TAGS_CFG_NUM_TAGS,
606 		      inst,
607 		      DEV10G_MAC_NUM_TAGS_CFG(0));
608 
609 	spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_TAG_CHK_SET(dotag),
610 		      DEV10G_MAC_MAXLEN_CFG_MAX_LEN_TAG_CHK,
611 		      inst,
612 		      DEV10G_MAC_MAXLEN_CFG(0));
613 	return 0;
614 }
615 
sparx5_port_fwd_urg(struct sparx5 * sparx5,u32 speed)616 int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed)
617 {
618 	u32 clk_period_ps = 1600; /* 625Mhz for now */
619 	u32 urg = 672000;
620 
621 	switch (speed) {
622 	case SPEED_10:
623 	case SPEED_100:
624 	case SPEED_1000:
625 		urg = 672000;
626 		break;
627 	case SPEED_2500:
628 		urg = 270000;
629 		break;
630 	case SPEED_5000:
631 		urg = 135000;
632 		break;
633 	case SPEED_10000:
634 		urg = 67200;
635 		break;
636 	case SPEED_25000:
637 		urg = 27000;
638 		break;
639 	}
640 	return urg / clk_period_ps - 1;
641 }
642 
sparx5_wm_enc(u16 value)643 static u16 sparx5_wm_enc(u16 value)
644 {
645 	if (value >= 2048)
646 		return 2048 + value / 16;
647 
648 	return value;
649 }
650 
sparx5_port_fc_setup(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)651 static int sparx5_port_fc_setup(struct sparx5 *sparx5,
652 				struct sparx5_port *port,
653 				struct sparx5_port_config *conf)
654 {
655 	bool fc_obey = conf->pause & MLO_PAUSE_RX ? 1 : 0;
656 	u32 pause_stop = 0xFFF - 1; /* FC gen disabled */
657 
658 	if (conf->pause & MLO_PAUSE_TX)
659 		pause_stop = sparx5_wm_enc(4  * (ETH_MAXLEN /
660 						 SPX5_BUFFER_CELL_SZ));
661 
662 	/* Set HDX flowcontrol */
663 	spx5_rmw(DSM_MAC_CFG_HDX_BACKPREASSURE_SET(conf->duplex == DUPLEX_HALF),
664 		 DSM_MAC_CFG_HDX_BACKPREASSURE,
665 		 sparx5,
666 		 DSM_MAC_CFG(port->portno));
667 
668 	/* Obey flowcontrol  */
669 	spx5_rmw(DSM_RX_PAUSE_CFG_RX_PAUSE_EN_SET(fc_obey),
670 		 DSM_RX_PAUSE_CFG_RX_PAUSE_EN,
671 		 sparx5,
672 		 DSM_RX_PAUSE_CFG(port->portno));
673 
674 	/* Disable forward pressure */
675 	spx5_rmw(QSYS_FWD_PRESSURE_FWD_PRESSURE_DIS_SET(fc_obey),
676 		 QSYS_FWD_PRESSURE_FWD_PRESSURE_DIS,
677 		 sparx5,
678 		 QSYS_FWD_PRESSURE(port->portno));
679 
680 	/* Generate pause frames */
681 	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop),
682 		 QSYS_PAUSE_CFG_PAUSE_STOP,
683 		 sparx5,
684 		 QSYS_PAUSE_CFG(port->portno));
685 
686 	return 0;
687 }
688 
sparx5_get_aneg_word(struct sparx5_port_config * conf)689 static u16 sparx5_get_aneg_word(struct sparx5_port_config *conf)
690 {
691 	if (conf->portmode == PHY_INTERFACE_MODE_1000BASEX) /* cl-37 aneg */
692 		return (conf->pause_adv | ADVERTISE_LPACK | ADVERTISE_1000XFULL);
693 	else
694 		return 1; /* Enable SGMII Aneg */
695 }
696 
sparx5_serdes_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)697 int sparx5_serdes_set(struct sparx5 *sparx5,
698 		      struct sparx5_port *port,
699 		      struct sparx5_port_config *conf)
700 {
701 	int portmode, err, speed = conf->speed;
702 
703 	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII &&
704 	    ((port->portno % 4) != 0)) {
705 		return 0;
706 	}
707 	if (sparx5_is_baser(conf->portmode)) {
708 		if (conf->portmode == PHY_INTERFACE_MODE_25GBASER)
709 			speed = SPEED_25000;
710 		else if (conf->portmode == PHY_INTERFACE_MODE_10GBASER)
711 			speed = SPEED_10000;
712 		else
713 			speed = SPEED_5000;
714 	}
715 
716 	err = phy_set_media(port->serdes, conf->media);
717 	if (err)
718 		return err;
719 	if (speed > 0) {
720 		err = phy_set_speed(port->serdes, speed);
721 		if (err)
722 			return err;
723 	}
724 	if (conf->serdes_reset) {
725 		err = phy_reset(port->serdes);
726 		if (err)
727 			return err;
728 	}
729 
730 	/* Configure SerDes with port parameters
731 	 * For BaseR, the serdes driver supports 10GGBASE-R and speed 5G/10G/25G
732 	 */
733 	portmode = conf->portmode;
734 	if (sparx5_is_baser(conf->portmode))
735 		portmode = PHY_INTERFACE_MODE_10GBASER;
736 	err = phy_set_mode_ext(port->serdes, PHY_MODE_ETHERNET, portmode);
737 	if (err)
738 		return err;
739 	conf->serdes_reset = false;
740 	return err;
741 }
742 
sparx5_port_pcs_low_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)743 static int sparx5_port_pcs_low_set(struct sparx5 *sparx5,
744 				   struct sparx5_port *port,
745 				   struct sparx5_port_config *conf)
746 {
747 	bool sgmii = false, inband_aneg = false;
748 	int err;
749 
750 	if (conf->inband) {
751 		if (conf->portmode == PHY_INTERFACE_MODE_SGMII ||
752 		    conf->portmode == PHY_INTERFACE_MODE_QSGMII)
753 			inband_aneg = true; /* Cisco-SGMII in-band-aneg */
754 		else if (conf->portmode == PHY_INTERFACE_MODE_1000BASEX &&
755 			 conf->autoneg)
756 			inband_aneg = true; /* Clause-37 in-band-aneg */
757 
758 		err = sparx5_serdes_set(sparx5, port, conf);
759 		if (err)
760 			return -EINVAL;
761 	} else {
762 		sgmii = true; /* Phy is connected to the MAC */
763 	}
764 
765 	/* Choose SGMII or 1000BaseX/2500BaseX PCS mode */
766 	spx5_rmw(DEV2G5_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(sgmii),
767 		 DEV2G5_PCS1G_MODE_CFG_SGMII_MODE_ENA,
768 		 sparx5,
769 		 DEV2G5_PCS1G_MODE_CFG(port->portno));
770 
771 	/* Enable PCS */
772 	spx5_wr(DEV2G5_PCS1G_CFG_PCS_ENA_SET(1),
773 		sparx5,
774 		DEV2G5_PCS1G_CFG(port->portno));
775 
776 	if (inband_aneg) {
777 		u16 abil = sparx5_get_aneg_word(conf);
778 
779 		/* Enable in-band aneg */
780 		spx5_wr(DEV2G5_PCS1G_ANEG_CFG_ADV_ABILITY_SET(abil) |
781 			DEV2G5_PCS1G_ANEG_CFG_SW_RESOLVE_ENA_SET(1) |
782 			DEV2G5_PCS1G_ANEG_CFG_ANEG_ENA_SET(1) |
783 			DEV2G5_PCS1G_ANEG_CFG_ANEG_RESTART_ONE_SHOT_SET(1),
784 			sparx5,
785 			DEV2G5_PCS1G_ANEG_CFG(port->portno));
786 	} else {
787 		spx5_wr(0, sparx5, DEV2G5_PCS1G_ANEG_CFG(port->portno));
788 	}
789 
790 	/* Take PCS out of reset */
791 	spx5_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(2) |
792 		 DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(0) |
793 		 DEV2G5_DEV_RST_CTRL_PCS_RX_RST_SET(0),
794 		 DEV2G5_DEV_RST_CTRL_SPEED_SEL |
795 		 DEV2G5_DEV_RST_CTRL_PCS_TX_RST |
796 		 DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
797 		 sparx5,
798 		 DEV2G5_DEV_RST_CTRL(port->portno));
799 
800 	return 0;
801 }
802 
sparx5_port_pcs_high_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)803 static int sparx5_port_pcs_high_set(struct sparx5 *sparx5,
804 				    struct sparx5_port *port,
805 				    struct sparx5_port_config *conf)
806 {
807 	u32 clk_spd = conf->portmode == PHY_INTERFACE_MODE_5GBASER ? 1 : 0;
808 	u32 pix = sparx5_port_dev_index(sparx5, port->portno);
809 	u32 dev = sparx5_to_high_dev(sparx5, port->portno);
810 	u32 pcs = sparx5_to_pcs_dev(sparx5, port->portno);
811 	void __iomem *devinst;
812 	void __iomem *pcsinst;
813 	int err;
814 
815 	devinst = spx5_inst_get(sparx5, dev, pix);
816 	pcsinst = spx5_inst_get(sparx5, pcs, pix);
817 
818 	/*  SFI : No in-band-aneg. Speeds 5G/10G/25G */
819 	err = sparx5_serdes_set(sparx5, port, conf);
820 	if (err)
821 		return -EINVAL;
822 	if (conf->portmode == PHY_INTERFACE_MODE_25GBASER) {
823 		/* Enable PCS for 25G device, speed 25G */
824 		spx5_rmw(DEV25G_PCS25G_CFG_PCS25G_ENA_SET(1),
825 			 DEV25G_PCS25G_CFG_PCS25G_ENA,
826 			 sparx5,
827 			 DEV25G_PCS25G_CFG(pix));
828 	} else {
829 		/* Enable PCS for 5G/10G/25G devices, speed 5G/10G */
830 		spx5_inst_rmw(PCS10G_BR_PCS_CFG_PCS_ENA_SET(1),
831 			      PCS10G_BR_PCS_CFG_PCS_ENA,
832 			      pcsinst,
833 			      PCS10G_BR_PCS_CFG(0));
834 	}
835 
836 	/* Enable 5G/10G/25G MAC module */
837 	spx5_inst_wr(DEV10G_MAC_ENA_CFG_RX_ENA_SET(1) |
838 		     DEV10G_MAC_ENA_CFG_TX_ENA_SET(1),
839 		     devinst,
840 		     DEV10G_MAC_ENA_CFG(0));
841 
842 	/* Take the device out of reset */
843 	spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_RX_RST_SET(0) |
844 		      DEV10G_DEV_RST_CTRL_PCS_TX_RST_SET(0) |
845 		      DEV10G_DEV_RST_CTRL_MAC_RX_RST_SET(0) |
846 		      DEV10G_DEV_RST_CTRL_MAC_TX_RST_SET(0) |
847 		      DEV10G_DEV_RST_CTRL_SPEED_SEL_SET(clk_spd),
848 		      DEV10G_DEV_RST_CTRL_PCS_RX_RST |
849 		      DEV10G_DEV_RST_CTRL_PCS_TX_RST |
850 		      DEV10G_DEV_RST_CTRL_MAC_RX_RST |
851 		      DEV10G_DEV_RST_CTRL_MAC_TX_RST |
852 		      DEV10G_DEV_RST_CTRL_SPEED_SEL,
853 		      devinst,
854 		      DEV10G_DEV_RST_CTRL(0));
855 
856 	return 0;
857 }
858 
859 /* Switch between 1G/2500 and 5G/10G/25G devices */
sparx5_dev_switch(struct sparx5 * sparx5,int port,bool hsd)860 static void sparx5_dev_switch(struct sparx5 *sparx5, int port, bool hsd)
861 {
862 	const struct sparx5_ops *ops = sparx5->data->ops;
863 	int bt_indx;
864 
865 	bt_indx = BIT(ops->get_port_dev_bit(sparx5, port));
866 
867 	if (ops->is_port_5g(port)) {
868 		spx5_rmw(hsd ? 0 : bt_indx,
869 			 bt_indx,
870 			 sparx5,
871 			 PORT_CONF_DEV5G_MODES);
872 	} else if (ops->is_port_10g(port)) {
873 		spx5_rmw(hsd ? 0 : bt_indx,
874 			 bt_indx,
875 			 sparx5,
876 			 PORT_CONF_DEV10G_MODES);
877 	} else if (ops->is_port_25g(port)) {
878 		spx5_rmw(hsd ? 0 : bt_indx,
879 			 bt_indx,
880 			 sparx5,
881 			 PORT_CONF_DEV25G_MODES);
882 	}
883 }
884 
885 /* Configure speed/duplex dependent registers */
sparx5_port_config_low_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)886 static int sparx5_port_config_low_set(struct sparx5 *sparx5,
887 				      struct sparx5_port *port,
888 				      struct sparx5_port_config *conf)
889 {
890 	u32 clk_spd, gig_mode, tx_gap, hdx_gap_1, hdx_gap_2;
891 	bool fdx = conf->duplex == DUPLEX_FULL;
892 	int spd = conf->speed;
893 
894 	clk_spd = spd == SPEED_10 ? 0 : spd == SPEED_100 ? 1 : 2;
895 	gig_mode = spd == SPEED_1000 || spd == SPEED_2500;
896 	tx_gap = spd == SPEED_1000 ? 4 : fdx ? 6 : 5;
897 	hdx_gap_1 = spd == SPEED_1000 ? 0 : spd == SPEED_100 ? 1 : 2;
898 	hdx_gap_2 = spd == SPEED_1000 ? 0 : spd == SPEED_100 ? 4 : 1;
899 
900 	/* GIG/FDX mode */
901 	spx5_rmw(DEV2G5_MAC_MODE_CFG_GIGA_MODE_ENA_SET(gig_mode) |
902 		 DEV2G5_MAC_MODE_CFG_FDX_ENA_SET(fdx),
903 		 DEV2G5_MAC_MODE_CFG_GIGA_MODE_ENA |
904 		 DEV2G5_MAC_MODE_CFG_FDX_ENA,
905 		 sparx5,
906 		 DEV2G5_MAC_MODE_CFG(port->portno));
907 
908 	/* Set MAC IFG Gaps */
909 	spx5_wr(DEV2G5_MAC_IFG_CFG_TX_IFG_SET(tx_gap) |
910 		DEV2G5_MAC_IFG_CFG_RX_IFG1_SET(hdx_gap_1) |
911 		DEV2G5_MAC_IFG_CFG_RX_IFG2_SET(hdx_gap_2),
912 		sparx5,
913 		DEV2G5_MAC_IFG_CFG(port->portno));
914 
915 	/* Disabling frame aging when in HDX (due to HDX issue) */
916 	spx5_rmw(HSCH_PORT_MODE_AGE_DIS_SET(fdx == 0),
917 		 HSCH_PORT_MODE_AGE_DIS,
918 		 sparx5,
919 		 HSCH_PORT_MODE(port->portno));
920 
921 	/* Enable MAC module */
922 	spx5_wr(DEV2G5_MAC_ENA_CFG_RX_ENA |
923 		DEV2G5_MAC_ENA_CFG_TX_ENA,
924 		sparx5,
925 		DEV2G5_MAC_ENA_CFG(port->portno));
926 
927 	/* Select speed and take MAC out of reset */
928 	spx5_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(clk_spd) |
929 		 DEV2G5_DEV_RST_CTRL_MAC_TX_RST_SET(0) |
930 		 DEV2G5_DEV_RST_CTRL_MAC_RX_RST_SET(0),
931 		 DEV2G5_DEV_RST_CTRL_SPEED_SEL |
932 		 DEV2G5_DEV_RST_CTRL_MAC_TX_RST |
933 		 DEV2G5_DEV_RST_CTRL_MAC_RX_RST,
934 		 sparx5,
935 		 DEV2G5_DEV_RST_CTRL(port->portno));
936 
937 	/* Enable PHAD_CTRL for better timestamping */
938 	if (!is_sparx5(sparx5)) {
939 		for (int i = 0; i < 2; ++i) {
940 			/* Divide the port clock by three for the two
941 			 * phase detection registers.
942 			 */
943 			spx5_rmw(DEV2G5_PHAD_CTRL_DIV_CFG_SET(3) |
944 				 DEV2G5_PHAD_CTRL_PHAD_ENA_SET(1),
945 				 DEV2G5_PHAD_CTRL_DIV_CFG |
946 				 DEV2G5_PHAD_CTRL_PHAD_ENA,
947 				 sparx5, DEV2G5_PHAD_CTRL(port->portno, i));
948 		}
949 	}
950 
951 	return 0;
952 }
953 
sparx5_port_pcs_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)954 int sparx5_port_pcs_set(struct sparx5 *sparx5,
955 			struct sparx5_port *port,
956 			struct sparx5_port_config *conf)
957 
958 {
959 	bool high_speed_dev = sparx5_is_baser(conf->portmode);
960 	int err;
961 
962 	if (sparx5_dev_change(sparx5, port, conf)) {
963 		/* switch device */
964 		sparx5_dev_switch(sparx5, port->portno, high_speed_dev);
965 
966 		/* Disable the not-in-use device */
967 		err = sparx5_port_disable(sparx5, port, !high_speed_dev);
968 		if (err)
969 			return err;
970 	}
971 	/* Disable the port before re-configuring */
972 	err = sparx5_port_disable(sparx5, port, high_speed_dev);
973 	if (err)
974 		return -EINVAL;
975 
976 	if (high_speed_dev)
977 		err = sparx5_port_pcs_high_set(sparx5, port, conf);
978 	else
979 		err = sparx5_port_pcs_low_set(sparx5, port, conf);
980 
981 	if (err)
982 		return -EINVAL;
983 
984 	if (conf->inband) {
985 		/* Enable/disable 1G counters in ASM */
986 		spx5_rmw(ASM_PORT_CFG_CSC_STAT_DIS_SET(high_speed_dev),
987 			 ASM_PORT_CFG_CSC_STAT_DIS,
988 			 sparx5,
989 			 ASM_PORT_CFG(port->portno));
990 
991 		/* Enable/disable 1G counters in DSM */
992 		spx5_rmw(DSM_BUF_CFG_CSC_STAT_DIS_SET(high_speed_dev),
993 			 DSM_BUF_CFG_CSC_STAT_DIS,
994 			 sparx5,
995 			 DSM_BUF_CFG(port->portno));
996 	}
997 
998 	port->conf = *conf;
999 
1000 	return 0;
1001 }
1002 
sparx5_port_config(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)1003 int sparx5_port_config(struct sparx5 *sparx5,
1004 		       struct sparx5_port *port,
1005 		       struct sparx5_port_config *conf)
1006 {
1007 	bool rgmii = phy_interface_mode_is_rgmii(conf->phy_mode);
1008 	bool high_speed_dev = sparx5_is_baser(conf->portmode);
1009 	const struct sparx5_ops *ops = sparx5->data->ops;
1010 	int err, urgency, stop_wm;
1011 
1012 	err = sparx5_port_verify_speed(sparx5, port, conf);
1013 	if (err)
1014 		return err;
1015 
1016 	if (rgmii) {
1017 		err = ops->port_config_rgmii(port, conf);
1018 		if (err)
1019 			return err;
1020 	}
1021 
1022 	/* high speed device is already configured */
1023 	if (!rgmii && !high_speed_dev)
1024 		sparx5_port_config_low_set(sparx5, port, conf);
1025 
1026 	/* Configure flow control */
1027 	err = sparx5_port_fc_setup(sparx5, port, conf);
1028 	if (err)
1029 		return err;
1030 
1031 	if (!is_sparx5(sparx5) && ops->is_port_10g(port->portno) &&
1032 	    conf->speed < SPEED_10000)
1033 		spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA_SET(1),
1034 			 DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA,
1035 			 sparx5,
1036 			 DSM_DEV_TX_STOP_WM_CFG(port->portno));
1037 
1038 	/* Set the DSM stop watermark */
1039 	stop_wm = sparx5_port_fifo_sz(sparx5, port->portno, conf->speed);
1040 	spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM_SET(stop_wm),
1041 		 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM,
1042 		 sparx5,
1043 		 DSM_DEV_TX_STOP_WM_CFG(port->portno));
1044 
1045 	/* Enable port in queue system */
1046 	urgency = sparx5_port_fwd_urg(sparx5, conf->speed);
1047 	spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(1) |
1048 		 QFWD_SWITCH_PORT_MODE_FWD_URGENCY_SET(urgency),
1049 		 QFWD_SWITCH_PORT_MODE_PORT_ENA |
1050 		 QFWD_SWITCH_PORT_MODE_FWD_URGENCY,
1051 		 sparx5,
1052 		 QFWD_SWITCH_PORT_MODE(port->portno));
1053 
1054 	/* Notify TAS about the speed. */
1055 	sparx5_tas_speed(port, conf->speed);
1056 
1057 	/* Save the new values */
1058 	port->conf = *conf;
1059 
1060 	return 0;
1061 }
1062 
1063 /* Initialize port config to default */
sparx5_port_init(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)1064 int sparx5_port_init(struct sparx5 *sparx5,
1065 		     struct sparx5_port *port,
1066 		     struct sparx5_port_config *conf)
1067 {
1068 	u32 pause_start = sparx5_wm_enc(6  * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
1069 	u32 atop = sparx5_wm_enc(20 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
1070 	const struct sparx5_ops *ops = sparx5->data->ops;
1071 	u32 devhigh = sparx5_to_high_dev(sparx5, port->portno);
1072 	u32 pix = sparx5_port_dev_index(sparx5, port->portno);
1073 	u32 pcs = sparx5_to_pcs_dev(sparx5, port->portno);
1074 	bool sd_pol = port->signd_active_high;
1075 	bool sd_sel = !port->signd_internal;
1076 	bool sd_ena = port->signd_enable;
1077 	u32 pause_stop = 0xFFF - 1; /* FC generate disabled */
1078 	void __iomem *devinst;
1079 	void __iomem *pcsinst;
1080 	int err;
1081 
1082 	devinst = spx5_inst_get(sparx5, devhigh, pix);
1083 	pcsinst = spx5_inst_get(sparx5, pcs, pix);
1084 
1085 	/* Set the mux port mode  */
1086 	err = ops->set_port_mux(sparx5, port, conf);
1087 	if (err)
1088 		return err;
1089 
1090 	/* Set Pause WM hysteresis */
1091 	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_START_SET(pause_start) |
1092 		 QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop) |
1093 		 QSYS_PAUSE_CFG_PAUSE_ENA_SET(1),
1094 		 QSYS_PAUSE_CFG_PAUSE_START |
1095 		 QSYS_PAUSE_CFG_PAUSE_STOP |
1096 		 QSYS_PAUSE_CFG_PAUSE_ENA,
1097 		 sparx5,
1098 		 QSYS_PAUSE_CFG(port->portno));
1099 
1100 	/* Port ATOP. Frames are tail dropped when this WM is hit */
1101 	spx5_wr(QSYS_ATOP_ATOP_SET(atop),
1102 		sparx5,
1103 		QSYS_ATOP(port->portno));
1104 
1105 	/* Discard pause frame 01-80-C2-00-00-01 */
1106 	spx5_wr(PAUSE_DISCARD, sparx5, ANA_CL_CAPTURE_BPDU_CFG(port->portno));
1107 
1108 	/* Discard SMAC multicast */
1109 	spx5_rmw(ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS_SET(0),
1110 		 ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
1111 		 sparx5, ANA_CL_FILTER_CTRL(port->portno));
1112 
1113 	if (ops->is_port_rgmii(port->portno))
1114 		return 0; /* RGMII device - nothing more to configure */
1115 
1116 	/* Configure MAC vlan awareness */
1117 	err = sparx5_port_max_tags_set(sparx5, port);
1118 	if (err)
1119 		return err;
1120 
1121 	/* Set Max Length */
1122 	spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
1123 		 DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
1124 		 sparx5,
1125 		 DEV2G5_MAC_MAXLEN_CFG(port->portno));
1126 
1127 	/* 1G/2G5: Signal Detect configuration */
1128 	spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
1129 		DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
1130 		DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
1131 		sparx5,
1132 		DEV2G5_PCS1G_SD_CFG(port->portno));
1133 
1134 	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII ||
1135 	    conf->portmode == PHY_INTERFACE_MODE_SGMII ||
1136 	    conf->portmode == PHY_INTERFACE_MODE_1000BASEX) {
1137 		err = sparx5_serdes_set(sparx5, port, conf);
1138 		if (err)
1139 			return err;
1140 
1141 		if (!ops->is_port_2g5(port->portno))
1142 			/* Enable shadow device */
1143 			spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA_SET(1),
1144 				 DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA,
1145 				 sparx5,
1146 				 DSM_DEV_TX_STOP_WM_CFG(port->portno));
1147 
1148 		sparx5_dev_switch(sparx5, port->portno, false);
1149 	}
1150 	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII) {
1151 		// All ports must be PCS enabled in QSGMII mode
1152 		spx5_rmw(DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(0),
1153 			 DEV2G5_DEV_RST_CTRL_PCS_TX_RST,
1154 			 sparx5,
1155 			 DEV2G5_DEV_RST_CTRL(port->portno));
1156 	}
1157 	/* Default IFGs for 1G */
1158 	spx5_wr(DEV2G5_MAC_IFG_CFG_TX_IFG_SET(6) |
1159 		DEV2G5_MAC_IFG_CFG_RX_IFG1_SET(0) |
1160 		DEV2G5_MAC_IFG_CFG_RX_IFG2_SET(0),
1161 		sparx5,
1162 		DEV2G5_MAC_IFG_CFG(port->portno));
1163 
1164 	if (ops->is_port_2g5(port->portno))
1165 		return 0; /* Low speed device only - return */
1166 
1167 	/* Now setup the high speed device */
1168 	if (conf->portmode == PHY_INTERFACE_MODE_NA)
1169 		conf->portmode = PHY_INTERFACE_MODE_10GBASER;
1170 
1171 	if (sparx5_is_baser(conf->portmode))
1172 		sparx5_dev_switch(sparx5, port->portno, true);
1173 
1174 	/* Set Max Length */
1175 	spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
1176 		      DEV10G_MAC_MAXLEN_CFG_MAX_LEN,
1177 		      devinst,
1178 		      DEV10G_MAC_MAXLEN_CFG(0));
1179 
1180 	/* Handle Signal Detect in 10G PCS */
1181 	spx5_inst_wr(PCS10G_BR_PCS_SD_CFG_SD_POL_SET(sd_pol) |
1182 		     PCS10G_BR_PCS_SD_CFG_SD_SEL_SET(sd_sel) |
1183 		     PCS10G_BR_PCS_SD_CFG_SD_ENA_SET(sd_ena),
1184 		     pcsinst,
1185 		     PCS10G_BR_PCS_SD_CFG(0));
1186 
1187 	if (ops->is_port_25g(port->portno)) {
1188 		/* Handle Signal Detect in 25G PCS */
1189 		spx5_wr(DEV25G_PCS25G_SD_CFG_SD_POL_SET(sd_pol) |
1190 			DEV25G_PCS25G_SD_CFG_SD_SEL_SET(sd_sel) |
1191 			DEV25G_PCS25G_SD_CFG_SD_ENA_SET(sd_ena),
1192 			sparx5,
1193 			DEV25G_PCS25G_SD_CFG(pix));
1194 	}
1195 
1196 	if (!is_sparx5(sparx5)) {
1197 		void __iomem *inst;
1198 		u32 dev, tinst;
1199 
1200 		if (ops->is_port_10g(port->portno)) {
1201 			dev = sparx5_to_high_dev(sparx5, port->portno);
1202 			tinst = sparx5_port_dev_index(sparx5, port->portno);
1203 			inst = spx5_inst_get(sparx5, dev, tinst);
1204 
1205 			spx5_inst_wr(5, inst,
1206 				     DEV10G_PTP_STAMPER_CFG(port->portno));
1207 		} else if (ops->is_port_5g(port->portno)) {
1208 			dev = sparx5_to_high_dev(sparx5, port->portno);
1209 			tinst = sparx5_port_dev_index(sparx5, port->portno);
1210 			inst = spx5_inst_get(sparx5, dev, tinst);
1211 
1212 			spx5_inst_wr(5, inst,
1213 				     DEV5G_PTP_STAMPER_CFG(port->portno));
1214 		}
1215 	}
1216 
1217 	return 0;
1218 }
1219 
sparx5_port_enable(struct sparx5_port * port,bool enable)1220 void sparx5_port_enable(struct sparx5_port *port, bool enable)
1221 {
1222 	struct sparx5 *sparx5 = port->sparx5;
1223 
1224 	/* Enable port for frame transfer? */
1225 	spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(enable),
1226 		 QFWD_SWITCH_PORT_MODE_PORT_ENA,
1227 		 sparx5,
1228 		 QFWD_SWITCH_PORT_MODE(port->portno));
1229 }
1230 
sparx5_port_qos_set(struct sparx5_port * port,struct sparx5_port_qos * qos)1231 int sparx5_port_qos_set(struct sparx5_port *port,
1232 			struct sparx5_port_qos *qos)
1233 {
1234 	sparx5_port_qos_dscp_set(port, &qos->dscp);
1235 	sparx5_port_qos_pcp_set(port, &qos->pcp);
1236 	sparx5_port_qos_pcp_rewr_set(port, &qos->pcp_rewr);
1237 	sparx5_port_qos_dscp_rewr_set(port, &qos->dscp_rewr);
1238 	sparx5_port_qos_default_set(port, qos);
1239 
1240 	return 0;
1241 }
1242 
sparx5_port_qos_pcp_rewr_set(const struct sparx5_port * port,struct sparx5_port_qos_pcp_rewr * qos)1243 int sparx5_port_qos_pcp_rewr_set(const struct sparx5_port *port,
1244 				 struct sparx5_port_qos_pcp_rewr *qos)
1245 {
1246 	int i, mode = SPARX5_PORT_REW_TAG_CTRL_CLASSIFIED;
1247 	struct sparx5 *sparx5 = port->sparx5;
1248 	u8 pcp, dei;
1249 
1250 	/* Use mapping table, with classified QoS as index, to map QoS and DP
1251 	 * to tagged PCP and DEI, if PCP is trusted. Otherwise use classified
1252 	 * PCP. Classified PCP equals frame PCP.
1253 	 */
1254 	if (qos->enable)
1255 		mode = SPARX5_PORT_REW_TAG_CTRL_MAPPED;
1256 
1257 	spx5_rmw(REW_TAG_CTRL_TAG_PCP_CFG_SET(mode) |
1258 		 REW_TAG_CTRL_TAG_DEI_CFG_SET(mode),
1259 		 REW_TAG_CTRL_TAG_PCP_CFG | REW_TAG_CTRL_TAG_DEI_CFG,
1260 		 port->sparx5, REW_TAG_CTRL(port->portno));
1261 
1262 	for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) {
1263 		/* Extract PCP and DEI */
1264 		pcp = qos->map.map[i];
1265 		if (pcp > SPARX5_PORT_QOS_PCP_COUNT)
1266 			dei = 1;
1267 		else
1268 			dei = 0;
1269 
1270 		/* Rewrite PCP and DEI, for each classified QoS class and DP
1271 		 * level. This table is only used if tag ctrl mode is set to
1272 		 * 'mapped'.
1273 		 *
1274 		 * 0:0nd   - prio=0 and dp:0 => pcp=0 and dei=0
1275 		 * 0:0de   - prio=0 and dp:1 => pcp=0 and dei=1
1276 		 */
1277 		if (dei) {
1278 			spx5_rmw(REW_PCP_MAP_DE1_PCP_DE1_SET(pcp),
1279 				 REW_PCP_MAP_DE1_PCP_DE1, sparx5,
1280 				 REW_PCP_MAP_DE1(port->portno, i));
1281 
1282 			spx5_rmw(REW_DEI_MAP_DE1_DEI_DE1_SET(dei),
1283 				 REW_DEI_MAP_DE1_DEI_DE1, port->sparx5,
1284 				 REW_DEI_MAP_DE1(port->portno, i));
1285 		} else {
1286 			spx5_rmw(REW_PCP_MAP_DE0_PCP_DE0_SET(pcp),
1287 				 REW_PCP_MAP_DE0_PCP_DE0, sparx5,
1288 				 REW_PCP_MAP_DE0(port->portno, i));
1289 
1290 			spx5_rmw(REW_DEI_MAP_DE0_DEI_DE0_SET(dei),
1291 				 REW_DEI_MAP_DE0_DEI_DE0, port->sparx5,
1292 				 REW_DEI_MAP_DE0(port->portno, i));
1293 		}
1294 	}
1295 
1296 	return 0;
1297 }
1298 
sparx5_port_qos_pcp_set(const struct sparx5_port * port,struct sparx5_port_qos_pcp * qos)1299 int sparx5_port_qos_pcp_set(const struct sparx5_port *port,
1300 			    struct sparx5_port_qos_pcp *qos)
1301 {
1302 	struct sparx5 *sparx5 = port->sparx5;
1303 	u8 *pcp_itr = qos->map.map;
1304 	u8 pcp, dp;
1305 	int i;
1306 
1307 	/* Enable/disable pcp and dp for qos classification. */
1308 	spx5_rmw(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(qos->qos_enable) |
1309 		 ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(qos->dp_enable),
1310 		 ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA | ANA_CL_QOS_CFG_PCP_DEI_DP_ENA,
1311 		 sparx5, ANA_CL_QOS_CFG(port->portno));
1312 
1313 	/* Map each pcp and dei value to priority and dp */
1314 	for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) {
1315 		pcp = *(pcp_itr + i);
1316 		dp = (i < SPARX5_PORT_QOS_PCP_COUNT) ? 0 : 1;
1317 		spx5_rmw(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL_SET(pcp) |
1318 			 ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL_SET(dp),
1319 			 ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL |
1320 			 ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL, sparx5,
1321 			 ANA_CL_PCP_DEI_MAP_CFG(port->portno, i));
1322 	}
1323 
1324 	return 0;
1325 }
1326 
sparx5_port_qos_dscp_rewr_mode_set(const struct sparx5_port * port,int mode)1327 void sparx5_port_qos_dscp_rewr_mode_set(const struct sparx5_port *port,
1328 					int mode)
1329 {
1330 	spx5_rmw(ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL_SET(mode),
1331 		 ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL, port->sparx5,
1332 		 ANA_CL_QOS_CFG(port->portno));
1333 }
1334 
sparx5_port_qos_dscp_rewr_set(const struct sparx5_port * port,struct sparx5_port_qos_dscp_rewr * qos)1335 int sparx5_port_qos_dscp_rewr_set(const struct sparx5_port *port,
1336 				  struct sparx5_port_qos_dscp_rewr *qos)
1337 {
1338 	struct sparx5 *sparx5 = port->sparx5;
1339 	bool rewr = false;
1340 	u16 dscp;
1341 	int i;
1342 
1343 	/* On egress, rewrite DSCP value to either classified DSCP or frame
1344 	 * DSCP. If enabled; classified DSCP, if disabled; frame DSCP.
1345 	 */
1346 	if (qos->enable)
1347 		rewr = true;
1348 
1349 	spx5_rmw(REW_DSCP_MAP_DSCP_UPDATE_ENA_SET(rewr),
1350 		 REW_DSCP_MAP_DSCP_UPDATE_ENA, sparx5,
1351 		 REW_DSCP_MAP(port->portno));
1352 
1353 	/* On ingress, map each classified QoS class and DP to classified DSCP
1354 	 * value. This mapping table is global for all ports.
1355 	 */
1356 	for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) {
1357 		dscp = qos->map.map[i];
1358 		spx5_rmw(ANA_CL_QOS_MAP_CFG_DSCP_REWR_VAL_SET(dscp),
1359 			 ANA_CL_QOS_MAP_CFG_DSCP_REWR_VAL, sparx5,
1360 			 ANA_CL_QOS_MAP_CFG(i));
1361 	}
1362 
1363 	return 0;
1364 }
1365 
sparx5_port_qos_dscp_set(const struct sparx5_port * port,struct sparx5_port_qos_dscp * qos)1366 int sparx5_port_qos_dscp_set(const struct sparx5_port *port,
1367 			     struct sparx5_port_qos_dscp *qos)
1368 {
1369 	struct sparx5 *sparx5 = port->sparx5;
1370 	u8 *dscp = qos->map.map;
1371 	int i;
1372 
1373 	/* Enable/disable dscp and dp for qos classification.
1374 	 * Disable rewrite of dscp values for now.
1375 	 */
1376 	spx5_rmw(ANA_CL_QOS_CFG_DSCP_QOS_ENA_SET(qos->qos_enable) |
1377 		 ANA_CL_QOS_CFG_DSCP_DP_ENA_SET(qos->dp_enable) |
1378 		 ANA_CL_QOS_CFG_DSCP_KEEP_ENA_SET(1),
1379 		 ANA_CL_QOS_CFG_DSCP_QOS_ENA | ANA_CL_QOS_CFG_DSCP_DP_ENA |
1380 		 ANA_CL_QOS_CFG_DSCP_KEEP_ENA, sparx5,
1381 		 ANA_CL_QOS_CFG(port->portno));
1382 
1383 	/* Map each dscp value to priority and dp */
1384 	for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) {
1385 		spx5_rmw(ANA_CL_DSCP_CFG_DSCP_QOS_VAL_SET(*(dscp + i)) |
1386 			 ANA_CL_DSCP_CFG_DSCP_DP_VAL_SET(0),
1387 			 ANA_CL_DSCP_CFG_DSCP_QOS_VAL |
1388 			 ANA_CL_DSCP_CFG_DSCP_DP_VAL, sparx5,
1389 			 ANA_CL_DSCP_CFG(i));
1390 	}
1391 
1392 	/* Set per-dscp trust */
1393 	for (i = 0; i <  ARRAY_SIZE(qos->map.map); i++) {
1394 		if (qos->qos_enable) {
1395 			spx5_rmw(ANA_CL_DSCP_CFG_DSCP_TRUST_ENA_SET(1),
1396 				 ANA_CL_DSCP_CFG_DSCP_TRUST_ENA, sparx5,
1397 				 ANA_CL_DSCP_CFG(i));
1398 		}
1399 	}
1400 
1401 	return 0;
1402 }
1403 
sparx5_port_qos_default_set(const struct sparx5_port * port,const struct sparx5_port_qos * qos)1404 int sparx5_port_qos_default_set(const struct sparx5_port *port,
1405 				const struct sparx5_port_qos *qos)
1406 {
1407 	struct sparx5 *sparx5 = port->sparx5;
1408 
1409 	/* Set default prio and dp level */
1410 	spx5_rmw(ANA_CL_QOS_CFG_DEFAULT_QOS_VAL_SET(qos->default_prio) |
1411 		 ANA_CL_QOS_CFG_DEFAULT_DP_VAL_SET(0),
1412 		 ANA_CL_QOS_CFG_DEFAULT_QOS_VAL |
1413 		 ANA_CL_QOS_CFG_DEFAULT_DP_VAL,
1414 		 sparx5, ANA_CL_QOS_CFG(port->portno));
1415 
1416 	/* Set default pcp and dei for untagged frames */
1417 	spx5_rmw(ANA_CL_VLAN_CTRL_PORT_PCP_SET(0) |
1418 		 ANA_CL_VLAN_CTRL_PORT_DEI_SET(0),
1419 		 ANA_CL_VLAN_CTRL_PORT_PCP |
1420 		 ANA_CL_VLAN_CTRL_PORT_DEI,
1421 		 sparx5, ANA_CL_VLAN_CTRL(port->portno));
1422 
1423 	return 0;
1424 }
1425 
sparx5_get_internal_port(struct sparx5 * sparx5,int port)1426 int sparx5_get_internal_port(struct sparx5 *sparx5, int port)
1427 {
1428 	return sparx5->data->consts->n_ports + port;
1429 }
1430