1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Marvell 88E6xxx SERDES manipulation, via SMI bus
5 * Copyright (c) 2008 Marvell Semiconductor
7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
10 #include <linux/interrupt.h>
11 #include <linux/irqdomain.h>
12 #include <linux/mii.h>
20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
23 return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
24 MV88E6352_SERDES_PAGE_FIBER,
28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
31 return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
32 MV88E6352_SERDES_PAGE_FIBER,
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,
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;
72 state->speed = SPEED_1000;
74 case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
75 state->speed = SPEED_100;
77 case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
78 state->speed = SPEED_10;
81 dev_err(chip->dev, "invalid PHY speed\n");
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);
98 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
104 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
109 new_val = val & ~BMCR_PDOWN;
111 new_val = val | BMCR_PDOWN;
114 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
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)
129 case PHY_INTERFACE_MODE_SGMII:
133 case PHY_INTERFACE_MODE_1000BASEX:
134 adv = linkmode_adv_to_mii_adv_x(advertise,
135 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
142 err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
146 changed = val != adv;
148 err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
153 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
157 if (phylink_autoneg_inband(mode))
158 bmcr = val | BMCR_ANENABLE;
160 bmcr = val & ~BMCR_ANENABLE;
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)
174 err = mv88e6352_serdes_read(chip, 0x11, &status);
176 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
180 err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
182 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", 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,
195 err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
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)
208 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
212 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
215 bmcr |= BMCR_SPEED1000;
218 bmcr |= BMCR_SPEED100;
224 if (duplex == DUPLEX_FULL)
225 bmcr |= BMCR_FULLDPLX;
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;
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 */
246 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
248 if (mv88e6xxx_serdes_get_lane(chip, port))
254 struct mv88e6352_serdes_hw_stat {
255 char string[ETH_GSTRING_LEN];
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);
273 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
274 int port, uint8_t *data)
276 struct mv88e6352_serdes_hw_stat *stat;
279 if (!mv88e6352_port_has_serdes(chip, port))
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,
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)
297 err = mv88e6352_serdes_read(chip, stat->reg, ®);
299 dev_err(chip->dev, "failed to read statistic\n");
305 if (stat->sizeof_stat == 32) {
306 err = mv88e6352_serdes_read(chip, stat->reg + 1, ®);
308 dev_err(chip->dev, "failed to read statistic\n");
311 val = val << 16 | reg;
317 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
320 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
321 struct mv88e6352_serdes_hw_stat *stat;
325 if (!mv88e6352_port_has_serdes(chip, port))
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)
346 /* If the link has dropped, we want to know about it. */
347 err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
349 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
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,
359 irqreturn_t ret = IRQ_NONE;
363 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
367 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
369 mv88e6352_serdes_irq_link(chip, port);
375 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
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))
396 return 32 * sizeof(u16);
399 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
405 if (!mv88e6352_port_has_serdes(chip, port))
408 for (i = 0 ; i < 32; i++) {
409 mv88e6352_serdes_read(chip, i, ®);
414 u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
416 u8 cmode = chip->ports[port].cmode;
421 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
422 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
423 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
424 lane = MV88E6341_PORT5_LANE;
431 u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
433 u8 cmode = chip->ports[port].cmode;
438 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
439 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
440 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
441 lane = MV88E6390_PORT9_LANE0;
444 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
445 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
446 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
447 lane = MV88E6390_PORT10_LANE0;
454 u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
456 u8 cmode_port = chip->ports[port].cmode;
457 u8 cmode_port10 = chip->ports[10].cmode;
458 u8 cmode_port9 = chip->ports[9].cmode;
463 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
464 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
465 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
466 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
467 lane = MV88E6390_PORT9_LANE1;
470 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
471 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
472 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
473 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
474 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
475 lane = MV88E6390_PORT9_LANE2;
478 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
479 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
480 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
481 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
482 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
483 lane = MV88E6390_PORT9_LANE3;
486 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
487 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
488 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
489 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
490 lane = MV88E6390_PORT10_LANE1;
493 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
494 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
495 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
496 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
497 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
498 lane = MV88E6390_PORT10_LANE2;
501 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
502 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
503 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
504 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
505 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
506 lane = MV88E6390_PORT10_LANE3;
509 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
510 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
511 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
512 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
513 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
514 lane = MV88E6390_PORT9_LANE0;
517 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
518 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
519 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
520 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
521 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
522 lane = MV88E6390_PORT10_LANE0;
529 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
530 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
536 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
537 MV88E6390_10G_CTRL1, &val);
543 new_val = val & ~(MDIO_CTRL1_RESET |
544 MDIO_PCS_CTRL1_LOOPBACK |
547 new_val = val | MDIO_CTRL1_LPOWER;
550 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
551 MV88E6390_10G_CTRL1, new_val);
556 /* Set power up/down for SGMII and 1000Base-X */
557 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
563 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
564 MV88E6390_SGMII_BMCR, &val);
569 new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
571 new_val = val | BMCR_PDOWN;
574 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
575 MV88E6390_SGMII_BMCR, new_val);
580 struct mv88e6390_serdes_hw_stat {
581 char string[ETH_GSTRING_LEN];
585 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
586 { "serdes_rx_pkts", 0xf021 },
587 { "serdes_rx_bytes", 0xf024 },
588 { "serdes_rx_pkts_error", 0xf027 },
591 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
593 if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
596 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
599 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
600 int port, uint8_t *data)
602 struct mv88e6390_serdes_hw_stat *stat;
605 if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
608 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
609 stat = &mv88e6390_serdes_hw_stats[i];
610 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
613 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
616 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
617 struct mv88e6390_serdes_hw_stat *stat)
622 for (i = 0; i < 3; i++) {
623 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
624 stat->reg + i, ®[i]);
626 dev_err(chip->dev, "failed to read statistic\n");
631 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
634 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
637 struct mv88e6390_serdes_hw_stat *stat;
641 lane = mv88e6xxx_serdes_get_lane(chip, port);
645 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
646 stat = &mv88e6390_serdes_hw_stats[i];
647 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
650 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
653 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, u8 lane)
658 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
659 MV88E6390_PG_CONTROL, ®);
663 reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
664 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
665 MV88E6390_PG_CONTROL, reg);
668 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
671 u8 cmode = chip->ports[port].cmode;
675 case MV88E6XXX_PORT_STS_CMODE_SGMII:
676 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
677 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
678 err = mv88e6390_serdes_power_sgmii(chip, lane, up);
680 case MV88E6XXX_PORT_STS_CMODE_XAUI:
681 case MV88E6XXX_PORT_STS_CMODE_RXAUI:
682 err = mv88e6390_serdes_power_10g(chip, lane, up);
687 err = mv88e6390_serdes_enable_checker(chip, lane);
692 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
693 u8 lane, unsigned int mode,
694 phy_interface_t interface,
695 const unsigned long *advertise)
702 case PHY_INTERFACE_MODE_SGMII:
706 case PHY_INTERFACE_MODE_1000BASEX:
707 adv = linkmode_adv_to_mii_adv_x(advertise,
708 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
711 case PHY_INTERFACE_MODE_2500BASEX:
712 adv = linkmode_adv_to_mii_adv_x(advertise,
713 ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
720 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
721 MV88E6390_SGMII_ADVERTISE, &val);
725 changed = val != adv;
727 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
728 MV88E6390_SGMII_ADVERTISE, adv);
733 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
734 MV88E6390_SGMII_BMCR, &val);
738 if (phylink_autoneg_inband(mode))
739 bmcr = val | BMCR_ANENABLE;
741 bmcr = val & ~BMCR_ANENABLE;
743 /* setting ANENABLE triggers a restart of negotiation */
747 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
748 MV88E6390_SGMII_BMCR, bmcr);
751 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
752 int port, u8 lane, struct phylink_link_state *state)
757 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
758 MV88E6390_SGMII_PHY_STATUS, &status);
760 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
764 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
765 MV88E6390_SGMII_LPA, &lpa);
767 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
771 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
774 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
775 int port, u8 lane, struct phylink_link_state *state)
780 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
781 MV88E6390_10G_STAT1, &status);
785 state->link = !!(status & MDIO_STAT1_LSTATUS);
787 state->speed = SPEED_10000;
788 state->duplex = DUPLEX_FULL;
794 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
795 u8 lane, struct phylink_link_state *state)
797 switch (state->interface) {
798 case PHY_INTERFACE_MODE_SGMII:
799 case PHY_INTERFACE_MODE_1000BASEX:
800 case PHY_INTERFACE_MODE_2500BASEX:
801 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
803 case PHY_INTERFACE_MODE_XAUI:
804 case PHY_INTERFACE_MODE_RXAUI:
805 return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
813 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
819 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
820 MV88E6390_SGMII_BMCR, &bmcr);
824 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
825 MV88E6390_SGMII_BMCR,
826 bmcr | BMCR_ANRESTART);
829 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
830 u8 lane, int speed, int duplex)
835 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
836 MV88E6390_SGMII_BMCR, &val);
840 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
844 bmcr |= BMCR_SPEED1000;
847 bmcr |= BMCR_SPEED100;
853 if (duplex == DUPLEX_FULL)
854 bmcr |= BMCR_FULLDPLX;
859 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
860 MV88E6390_SGMII_BMCR, bmcr);
863 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
869 /* If the link has dropped, we want to know about it. */
870 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
871 MV88E6390_SGMII_BMSR, &bmsr);
873 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
877 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
880 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
881 u8 lane, bool enable)
886 val |= MV88E6390_SGMII_INT_LINK_DOWN |
887 MV88E6390_SGMII_INT_LINK_UP;
889 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
890 MV88E6390_SGMII_INT_ENABLE, val);
893 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
896 u8 cmode = chip->ports[port].cmode;
899 case MV88E6XXX_PORT_STS_CMODE_SGMII:
900 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
901 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
902 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
908 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
909 u8 lane, u16 *status)
913 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
914 MV88E6390_SGMII_INT_STATUS, status);
919 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
922 u8 cmode = chip->ports[port].cmode;
923 irqreturn_t ret = IRQ_NONE;
928 case MV88E6XXX_PORT_STS_CMODE_SGMII:
929 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
930 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
931 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
934 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
935 MV88E6390_SGMII_INT_LINK_UP)) {
937 mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
944 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
946 return irq_find_mapping(chip->g2_irq.domain, port);
949 static const u16 mv88e6390_serdes_regs[] = {
950 /* SERDES common registers */
951 0xf00a, 0xf00b, 0xf00c,
952 0xf010, 0xf011, 0xf012, 0xf013,
953 0xf016, 0xf017, 0xf018,
954 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
955 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
957 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
960 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
963 0xa000, 0xa001, 0xa002, 0xa003,
965 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
969 0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
971 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
973 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
974 0x1028, 0x1029, 0x102a, 0x102b,
977 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
979 if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
982 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
985 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
992 lane = mv88e6xxx_serdes_get_lane(chip, port);
996 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
997 mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
998 mv88e6390_serdes_regs[i], ®);