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