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