WIP FPC-III support
[linux/fpc-iii.git] / drivers / net / dsa / mv88e6xxx / serdes.c
blob3195936dc5be7ba694a5d5b2cdcbe6c1b929207d
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Marvell 88E6xxx SERDES manipulation, via SMI bus
5 * Copyright (c) 2008 Marvell Semiconductor
7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
8 */
10 #include <linux/interrupt.h>
11 #include <linux/irqdomain.h>
12 #include <linux/mii.h>
14 #include "chip.h"
15 #include "global2.h"
16 #include "phy.h"
17 #include "port.h"
18 #include "serdes.h"
20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
21 u16 *val)
23 return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
24 MV88E6352_SERDES_PAGE_FIBER,
25 reg, val);
28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
29 u16 val)
31 return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
32 MV88E6352_SERDES_PAGE_FIBER,
33 reg, val);
36 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
37 int lane, int device, int reg, u16 *val)
39 int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
41 return mv88e6xxx_phy_read(chip, lane, reg_c45, val);
44 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
45 int lane, int device, int reg, u16 val)
47 int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
49 return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
52 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
53 u16 status, u16 lpa,
54 struct phylink_link_state *state)
56 if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
57 state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
58 state->duplex = status &
59 MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
60 DUPLEX_FULL : DUPLEX_HALF;
62 if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE)
63 state->pause |= MLO_PAUSE_TX;
64 if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE)
65 state->pause |= MLO_PAUSE_RX;
67 switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
68 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
69 if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
70 state->speed = SPEED_2500;
71 else
72 state->speed = SPEED_1000;
73 break;
74 case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
75 state->speed = SPEED_100;
76 break;
77 case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
78 state->speed = SPEED_10;
79 break;
80 default:
81 dev_err(chip->dev, "invalid PHY speed\n");
82 return -EINVAL;
84 } else {
85 state->link = false;
88 if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
89 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
90 ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
91 else if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
92 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
93 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
95 return 0;
98 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
99 bool up)
101 u16 val, new_val;
102 int err;
104 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
105 if (err)
106 return err;
108 if (up)
109 new_val = val & ~BMCR_PDOWN;
110 else
111 new_val = val | BMCR_PDOWN;
113 if (val != new_val)
114 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
116 return err;
119 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
120 u8 lane, unsigned int mode,
121 phy_interface_t interface,
122 const unsigned long *advertise)
124 u16 adv, bmcr, val;
125 bool changed;
126 int err;
128 switch (interface) {
129 case PHY_INTERFACE_MODE_SGMII:
130 adv = 0x0001;
131 break;
133 case PHY_INTERFACE_MODE_1000BASEX:
134 adv = linkmode_adv_to_mii_adv_x(advertise,
135 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
136 break;
138 default:
139 return 0;
142 err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
143 if (err)
144 return err;
146 changed = val != adv;
147 if (changed) {
148 err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
149 if (err)
150 return err;
153 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
154 if (err)
155 return err;
157 if (phylink_autoneg_inband(mode))
158 bmcr = val | BMCR_ANENABLE;
159 else
160 bmcr = val & ~BMCR_ANENABLE;
162 if (bmcr == val)
163 return changed;
165 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
168 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
169 u8 lane, struct phylink_link_state *state)
171 u16 lpa, status;
172 int err;
174 err = mv88e6352_serdes_read(chip, 0x11, &status);
175 if (err) {
176 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
177 return err;
180 err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
181 if (err) {
182 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
183 return err;
186 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
189 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
190 u8 lane)
192 u16 bmcr;
193 int err;
195 err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
196 if (err)
197 return err;
199 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
202 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
203 u8 lane, int speed, int duplex)
205 u16 val, bmcr;
206 int err;
208 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
209 if (err)
210 return err;
212 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
213 switch (speed) {
214 case SPEED_1000:
215 bmcr |= BMCR_SPEED1000;
216 break;
217 case SPEED_100:
218 bmcr |= BMCR_SPEED100;
219 break;
220 case SPEED_10:
221 break;
224 if (duplex == DUPLEX_FULL)
225 bmcr |= BMCR_FULLDPLX;
227 if (bmcr == val)
228 return 0;
230 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
233 u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
235 u8 cmode = chip->ports[port].cmode;
236 u8 lane = 0;
238 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
239 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
240 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
241 lane = 0xff; /* Unused */
243 return lane;
246 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
248 if (mv88e6xxx_serdes_get_lane(chip, port))
249 return true;
251 return false;
254 struct mv88e6352_serdes_hw_stat {
255 char string[ETH_GSTRING_LEN];
256 int sizeof_stat;
257 int reg;
260 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
261 { "serdes_fibre_rx_error", 16, 21 },
262 { "serdes_PRBS_error", 32, 24 },
265 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
267 if (mv88e6352_port_has_serdes(chip, port))
268 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
270 return 0;
273 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
274 int port, uint8_t *data)
276 struct mv88e6352_serdes_hw_stat *stat;
277 int i;
279 if (!mv88e6352_port_has_serdes(chip, port))
280 return 0;
282 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
283 stat = &mv88e6352_serdes_hw_stats[i];
284 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
285 ETH_GSTRING_LEN);
287 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
290 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
291 struct mv88e6352_serdes_hw_stat *stat)
293 u64 val = 0;
294 u16 reg;
295 int err;
297 err = mv88e6352_serdes_read(chip, stat->reg, &reg);
298 if (err) {
299 dev_err(chip->dev, "failed to read statistic\n");
300 return 0;
303 val = reg;
305 if (stat->sizeof_stat == 32) {
306 err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
307 if (err) {
308 dev_err(chip->dev, "failed to read statistic\n");
309 return 0;
311 val = val << 16 | reg;
314 return val;
317 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
318 uint64_t *data)
320 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
321 struct mv88e6352_serdes_hw_stat *stat;
322 u64 value;
323 int i;
325 if (!mv88e6352_port_has_serdes(chip, port))
326 return 0;
328 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
329 ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
331 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
332 stat = &mv88e6352_serdes_hw_stats[i];
333 value = mv88e6352_serdes_get_stat(chip, stat);
334 mv88e6xxx_port->serdes_stats[i] += value;
335 data[i] = mv88e6xxx_port->serdes_stats[i];
338 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
341 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
343 u16 bmsr;
344 int err;
346 /* If the link has dropped, we want to know about it. */
347 err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
348 if (err) {
349 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
350 return;
353 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
356 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
357 u8 lane)
359 irqreturn_t ret = IRQ_NONE;
360 u16 status;
361 int err;
363 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
364 if (err)
365 return ret;
367 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
368 ret = IRQ_HANDLED;
369 mv88e6352_serdes_irq_link(chip, port);
372 return ret;
375 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
376 bool enable)
378 u16 val = 0;
380 if (enable)
381 val |= MV88E6352_SERDES_INT_LINK_CHANGE;
383 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
386 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
388 return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
391 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
393 if (!mv88e6352_port_has_serdes(chip, port))
394 return 0;
396 return 32 * sizeof(u16);
399 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
401 u16 *p = _p;
402 u16 reg;
403 int err;
404 int i;
406 if (!mv88e6352_port_has_serdes(chip, port))
407 return;
409 for (i = 0 ; i < 32; i++) {
410 err = mv88e6352_serdes_read(chip, i, &reg);
411 if (!err)
412 p[i] = reg;
416 u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
418 u8 cmode = chip->ports[port].cmode;
419 u8 lane = 0;
421 switch (port) {
422 case 5:
423 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
424 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
425 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
426 lane = MV88E6341_PORT5_LANE;
427 break;
430 return lane;
433 int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
434 bool up)
436 /* The serdes power can't be controlled on this switch chip but we need
437 * to supply this function to avoid returning -EOPNOTSUPP in
438 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
440 return 0;
443 u8 mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
445 /* There are no configurable serdes lanes on this switch chip but we
446 * need to return non-zero so that callers of
447 * mv88e6xxx_serdes_get_lane() know this is a serdes port.
449 switch (chip->ports[port].cmode) {
450 case MV88E6185_PORT_STS_CMODE_SERDES:
451 case MV88E6185_PORT_STS_CMODE_1000BASE_X:
452 return 0xff;
453 default:
454 return 0;
458 int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
459 u8 lane, struct phylink_link_state *state)
461 int err;
462 u16 status;
464 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
465 if (err)
466 return err;
468 state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
470 if (state->link) {
471 state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
473 switch (status & MV88E6XXX_PORT_STS_SPEED_MASK) {
474 case MV88E6XXX_PORT_STS_SPEED_1000:
475 state->speed = SPEED_1000;
476 break;
477 case MV88E6XXX_PORT_STS_SPEED_100:
478 state->speed = SPEED_100;
479 break;
480 case MV88E6XXX_PORT_STS_SPEED_10:
481 state->speed = SPEED_10;
482 break;
483 default:
484 dev_err(chip->dev, "invalid PHY speed\n");
485 return -EINVAL;
487 } else {
488 state->duplex = DUPLEX_UNKNOWN;
489 state->speed = SPEED_UNKNOWN;
492 return 0;
495 int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
496 bool enable)
498 u8 cmode = chip->ports[port].cmode;
500 /* The serdes interrupts are enabled in the G2_INT_MASK register. We
501 * need to return 0 to avoid returning -EOPNOTSUPP in
502 * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable
504 switch (cmode) {
505 case MV88E6185_PORT_STS_CMODE_SERDES:
506 case MV88E6185_PORT_STS_CMODE_1000BASE_X:
507 return 0;
510 return -EOPNOTSUPP;
513 static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
515 u16 status;
516 int err;
518 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
519 if (err) {
520 dev_err(chip->dev, "can't read port status: %d\n", err);
521 return;
524 dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK));
527 irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
528 u8 lane)
530 u8 cmode = chip->ports[port].cmode;
532 switch (cmode) {
533 case MV88E6185_PORT_STS_CMODE_SERDES:
534 case MV88E6185_PORT_STS_CMODE_1000BASE_X:
535 mv88e6097_serdes_irq_link(chip, port);
536 return IRQ_HANDLED;
539 return IRQ_NONE;
542 u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
544 u8 cmode = chip->ports[port].cmode;
545 u8 lane = 0;
547 switch (port) {
548 case 9:
549 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
550 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
551 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
552 lane = MV88E6390_PORT9_LANE0;
553 break;
554 case 10:
555 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
556 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
557 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
558 lane = MV88E6390_PORT10_LANE0;
559 break;
562 return lane;
565 u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
567 u8 cmode_port = chip->ports[port].cmode;
568 u8 cmode_port10 = chip->ports[10].cmode;
569 u8 cmode_port9 = chip->ports[9].cmode;
570 u8 lane = 0;
572 switch (port) {
573 case 2:
574 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
575 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
576 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
577 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
578 lane = MV88E6390_PORT9_LANE1;
579 break;
580 case 3:
581 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
582 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
583 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
584 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
585 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
586 lane = MV88E6390_PORT9_LANE2;
587 break;
588 case 4:
589 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
590 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
591 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
592 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
593 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
594 lane = MV88E6390_PORT9_LANE3;
595 break;
596 case 5:
597 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
598 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
599 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
600 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
601 lane = MV88E6390_PORT10_LANE1;
602 break;
603 case 6:
604 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
605 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
606 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
607 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
608 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
609 lane = MV88E6390_PORT10_LANE2;
610 break;
611 case 7:
612 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
613 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
614 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
615 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
616 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
617 lane = MV88E6390_PORT10_LANE3;
618 break;
619 case 9:
620 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
621 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
622 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
623 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
624 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
625 lane = MV88E6390_PORT9_LANE0;
626 break;
627 case 10:
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_XAUI ||
632 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
633 lane = MV88E6390_PORT10_LANE0;
634 break;
637 return lane;
640 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
641 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
642 bool up)
644 u16 val, new_val;
645 int err;
647 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
648 MV88E6390_10G_CTRL1, &val);
650 if (err)
651 return err;
653 if (up)
654 new_val = val & ~(MDIO_CTRL1_RESET |
655 MDIO_PCS_CTRL1_LOOPBACK |
656 MDIO_CTRL1_LPOWER);
657 else
658 new_val = val | MDIO_CTRL1_LPOWER;
660 if (val != new_val)
661 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
662 MV88E6390_10G_CTRL1, new_val);
664 return err;
667 /* Set power up/down for SGMII and 1000Base-X */
668 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
669 bool up)
671 u16 val, new_val;
672 int err;
674 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
675 MV88E6390_SGMII_BMCR, &val);
676 if (err)
677 return err;
679 if (up)
680 new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
681 else
682 new_val = val | BMCR_PDOWN;
684 if (val != new_val)
685 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
686 MV88E6390_SGMII_BMCR, new_val);
688 return err;
691 struct mv88e6390_serdes_hw_stat {
692 char string[ETH_GSTRING_LEN];
693 int reg;
696 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
697 { "serdes_rx_pkts", 0xf021 },
698 { "serdes_rx_bytes", 0xf024 },
699 { "serdes_rx_pkts_error", 0xf027 },
702 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
704 if (mv88e6390_serdes_get_lane(chip, port) == 0)
705 return 0;
707 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
710 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
711 int port, uint8_t *data)
713 struct mv88e6390_serdes_hw_stat *stat;
714 int i;
716 if (mv88e6390_serdes_get_lane(chip, port) == 0)
717 return 0;
719 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
720 stat = &mv88e6390_serdes_hw_stats[i];
721 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
722 ETH_GSTRING_LEN);
724 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
727 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
728 struct mv88e6390_serdes_hw_stat *stat)
730 u16 reg[3];
731 int err, i;
733 for (i = 0; i < 3; i++) {
734 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
735 stat->reg + i, &reg[i]);
736 if (err) {
737 dev_err(chip->dev, "failed to read statistic\n");
738 return 0;
742 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
745 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
746 uint64_t *data)
748 struct mv88e6390_serdes_hw_stat *stat;
749 int lane;
750 int i;
752 lane = mv88e6390_serdes_get_lane(chip, port);
753 if (lane == 0)
754 return 0;
756 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
757 stat = &mv88e6390_serdes_hw_stats[i];
758 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
761 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
764 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, u8 lane)
766 u16 reg;
767 int err;
769 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
770 MV88E6390_PG_CONTROL, &reg);
771 if (err)
772 return err;
774 reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
775 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
776 MV88E6390_PG_CONTROL, reg);
779 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
780 bool up)
782 u8 cmode = chip->ports[port].cmode;
783 int err = 0;
785 switch (cmode) {
786 case MV88E6XXX_PORT_STS_CMODE_SGMII:
787 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
788 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
789 err = mv88e6390_serdes_power_sgmii(chip, lane, up);
790 break;
791 case MV88E6XXX_PORT_STS_CMODE_XAUI:
792 case MV88E6XXX_PORT_STS_CMODE_RXAUI:
793 err = mv88e6390_serdes_power_10g(chip, lane, up);
794 break;
797 if (!err && up)
798 err = mv88e6390_serdes_enable_checker(chip, lane);
800 return err;
803 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
804 u8 lane, unsigned int mode,
805 phy_interface_t interface,
806 const unsigned long *advertise)
808 u16 val, bmcr, adv;
809 bool changed;
810 int err;
812 switch (interface) {
813 case PHY_INTERFACE_MODE_SGMII:
814 adv = 0x0001;
815 break;
817 case PHY_INTERFACE_MODE_1000BASEX:
818 adv = linkmode_adv_to_mii_adv_x(advertise,
819 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
820 break;
822 case PHY_INTERFACE_MODE_2500BASEX:
823 adv = linkmode_adv_to_mii_adv_x(advertise,
824 ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
825 break;
827 default:
828 return 0;
831 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
832 MV88E6390_SGMII_ADVERTISE, &val);
833 if (err)
834 return err;
836 changed = val != adv;
837 if (changed) {
838 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
839 MV88E6390_SGMII_ADVERTISE, adv);
840 if (err)
841 return err;
844 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
845 MV88E6390_SGMII_BMCR, &val);
846 if (err)
847 return err;
849 if (phylink_autoneg_inband(mode))
850 bmcr = val | BMCR_ANENABLE;
851 else
852 bmcr = val & ~BMCR_ANENABLE;
854 /* setting ANENABLE triggers a restart of negotiation */
855 if (bmcr == val)
856 return changed;
858 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
859 MV88E6390_SGMII_BMCR, bmcr);
862 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
863 int port, u8 lane, struct phylink_link_state *state)
865 u16 lpa, status;
866 int err;
868 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
869 MV88E6390_SGMII_PHY_STATUS, &status);
870 if (err) {
871 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
872 return err;
875 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
876 MV88E6390_SGMII_LPA, &lpa);
877 if (err) {
878 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
879 return err;
882 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
885 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
886 int port, u8 lane, struct phylink_link_state *state)
888 u16 status;
889 int err;
891 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
892 MV88E6390_10G_STAT1, &status);
893 if (err)
894 return err;
896 state->link = !!(status & MDIO_STAT1_LSTATUS);
897 if (state->link) {
898 state->speed = SPEED_10000;
899 state->duplex = DUPLEX_FULL;
902 return 0;
905 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
906 u8 lane, struct phylink_link_state *state)
908 switch (state->interface) {
909 case PHY_INTERFACE_MODE_SGMII:
910 case PHY_INTERFACE_MODE_1000BASEX:
911 case PHY_INTERFACE_MODE_2500BASEX:
912 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
913 state);
914 case PHY_INTERFACE_MODE_XAUI:
915 case PHY_INTERFACE_MODE_RXAUI:
916 return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
917 state);
919 default:
920 return -EOPNOTSUPP;
924 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
925 u8 lane)
927 u16 bmcr;
928 int err;
930 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
931 MV88E6390_SGMII_BMCR, &bmcr);
932 if (err)
933 return err;
935 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
936 MV88E6390_SGMII_BMCR,
937 bmcr | BMCR_ANRESTART);
940 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
941 u8 lane, int speed, int duplex)
943 u16 val, bmcr;
944 int err;
946 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
947 MV88E6390_SGMII_BMCR, &val);
948 if (err)
949 return err;
951 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
952 switch (speed) {
953 case SPEED_2500:
954 case SPEED_1000:
955 bmcr |= BMCR_SPEED1000;
956 break;
957 case SPEED_100:
958 bmcr |= BMCR_SPEED100;
959 break;
960 case SPEED_10:
961 break;
964 if (duplex == DUPLEX_FULL)
965 bmcr |= BMCR_FULLDPLX;
967 if (bmcr == val)
968 return 0;
970 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
971 MV88E6390_SGMII_BMCR, bmcr);
974 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
975 int port, u8 lane)
977 u16 bmsr;
978 int err;
980 /* If the link has dropped, we want to know about it. */
981 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
982 MV88E6390_SGMII_BMSR, &bmsr);
983 if (err) {
984 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
985 return;
988 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
991 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
992 u8 lane, bool enable)
994 u16 val = 0;
996 if (enable)
997 val |= MV88E6390_SGMII_INT_LINK_DOWN |
998 MV88E6390_SGMII_INT_LINK_UP;
1000 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1001 MV88E6390_SGMII_INT_ENABLE, val);
1004 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
1005 bool enable)
1007 u8 cmode = chip->ports[port].cmode;
1009 switch (cmode) {
1010 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1011 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1012 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1013 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1016 return 0;
1019 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
1020 u8 lane, u16 *status)
1022 int err;
1024 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1025 MV88E6390_SGMII_INT_STATUS, status);
1027 return err;
1030 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1031 u8 lane)
1033 u8 cmode = chip->ports[port].cmode;
1034 irqreturn_t ret = IRQ_NONE;
1035 u16 status;
1036 int err;
1038 switch (cmode) {
1039 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1040 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1041 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1042 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1043 if (err)
1044 return ret;
1045 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1046 MV88E6390_SGMII_INT_LINK_UP)) {
1047 ret = IRQ_HANDLED;
1048 mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1052 return ret;
1055 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1057 return irq_find_mapping(chip->g2_irq.domain, port);
1060 static const u16 mv88e6390_serdes_regs[] = {
1061 /* SERDES common registers */
1062 0xf00a, 0xf00b, 0xf00c,
1063 0xf010, 0xf011, 0xf012, 0xf013,
1064 0xf016, 0xf017, 0xf018,
1065 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
1066 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
1067 0xf028, 0xf029,
1068 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
1069 0xf038, 0xf039,
1070 /* SGMII */
1071 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1072 0x2008,
1073 0x200f,
1074 0xa000, 0xa001, 0xa002, 0xa003,
1075 /* 10Gbase-X */
1076 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1077 0x1008,
1078 0x100e, 0x100f,
1079 0x1018, 0x1019,
1080 0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
1081 0x9006,
1082 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
1083 /* 10Gbase-R */
1084 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1085 0x1028, 0x1029, 0x102a, 0x102b,
1088 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
1090 if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
1091 return 0;
1093 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
1096 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
1098 u16 *p = _p;
1099 int lane;
1100 u16 reg;
1101 int err;
1102 int i;
1104 lane = mv88e6xxx_serdes_get_lane(chip, port);
1105 if (lane == 0)
1106 return;
1108 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
1109 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1110 mv88e6390_serdes_regs[i], &reg);
1111 if (!err)
1112 p[i] = reg;