1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Marvell 88E6xxx SERDES manipulation, via SMI bus
4 *
5 * Copyright (c) 2008 Marvell Semiconductor
6 *
7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
8 */
9
10 #include <linux/interrupt.h>
11 #include <linux/irqdomain.h>
12 #include <linux/mii.h>
13
14 #include "chip.h"
15 #include "global2.h"
16 #include "phy.h"
17 #include "port.h"
18 #include "serdes.h"
19
mv88e6352_serdes_read(struct mv88e6xxx_chip * chip,int reg,u16 * val)20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
21 u16 *val)
22 {
23 return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
24 MV88E6352_SERDES_PAGE_FIBER,
25 reg, val);
26 }
27
mv88e6352_serdes_write(struct mv88e6xxx_chip * chip,int reg,u16 val)28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
29 u16 val)
30 {
31 return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
32 MV88E6352_SERDES_PAGE_FIBER,
33 reg, val);
34 }
35
mv88e6390_serdes_read(struct mv88e6xxx_chip * chip,int lane,int device,int reg,u16 * val)36 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
37 int lane, int device, int reg, u16 *val)
38 {
39 int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
40
41 return mv88e6xxx_phy_read(chip, lane, reg_c45, val);
42 }
43
mv88e6390_serdes_write(struct mv88e6xxx_chip * chip,int lane,int device,int reg,u16 val)44 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
45 int lane, int device, int reg, u16 val)
46 {
47 int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
48
49 return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
50 }
51
mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,u16 bmsr,u16 lpa,u16 status,struct phylink_link_state * state)52 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
53 u16 bmsr, u16 lpa, u16 status,
54 struct phylink_link_state *state)
55 {
56 state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
57 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
58
59 if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
60 /* The Spped and Duplex Resolved register is 1 if AN is enabled
61 * and complete, or if AN is disabled. So with disabled AN we
62 * still get here on link up.
63 */
64 state->duplex = status &
65 MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
66 DUPLEX_FULL : DUPLEX_HALF;
67
68 if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE)
69 state->pause |= MLO_PAUSE_TX;
70 if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE)
71 state->pause |= MLO_PAUSE_RX;
72
73 switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
74 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
75 if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
76 state->speed = SPEED_2500;
77 else
78 state->speed = SPEED_1000;
79 break;
80 case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
81 state->speed = SPEED_100;
82 break;
83 case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
84 state->speed = SPEED_10;
85 break;
86 default:
87 dev_err(chip->dev, "invalid PHY speed\n");
88 return -EINVAL;
89 }
90 } else if (state->link &&
91 state->interface != PHY_INTERFACE_MODE_SGMII) {
92 /* If Speed and Duplex Resolved register is 0 and link is up, it
93 * means that AN was enabled, but link partner had it disabled
94 * and the PHY invoked the Auto-Negotiation Bypass feature and
95 * linked anyway.
96 */
97 state->duplex = DUPLEX_FULL;
98 if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
99 state->speed = SPEED_2500;
100 else
101 state->speed = SPEED_1000;
102 } else {
103 state->link = false;
104 }
105
106 if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
107 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
108 ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
109 else if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
110 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
111 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
112
113 return 0;
114 }
115
mv88e6352_serdes_power(struct mv88e6xxx_chip * chip,int port,int lane,bool up)116 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
117 bool up)
118 {
119 u16 val, new_val;
120 int err;
121
122 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
123 if (err)
124 return err;
125
126 if (up)
127 new_val = val & ~BMCR_PDOWN;
128 else
129 new_val = val | BMCR_PDOWN;
130
131 if (val != new_val)
132 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
133
134 return err;
135 }
136
mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip * chip,int port,int lane,unsigned int mode,phy_interface_t interface,const unsigned long * advertise)137 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
138 int lane, unsigned int mode,
139 phy_interface_t interface,
140 const unsigned long *advertise)
141 {
142 u16 adv, bmcr, val;
143 bool changed;
144 int err;
145
146 switch (interface) {
147 case PHY_INTERFACE_MODE_SGMII:
148 adv = 0x0001;
149 break;
150
151 case PHY_INTERFACE_MODE_1000BASEX:
152 adv = linkmode_adv_to_mii_adv_x(advertise,
153 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
154 break;
155
156 default:
157 return 0;
158 }
159
160 err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
161 if (err)
162 return err;
163
164 changed = val != adv;
165 if (changed) {
166 err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
167 if (err)
168 return err;
169 }
170
171 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
172 if (err)
173 return err;
174
175 if (phylink_autoneg_inband(mode))
176 bmcr = val | BMCR_ANENABLE;
177 else
178 bmcr = val & ~BMCR_ANENABLE;
179
180 if (bmcr == val)
181 return changed;
182
183 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
184 }
185
mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)186 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
187 int lane, struct phylink_link_state *state)
188 {
189 u16 bmsr, lpa, status;
190 int err;
191
192 err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
193 if (err) {
194 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
195 return err;
196 }
197
198 err = mv88e6352_serdes_read(chip, 0x11, &status);
199 if (err) {
200 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
201 return err;
202 }
203
204 err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
205 if (err) {
206 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
207 return err;
208 }
209
210 return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
211 }
212
mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip * chip,int port,int lane)213 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
214 int lane)
215 {
216 u16 bmcr;
217 int err;
218
219 err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
220 if (err)
221 return err;
222
223 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
224 }
225
mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip * chip,int port,int lane,int speed,int duplex)226 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
227 int lane, int speed, int duplex)
228 {
229 u16 val, bmcr;
230 int err;
231
232 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
233 if (err)
234 return err;
235
236 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
237 switch (speed) {
238 case SPEED_1000:
239 bmcr |= BMCR_SPEED1000;
240 break;
241 case SPEED_100:
242 bmcr |= BMCR_SPEED100;
243 break;
244 case SPEED_10:
245 break;
246 }
247
248 if (duplex == DUPLEX_FULL)
249 bmcr |= BMCR_FULLDPLX;
250
251 if (bmcr == val)
252 return 0;
253
254 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
255 }
256
mv88e6352_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)257 int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
258 {
259 u8 cmode = chip->ports[port].cmode;
260 int lane = -ENODEV;
261
262 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
263 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
264 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
265 lane = 0xff; /* Unused */
266
267 return lane;
268 }
269
mv88e6352_port_has_serdes(struct mv88e6xxx_chip * chip,int port)270 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
271 {
272 if (mv88e6xxx_serdes_get_lane(chip, port) >= 0)
273 return true;
274
275 return false;
276 }
277
278 struct mv88e6352_serdes_hw_stat {
279 char string[ETH_GSTRING_LEN];
280 int sizeof_stat;
281 int reg;
282 };
283
284 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
285 { "serdes_fibre_rx_error", 16, 21 },
286 { "serdes_PRBS_error", 32, 24 },
287 };
288
mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip * chip,int port)289 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
290 {
291 if (mv88e6352_port_has_serdes(chip, port))
292 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
293
294 return 0;
295 }
296
mv88e6352_serdes_get_strings(struct mv88e6xxx_chip * chip,int port,uint8_t * data)297 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
298 int port, uint8_t *data)
299 {
300 struct mv88e6352_serdes_hw_stat *stat;
301 int i;
302
303 if (!mv88e6352_port_has_serdes(chip, port))
304 return 0;
305
306 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
307 stat = &mv88e6352_serdes_hw_stats[i];
308 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
309 ETH_GSTRING_LEN);
310 }
311 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
312 }
313
mv88e6352_serdes_get_stat(struct mv88e6xxx_chip * chip,struct mv88e6352_serdes_hw_stat * stat)314 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
315 struct mv88e6352_serdes_hw_stat *stat)
316 {
317 u64 val = 0;
318 u16 reg;
319 int err;
320
321 err = mv88e6352_serdes_read(chip, stat->reg, ®);
322 if (err) {
323 dev_err(chip->dev, "failed to read statistic\n");
324 return 0;
325 }
326
327 val = reg;
328
329 if (stat->sizeof_stat == 32) {
330 err = mv88e6352_serdes_read(chip, stat->reg + 1, ®);
331 if (err) {
332 dev_err(chip->dev, "failed to read statistic\n");
333 return 0;
334 }
335 val = val << 16 | reg;
336 }
337
338 return val;
339 }
340
mv88e6352_serdes_get_stats(struct mv88e6xxx_chip * chip,int port,uint64_t * data)341 size_t mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
342 uint64_t *data)
343 {
344 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
345 struct mv88e6352_serdes_hw_stat *stat;
346 u64 value;
347 int i;
348
349 if (!mv88e6352_port_has_serdes(chip, port))
350 return 0;
351
352 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
353 ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
354
355 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
356 stat = &mv88e6352_serdes_hw_stats[i];
357 value = mv88e6352_serdes_get_stat(chip, stat);
358 mv88e6xxx_port->serdes_stats[i] += value;
359 data[i] = mv88e6xxx_port->serdes_stats[i];
360 }
361
362 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
363 }
364
mv88e6352_serdes_irq_link(struct mv88e6xxx_chip * chip,int port)365 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
366 {
367 u16 bmsr;
368 int err;
369
370 /* If the link has dropped, we want to know about it. */
371 err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
372 if (err) {
373 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
374 return;
375 }
376
377 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
378 }
379
mv88e6352_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,int lane)380 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
381 int lane)
382 {
383 irqreturn_t ret = IRQ_NONE;
384 u16 status;
385 int err;
386
387 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
388 if (err)
389 return ret;
390
391 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
392 ret = IRQ_HANDLED;
393 mv88e6352_serdes_irq_link(chip, port);
394 }
395
396 return ret;
397 }
398
mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,int lane,bool enable)399 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
400 bool enable)
401 {
402 u16 val = 0;
403
404 if (enable)
405 val |= MV88E6352_SERDES_INT_LINK_CHANGE;
406
407 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
408 }
409
mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip * chip,int port)410 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
411 {
412 return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
413 }
414
mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip * chip,int port)415 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
416 {
417 if (!mv88e6352_port_has_serdes(chip, port))
418 return 0;
419
420 return 32 * sizeof(u16);
421 }
422
mv88e6352_serdes_get_regs(struct mv88e6xxx_chip * chip,int port,void * _p)423 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
424 {
425 u16 *p = _p;
426 u16 reg;
427 int err;
428 int i;
429
430 if (!mv88e6352_port_has_serdes(chip, port))
431 return;
432
433 for (i = 0 ; i < 32; i++) {
434 err = mv88e6352_serdes_read(chip, i, ®);
435 if (!err)
436 p[i] = reg;
437 }
438 }
439
mv88e6341_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)440 int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
441 {
442 u8 cmode = chip->ports[port].cmode;
443 int lane = -ENODEV;
444
445 switch (port) {
446 case 5:
447 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
448 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
449 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
450 lane = MV88E6341_PORT5_LANE;
451 break;
452 }
453
454 return lane;
455 }
456
mv88e6185_serdes_power(struct mv88e6xxx_chip * chip,int port,int lane,bool up)457 int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
458 bool up)
459 {
460 /* The serdes power can't be controlled on this switch chip but we need
461 * to supply this function to avoid returning -EOPNOTSUPP in
462 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
463 */
464 return 0;
465 }
466
mv88e6185_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)467 int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
468 {
469 /* There are no configurable serdes lanes on this switch chip but we
470 * need to return a non-negative lane number so that callers of
471 * mv88e6xxx_serdes_get_lane() know this is a serdes port.
472 */
473 switch (chip->ports[port].cmode) {
474 case MV88E6185_PORT_STS_CMODE_SERDES:
475 case MV88E6185_PORT_STS_CMODE_1000BASE_X:
476 return 0;
477 default:
478 return -ENODEV;
479 }
480 }
481
mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)482 int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
483 int lane, struct phylink_link_state *state)
484 {
485 int err;
486 u16 status;
487
488 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
489 if (err)
490 return err;
491
492 state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
493
494 if (state->link) {
495 state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
496
497 switch (status & MV88E6XXX_PORT_STS_SPEED_MASK) {
498 case MV88E6XXX_PORT_STS_SPEED_1000:
499 state->speed = SPEED_1000;
500 break;
501 case MV88E6XXX_PORT_STS_SPEED_100:
502 state->speed = SPEED_100;
503 break;
504 case MV88E6XXX_PORT_STS_SPEED_10:
505 state->speed = SPEED_10;
506 break;
507 default:
508 dev_err(chip->dev, "invalid PHY speed\n");
509 return -EINVAL;
510 }
511 } else {
512 state->duplex = DUPLEX_UNKNOWN;
513 state->speed = SPEED_UNKNOWN;
514 }
515
516 return 0;
517 }
518
mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,int lane,bool enable)519 int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
520 bool enable)
521 {
522 u8 cmode = chip->ports[port].cmode;
523
524 /* The serdes interrupts are enabled in the G2_INT_MASK register. We
525 * need to return 0 to avoid returning -EOPNOTSUPP in
526 * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable
527 */
528 switch (cmode) {
529 case MV88E6185_PORT_STS_CMODE_SERDES:
530 case MV88E6185_PORT_STS_CMODE_1000BASE_X:
531 return 0;
532 }
533
534 return -EOPNOTSUPP;
535 }
536
mv88e6097_serdes_irq_link(struct mv88e6xxx_chip * chip,int port)537 static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
538 {
539 u16 status;
540 int err;
541
542 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
543 if (err) {
544 dev_err(chip->dev, "can't read port status: %d\n", err);
545 return;
546 }
547
548 dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK));
549 }
550
mv88e6097_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,int lane)551 irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
552 int lane)
553 {
554 u8 cmode = chip->ports[port].cmode;
555
556 switch (cmode) {
557 case MV88E6185_PORT_STS_CMODE_SERDES:
558 case MV88E6185_PORT_STS_CMODE_1000BASE_X:
559 mv88e6097_serdes_irq_link(chip, port);
560 return IRQ_HANDLED;
561 }
562
563 return IRQ_NONE;
564 }
565
mv88e6390_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)566 int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
567 {
568 u8 cmode = chip->ports[port].cmode;
569 int lane = -ENODEV;
570
571 switch (port) {
572 case 9:
573 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
574 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
575 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
576 lane = MV88E6390_PORT9_LANE0;
577 break;
578 case 10:
579 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
580 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
581 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
582 lane = MV88E6390_PORT10_LANE0;
583 break;
584 }
585
586 return lane;
587 }
588
mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)589 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
590 {
591 u8 cmode_port = chip->ports[port].cmode;
592 u8 cmode_port10 = chip->ports[10].cmode;
593 u8 cmode_port9 = chip->ports[9].cmode;
594 int lane = -ENODEV;
595
596 switch (port) {
597 case 2:
598 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
599 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
600 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
601 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
602 lane = MV88E6390_PORT9_LANE1;
603 break;
604 case 3:
605 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
606 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
607 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
608 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
609 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
610 lane = MV88E6390_PORT9_LANE2;
611 break;
612 case 4:
613 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
614 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
615 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
616 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
617 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
618 lane = MV88E6390_PORT9_LANE3;
619 break;
620 case 5:
621 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
622 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
623 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
624 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
625 lane = MV88E6390_PORT10_LANE1;
626 break;
627 case 6:
628 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
629 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
630 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
631 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
632 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
633 lane = MV88E6390_PORT10_LANE2;
634 break;
635 case 7:
636 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
637 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
638 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
639 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
640 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
641 lane = MV88E6390_PORT10_LANE3;
642 break;
643 case 9:
644 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
645 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
646 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
647 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
648 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
649 lane = MV88E6390_PORT9_LANE0;
650 break;
651 case 10:
652 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
653 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
654 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
655 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
656 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
657 lane = MV88E6390_PORT10_LANE0;
658 break;
659 }
660
661 return lane;
662 }
663
664 /* Only Ports 0, 9 and 10 have SERDES lanes. Return the SERDES lane address
665 * a port is using else Returns -ENODEV.
666 */
mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)667 int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
668 {
669 u8 cmode = chip->ports[port].cmode;
670 int lane = -ENODEV;
671
672 if (port != 0 && port != 9 && port != 10)
673 return -EOPNOTSUPP;
674
675 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
676 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
677 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
678 cmode == MV88E6393X_PORT_STS_CMODE_5GBASER ||
679 cmode == MV88E6393X_PORT_STS_CMODE_10GBASER)
680 lane = port;
681
682 return lane;
683 }
684
685 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
mv88e6390_serdes_power_10g(struct mv88e6xxx_chip * chip,int lane,bool up)686 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane,
687 bool up)
688 {
689 u16 val, new_val;
690 int err;
691
692 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
693 MV88E6390_10G_CTRL1, &val);
694
695 if (err)
696 return err;
697
698 if (up)
699 new_val = val & ~(MDIO_CTRL1_RESET |
700 MDIO_PCS_CTRL1_LOOPBACK |
701 MDIO_CTRL1_LPOWER);
702 else
703 new_val = val | MDIO_CTRL1_LPOWER;
704
705 if (val != new_val)
706 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
707 MV88E6390_10G_CTRL1, new_val);
708
709 return err;
710 }
711
712 /* Set power up/down for SGMII and 1000Base-X */
mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip * chip,int lane,bool up)713 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
714 bool up)
715 {
716 u16 val, new_val;
717 int err;
718
719 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
720 MV88E6390_SGMII_BMCR, &val);
721 if (err)
722 return err;
723
724 if (up)
725 new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
726 else
727 new_val = val | BMCR_PDOWN;
728
729 if (val != new_val)
730 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
731 MV88E6390_SGMII_BMCR, new_val);
732
733 return err;
734 }
735
736 struct mv88e6390_serdes_hw_stat {
737 char string[ETH_GSTRING_LEN];
738 int reg;
739 };
740
741 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
742 { "serdes_rx_pkts", 0xf021 },
743 { "serdes_rx_bytes", 0xf024 },
744 { "serdes_rx_pkts_error", 0xf027 },
745 };
746
mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip * chip,int port)747 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
748 {
749 if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
750 return 0;
751
752 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
753 }
754
mv88e6390_serdes_get_strings(struct mv88e6xxx_chip * chip,int port,uint8_t * data)755 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
756 int port, uint8_t *data)
757 {
758 struct mv88e6390_serdes_hw_stat *stat;
759 int i;
760
761 if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
762 return 0;
763
764 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
765 stat = &mv88e6390_serdes_hw_stats[i];
766 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
767 ETH_GSTRING_LEN);
768 }
769 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
770 }
771
mv88e6390_serdes_get_stat(struct mv88e6xxx_chip * chip,int lane,struct mv88e6390_serdes_hw_stat * stat)772 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
773 struct mv88e6390_serdes_hw_stat *stat)
774 {
775 u16 reg[3];
776 int err, i;
777
778 for (i = 0; i < 3; i++) {
779 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
780 stat->reg + i, ®[i]);
781 if (err) {
782 dev_err(chip->dev, "failed to read statistic\n");
783 return 0;
784 }
785 }
786
787 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
788 }
789
mv88e6390_serdes_get_stats(struct mv88e6xxx_chip * chip,int port,uint64_t * data)790 size_t mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
791 uint64_t *data)
792 {
793 struct mv88e6390_serdes_hw_stat *stat;
794 int lane;
795 int i;
796
797 lane = mv88e6xxx_serdes_get_lane(chip, port);
798 if (lane < 0)
799 return 0;
800
801 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
802 stat = &mv88e6390_serdes_hw_stats[i];
803 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
804 }
805
806 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
807 }
808
mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip * chip,int lane)809 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, int lane)
810 {
811 u16 reg;
812 int err;
813
814 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
815 MV88E6390_PG_CONTROL, ®);
816 if (err)
817 return err;
818
819 reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
820 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
821 MV88E6390_PG_CONTROL, reg);
822 }
823
mv88e6390_serdes_power(struct mv88e6xxx_chip * chip,int port,int lane,bool up)824 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
825 bool up)
826 {
827 u8 cmode = chip->ports[port].cmode;
828 int err;
829
830 switch (cmode) {
831 case MV88E6XXX_PORT_STS_CMODE_SGMII:
832 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
833 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
834 err = mv88e6390_serdes_power_sgmii(chip, lane, up);
835 break;
836 case MV88E6XXX_PORT_STS_CMODE_XAUI:
837 case MV88E6XXX_PORT_STS_CMODE_RXAUI:
838 err = mv88e6390_serdes_power_10g(chip, lane, up);
839 break;
840 default:
841 err = -EINVAL;
842 break;
843 }
844
845 if (!err && up)
846 err = mv88e6390_serdes_enable_checker(chip, lane);
847
848 return err;
849 }
850
mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip * chip,int port,int lane,unsigned int mode,phy_interface_t interface,const unsigned long * advertise)851 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
852 int lane, unsigned int mode,
853 phy_interface_t interface,
854 const unsigned long *advertise)
855 {
856 u16 val, bmcr, adv;
857 bool changed;
858 int err;
859
860 switch (interface) {
861 case PHY_INTERFACE_MODE_SGMII:
862 adv = 0x0001;
863 break;
864
865 case PHY_INTERFACE_MODE_1000BASEX:
866 adv = linkmode_adv_to_mii_adv_x(advertise,
867 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
868 break;
869
870 case PHY_INTERFACE_MODE_2500BASEX:
871 adv = linkmode_adv_to_mii_adv_x(advertise,
872 ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
873 break;
874
875 default:
876 return 0;
877 }
878
879 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
880 MV88E6390_SGMII_ADVERTISE, &val);
881 if (err)
882 return err;
883
884 changed = val != adv;
885 if (changed) {
886 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
887 MV88E6390_SGMII_ADVERTISE, adv);
888 if (err)
889 return err;
890 }
891
892 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
893 MV88E6390_SGMII_BMCR, &val);
894 if (err)
895 return err;
896
897 if (phylink_autoneg_inband(mode))
898 bmcr = val | BMCR_ANENABLE;
899 else
900 bmcr = val & ~BMCR_ANENABLE;
901
902 /* setting ANENABLE triggers a restart of negotiation */
903 if (bmcr == val)
904 return changed;
905
906 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
907 MV88E6390_SGMII_BMCR, bmcr);
908 }
909
mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)910 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
911 int port, int lane, struct phylink_link_state *state)
912 {
913 u16 bmsr, lpa, status;
914 int err;
915
916 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
917 MV88E6390_SGMII_BMSR, &bmsr);
918 if (err) {
919 dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
920 return err;
921 }
922
923 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
924 MV88E6390_SGMII_PHY_STATUS, &status);
925 if (err) {
926 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
927 return err;
928 }
929
930 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
931 MV88E6390_SGMII_LPA, &lpa);
932 if (err) {
933 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
934 return err;
935 }
936
937 return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
938 }
939
mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)940 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
941 int port, int lane, struct phylink_link_state *state)
942 {
943 u16 status;
944 int err;
945
946 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
947 MV88E6390_10G_STAT1, &status);
948 if (err)
949 return err;
950
951 state->link = !!(status & MDIO_STAT1_LSTATUS);
952 if (state->link) {
953 state->speed = SPEED_10000;
954 state->duplex = DUPLEX_FULL;
955 }
956
957 return 0;
958 }
959
mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)960 static int mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
961 int port, int lane,
962 struct phylink_link_state *state)
963 {
964 u16 status;
965 int err;
966
967 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
968 MV88E6390_10G_STAT1, &status);
969 if (err)
970 return err;
971
972 state->link = !!(status & MDIO_STAT1_LSTATUS);
973 if (state->link) {
974 if (state->interface == PHY_INTERFACE_MODE_5GBASER)
975 state->speed = SPEED_5000;
976 else
977 state->speed = SPEED_10000;
978 state->duplex = DUPLEX_FULL;
979 }
980
981 return 0;
982 }
983
mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)984 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
985 int lane, struct phylink_link_state *state)
986 {
987 switch (state->interface) {
988 case PHY_INTERFACE_MODE_SGMII:
989 case PHY_INTERFACE_MODE_1000BASEX:
990 case PHY_INTERFACE_MODE_2500BASEX:
991 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
992 state);
993 case PHY_INTERFACE_MODE_XAUI:
994 case PHY_INTERFACE_MODE_RXAUI:
995 return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
996 state);
997
998 default:
999 return -EOPNOTSUPP;
1000 }
1001 }
1002
mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)1003 int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
1004 int lane, struct phylink_link_state *state)
1005 {
1006 switch (state->interface) {
1007 case PHY_INTERFACE_MODE_SGMII:
1008 case PHY_INTERFACE_MODE_1000BASEX:
1009 case PHY_INTERFACE_MODE_2500BASEX:
1010 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
1011 state);
1012 case PHY_INTERFACE_MODE_5GBASER:
1013 case PHY_INTERFACE_MODE_10GBASER:
1014 return mv88e6393x_serdes_pcs_get_state_10g(chip, port, lane,
1015 state);
1016
1017 default:
1018 return -EOPNOTSUPP;
1019 }
1020 }
1021
mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip * chip,int port,int lane)1022 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
1023 int lane)
1024 {
1025 u16 bmcr;
1026 int err;
1027
1028 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1029 MV88E6390_SGMII_BMCR, &bmcr);
1030 if (err)
1031 return err;
1032
1033 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1034 MV88E6390_SGMII_BMCR,
1035 bmcr | BMCR_ANRESTART);
1036 }
1037
mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip * chip,int port,int lane,int speed,int duplex)1038 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
1039 int lane, int speed, int duplex)
1040 {
1041 u16 val, bmcr;
1042 int err;
1043
1044 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1045 MV88E6390_SGMII_BMCR, &val);
1046 if (err)
1047 return err;
1048
1049 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
1050 switch (speed) {
1051 case SPEED_2500:
1052 case SPEED_1000:
1053 bmcr |= BMCR_SPEED1000;
1054 break;
1055 case SPEED_100:
1056 bmcr |= BMCR_SPEED100;
1057 break;
1058 case SPEED_10:
1059 break;
1060 }
1061
1062 if (duplex == DUPLEX_FULL)
1063 bmcr |= BMCR_FULLDPLX;
1064
1065 if (bmcr == val)
1066 return 0;
1067
1068 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1069 MV88E6390_SGMII_BMCR, bmcr);
1070 }
1071
mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip * chip,int port,int lane)1072 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
1073 int port, int lane)
1074 {
1075 u16 bmsr;
1076 int err;
1077
1078 /* If the link has dropped, we want to know about it. */
1079 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1080 MV88E6390_SGMII_BMSR, &bmsr);
1081 if (err) {
1082 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
1083 return;
1084 }
1085
1086 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
1087 }
1088
mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip * chip,int port,u8 lane)1089 static void mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip *chip,
1090 int port, u8 lane)
1091 {
1092 u16 status;
1093 int err;
1094
1095 /* If the link has dropped, we want to know about it. */
1096 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1097 MV88E6390_10G_STAT1, &status);
1098 if (err) {
1099 dev_err(chip->dev, "can't read Serdes STAT1: %d\n", err);
1100 return;
1101 }
1102
1103 dsa_port_phylink_mac_change(chip->ds, port, !!(status & MDIO_STAT1_LSTATUS));
1104 }
1105
mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip * chip,int lane,bool enable)1106 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
1107 int lane, bool enable)
1108 {
1109 u16 val = 0;
1110
1111 if (enable)
1112 val |= MV88E6390_SGMII_INT_LINK_DOWN |
1113 MV88E6390_SGMII_INT_LINK_UP;
1114
1115 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1116 MV88E6390_SGMII_INT_ENABLE, val);
1117 }
1118
mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,int lane,bool enable)1119 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
1120 bool enable)
1121 {
1122 u8 cmode = chip->ports[port].cmode;
1123
1124 switch (cmode) {
1125 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1126 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1127 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1128 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1129 }
1130
1131 return 0;
1132 }
1133
mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip * chip,int lane,u16 * status)1134 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
1135 int lane, u16 *status)
1136 {
1137 int err;
1138
1139 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1140 MV88E6390_SGMII_INT_STATUS, status);
1141
1142 return err;
1143 }
1144
mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip * chip,u8 lane,bool enable)1145 static int mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip *chip,
1146 u8 lane, bool enable)
1147 {
1148 u16 val = 0;
1149
1150 if (enable)
1151 val |= MV88E6393X_10G_INT_LINK_CHANGE;
1152
1153 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1154 MV88E6393X_10G_INT_ENABLE, val);
1155 }
1156
mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,int lane,bool enable)1157 int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
1158 int lane, bool enable)
1159 {
1160 u8 cmode = chip->ports[port].cmode;
1161
1162 switch (cmode) {
1163 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1164 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1165 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1166 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1167 case MV88E6393X_PORT_STS_CMODE_5GBASER:
1168 case MV88E6393X_PORT_STS_CMODE_10GBASER:
1169 return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable);
1170 }
1171
1172 return 0;
1173 }
1174
mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip * chip,u8 lane,u16 * status)1175 static int mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip *chip,
1176 u8 lane, u16 *status)
1177 {
1178 int err;
1179
1180 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1181 MV88E6393X_10G_INT_STATUS, status);
1182
1183 return err;
1184 }
1185
mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,int lane)1186 irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1187 int lane)
1188 {
1189 u8 cmode = chip->ports[port].cmode;
1190 irqreturn_t ret = IRQ_NONE;
1191 u16 status;
1192 int err;
1193
1194 switch (cmode) {
1195 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1196 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1197 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1198 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1199 if (err)
1200 return ret;
1201 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1202 MV88E6390_SGMII_INT_LINK_UP)) {
1203 ret = IRQ_HANDLED;
1204 mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1205 }
1206 break;
1207 case MV88E6393X_PORT_STS_CMODE_5GBASER:
1208 case MV88E6393X_PORT_STS_CMODE_10GBASER:
1209 err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status);
1210 if (err)
1211 return err;
1212 if (status & MV88E6393X_10G_INT_LINK_CHANGE) {
1213 ret = IRQ_HANDLED;
1214 mv88e6393x_serdes_irq_link_10g(chip, port, lane);
1215 }
1216 break;
1217 }
1218
1219 return ret;
1220 }
1221
mv88e6390_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,int lane)1222 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1223 int lane)
1224 {
1225 u8 cmode = chip->ports[port].cmode;
1226 irqreturn_t ret = IRQ_NONE;
1227 u16 status;
1228 int err;
1229
1230 switch (cmode) {
1231 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1232 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1233 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1234 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1235 if (err)
1236 return ret;
1237 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1238 MV88E6390_SGMII_INT_LINK_UP)) {
1239 ret = IRQ_HANDLED;
1240 mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1241 }
1242 }
1243
1244 return ret;
1245 }
1246
mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip * chip,int port)1247 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1248 {
1249 return irq_find_mapping(chip->g2_irq.domain, port);
1250 }
1251
1252 static const u16 mv88e6390_serdes_regs[] = {
1253 /* SERDES common registers */
1254 0xf00a, 0xf00b, 0xf00c,
1255 0xf010, 0xf011, 0xf012, 0xf013,
1256 0xf016, 0xf017, 0xf018,
1257 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
1258 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
1259 0xf028, 0xf029,
1260 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
1261 0xf038, 0xf039,
1262 /* SGMII */
1263 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1264 0x2008,
1265 0x200f,
1266 0xa000, 0xa001, 0xa002, 0xa003,
1267 /* 10Gbase-X */
1268 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1269 0x1008,
1270 0x100e, 0x100f,
1271 0x1018, 0x1019,
1272 0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
1273 0x9006,
1274 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
1275 /* 10Gbase-R */
1276 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1277 0x1028, 0x1029, 0x102a, 0x102b,
1278 };
1279
mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip * chip,int port)1280 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
1281 {
1282 if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
1283 return 0;
1284
1285 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
1286 }
1287
mv88e6390_serdes_get_regs(struct mv88e6xxx_chip * chip,int port,void * _p)1288 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
1289 {
1290 u16 *p = _p;
1291 int lane;
1292 u16 reg;
1293 int err;
1294 int i;
1295
1296 lane = mv88e6xxx_serdes_get_lane(chip, port);
1297 if (lane < 0)
1298 return;
1299
1300 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
1301 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1302 mv88e6390_serdes_regs[i], ®);
1303 if (!err)
1304 p[i] = reg;
1305 }
1306 }
1307
mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip * chip,int lane,bool on)1308 static int mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip *chip, int lane,
1309 bool on)
1310 {
1311 u16 reg;
1312 int err;
1313
1314 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1315 MV88E6393X_SERDES_CTRL1, ®);
1316 if (err)
1317 return err;
1318
1319 if (on)
1320 reg &= ~(MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1321 MV88E6393X_SERDES_CTRL1_RX_PDOWN);
1322 else
1323 reg |= MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1324 MV88E6393X_SERDES_CTRL1_RX_PDOWN;
1325
1326 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1327 MV88E6393X_SERDES_CTRL1, reg);
1328 }
1329
mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip * chip,int lane)1330 static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane)
1331 {
1332 u16 reg;
1333 int err;
1334
1335 /* mv88e6393x family errata 4.6:
1336 * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD
1337 * mode or P0_mode is configured for [x]MII.
1338 * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1.
1339 *
1340 * It seems that after this workaround the SERDES is automatically
1341 * powered up (the bit is cleared), so power it down.
1342 */
1343 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1344 MV88E6393X_SERDES_POC, ®);
1345 if (err)
1346 return err;
1347
1348 reg &= ~MV88E6393X_SERDES_POC_PDOWN;
1349 reg |= MV88E6393X_SERDES_POC_RESET;
1350
1351 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1352 MV88E6393X_SERDES_POC, reg);
1353 if (err)
1354 return err;
1355
1356 err = mv88e6390_serdes_power_sgmii(chip, lane, false);
1357 if (err)
1358 return err;
1359
1360 return mv88e6393x_serdes_power_lane(chip, lane, false);
1361 }
1362
mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip * chip)1363 int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip)
1364 {
1365 int err;
1366
1367 err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT0_LANE);
1368 if (err)
1369 return err;
1370
1371 err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT9_LANE);
1372 if (err)
1373 return err;
1374
1375 return mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT10_LANE);
1376 }
1377
mv88e6393x_serdes_erratum_4_8(struct mv88e6xxx_chip * chip,int lane)1378 static int mv88e6393x_serdes_erratum_4_8(struct mv88e6xxx_chip *chip, int lane)
1379 {
1380 u16 reg, pcs;
1381 int err;
1382
1383 /* mv88e6393x family errata 4.8:
1384 * When a SERDES port is operating in 1000BASE-X or SGMII mode link may
1385 * not come up after hardware reset or software reset of SERDES core.
1386 * Workaround is to write SERDES register 4.F074.14=1 for only those
1387 * modes and 0 in all other modes.
1388 */
1389 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1390 MV88E6393X_SERDES_POC, &pcs);
1391 if (err)
1392 return err;
1393
1394 pcs &= MV88E6393X_SERDES_POC_PCS_MASK;
1395
1396 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1397 MV88E6393X_ERRATA_4_8_REG, ®);
1398 if (err)
1399 return err;
1400
1401 if (pcs == MV88E6393X_SERDES_POC_PCS_1000BASEX ||
1402 pcs == MV88E6393X_SERDES_POC_PCS_SGMII_PHY ||
1403 pcs == MV88E6393X_SERDES_POC_PCS_SGMII_MAC)
1404 reg |= MV88E6393X_ERRATA_4_8_BIT;
1405 else
1406 reg &= ~MV88E6393X_ERRATA_4_8_BIT;
1407
1408 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1409 MV88E6393X_ERRATA_4_8_REG, reg);
1410 }
1411
mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip * chip,int lane,u8 cmode)1412 static int mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip *chip, int lane,
1413 u8 cmode)
1414 {
1415 static const struct {
1416 u16 dev, reg, val, mask;
1417 } fixes[] = {
1418 { MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff },
1419 { MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff },
1420 { MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff },
1421 { MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f },
1422 { MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 },
1423 { MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff },
1424 { MDIO_MMD_PHYXS, MV88E6393X_SERDES_POC,
1425 MV88E6393X_SERDES_POC_RESET, MV88E6393X_SERDES_POC_RESET },
1426 };
1427 int err, i;
1428 u16 reg;
1429
1430 /* mv88e6393x family errata 5.2:
1431 * For optimal signal integrity the following sequence should be applied
1432 * to SERDES operating in 10G mode. These registers only apply to 10G
1433 * operation and have no effect on other speeds.
1434 */
1435 if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER)
1436 return 0;
1437
1438 for (i = 0; i < ARRAY_SIZE(fixes); ++i) {
1439 err = mv88e6390_serdes_read(chip, lane, fixes[i].dev,
1440 fixes[i].reg, ®);
1441 if (err)
1442 return err;
1443
1444 reg &= ~fixes[i].mask;
1445 reg |= fixes[i].val;
1446
1447 err = mv88e6390_serdes_write(chip, lane, fixes[i].dev,
1448 fixes[i].reg, reg);
1449 if (err)
1450 return err;
1451 }
1452
1453 return 0;
1454 }
1455
mv88e6393x_serdes_fix_2500basex_an(struct mv88e6xxx_chip * chip,int lane,u8 cmode,bool on)1456 static int mv88e6393x_serdes_fix_2500basex_an(struct mv88e6xxx_chip *chip,
1457 int lane, u8 cmode, bool on)
1458 {
1459 u16 reg;
1460 int err;
1461
1462 if (cmode != MV88E6XXX_PORT_STS_CMODE_2500BASEX)
1463 return 0;
1464
1465 /* Inband AN is broken on Amethyst in 2500base-x mode when set by
1466 * standard mechanism (via cmode).
1467 * We can get around this by configuring the PCS mode to 1000base-x
1468 * and then writing value 0x58 to register 1e.8000. (This must be done
1469 * while SerDes receiver and transmitter are disabled, which is, when
1470 * this function is called.)
1471 * It seem that when we do this configuration to 2500base-x mode (by
1472 * changing PCS mode to 1000base-x and frequency to 3.125 GHz from
1473 * 1.25 GHz) and then configure to sgmii or 1000base-x, the device
1474 * thinks that it already has SerDes at 1.25 GHz and does not change
1475 * the 1e.8000 register, leaving SerDes at 3.125 GHz.
1476 * To avoid this, change PCS mode back to 2500base-x when disabling
1477 * SerDes from 2500base-x mode.
1478 */
1479 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1480 MV88E6393X_SERDES_POC, ®);
1481 if (err)
1482 return err;
1483
1484 reg &= ~(MV88E6393X_SERDES_POC_PCS_MASK | MV88E6393X_SERDES_POC_AN);
1485 if (on)
1486 reg |= MV88E6393X_SERDES_POC_PCS_1000BASEX |
1487 MV88E6393X_SERDES_POC_AN;
1488 else
1489 reg |= MV88E6393X_SERDES_POC_PCS_2500BASEX;
1490 reg |= MV88E6393X_SERDES_POC_RESET;
1491
1492 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1493 MV88E6393X_SERDES_POC, reg);
1494 if (err)
1495 return err;
1496
1497 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_VEND1, 0x8000, 0x58);
1498 if (err)
1499 return err;
1500
1501 return 0;
1502 }
1503
mv88e6393x_serdes_power(struct mv88e6xxx_chip * chip,int port,int lane,bool on)1504 int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
1505 bool on)
1506 {
1507 u8 cmode = chip->ports[port].cmode;
1508 int err;
1509
1510 if (port != 0 && port != 9 && port != 10)
1511 return -EOPNOTSUPP;
1512
1513 if (on) {
1514 err = mv88e6393x_serdes_erratum_4_8(chip, lane);
1515 if (err)
1516 return err;
1517
1518 err = mv88e6393x_serdes_erratum_5_2(chip, lane, cmode);
1519 if (err)
1520 return err;
1521
1522 err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1523 true);
1524 if (err)
1525 return err;
1526
1527 err = mv88e6393x_serdes_power_lane(chip, lane, true);
1528 if (err)
1529 return err;
1530 }
1531
1532 switch (cmode) {
1533 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1534 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1535 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1536 err = mv88e6390_serdes_power_sgmii(chip, lane, on);
1537 break;
1538 case MV88E6393X_PORT_STS_CMODE_5GBASER:
1539 case MV88E6393X_PORT_STS_CMODE_10GBASER:
1540 err = mv88e6390_serdes_power_10g(chip, lane, on);
1541 break;
1542 default:
1543 err = -EINVAL;
1544 break;
1545 }
1546
1547 if (err)
1548 return err;
1549
1550 if (!on) {
1551 err = mv88e6393x_serdes_power_lane(chip, lane, false);
1552 if (err)
1553 return err;
1554
1555 err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1556 false);
1557 }
1558
1559 return err;
1560 }
1561