Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Marvell 88E6xxx SERDES manipulation, via SMI bus
0004  *
0005  * Copyright (c) 2008 Marvell Semiconductor
0006  *
0007  * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
0008  */
0009 
0010 #include <linux/interrupt.h>
0011 #include <linux/irqdomain.h>
0012 #include <linux/mii.h>
0013 
0014 #include "chip.h"
0015 #include "global2.h"
0016 #include "phy.h"
0017 #include "port.h"
0018 #include "serdes.h"
0019 
0020 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
0021                  u16 *val)
0022 {
0023     return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
0024                        MV88E6352_SERDES_PAGE_FIBER,
0025                        reg, val);
0026 }
0027 
0028 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
0029                   u16 val)
0030 {
0031     return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
0032                     MV88E6352_SERDES_PAGE_FIBER,
0033                     reg, val);
0034 }
0035 
0036 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
0037                  int lane, int device, int reg, u16 *val)
0038 {
0039     int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
0040 
0041     return mv88e6xxx_phy_read(chip, lane, reg_c45, val);
0042 }
0043 
0044 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
0045                   int lane, int device, int reg, u16 val)
0046 {
0047     int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
0048 
0049     return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
0050 }
0051 
0052 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
0053                       u16 bmsr, u16 lpa, u16 status,
0054                       struct phylink_link_state *state)
0055 {
0056     state->link = false;
0057 
0058     /* If the BMSR reports that the link had failed, report this to
0059      * phylink.
0060      */
0061     if (!(bmsr & BMSR_LSTATUS))
0062         return 0;
0063 
0064     state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
0065     state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
0066 
0067     if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
0068         /* The Spped and Duplex Resolved register is 1 if AN is enabled
0069          * and complete, or if AN is disabled. So with disabled AN we
0070          * still get here on link up.
0071          */
0072         state->duplex = status &
0073                 MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
0074                                      DUPLEX_FULL : DUPLEX_HALF;
0075 
0076         if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE)
0077             state->pause |= MLO_PAUSE_TX;
0078         if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE)
0079             state->pause |= MLO_PAUSE_RX;
0080 
0081         switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
0082         case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
0083             if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
0084                 state->speed = SPEED_2500;
0085             else
0086                 state->speed = SPEED_1000;
0087             break;
0088         case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
0089             state->speed = SPEED_100;
0090             break;
0091         case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
0092             state->speed = SPEED_10;
0093             break;
0094         default:
0095             dev_err(chip->dev, "invalid PHY speed\n");
0096             return -EINVAL;
0097         }
0098     } else if (state->link &&
0099            state->interface != PHY_INTERFACE_MODE_SGMII) {
0100         /* If Speed and Duplex Resolved register is 0 and link is up, it
0101          * means that AN was enabled, but link partner had it disabled
0102          * and the PHY invoked the Auto-Negotiation Bypass feature and
0103          * linked anyway.
0104          */
0105         state->duplex = DUPLEX_FULL;
0106         if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
0107             state->speed = SPEED_2500;
0108         else
0109             state->speed = SPEED_1000;
0110     } else {
0111         state->link = false;
0112     }
0113 
0114     if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
0115         mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
0116                        ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
0117     else if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
0118         mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
0119                        ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
0120 
0121     return 0;
0122 }
0123 
0124 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
0125                bool up)
0126 {
0127     u16 val, new_val;
0128     int err;
0129 
0130     err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
0131     if (err)
0132         return err;
0133 
0134     if (up)
0135         new_val = val & ~BMCR_PDOWN;
0136     else
0137         new_val = val | BMCR_PDOWN;
0138 
0139     if (val != new_val)
0140         err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
0141 
0142     return err;
0143 }
0144 
0145 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
0146                 int lane, unsigned int mode,
0147                 phy_interface_t interface,
0148                 const unsigned long *advertise)
0149 {
0150     u16 adv, bmcr, val;
0151     bool changed;
0152     int err;
0153 
0154     switch (interface) {
0155     case PHY_INTERFACE_MODE_SGMII:
0156         adv = 0x0001;
0157         break;
0158 
0159     case PHY_INTERFACE_MODE_1000BASEX:
0160         adv = linkmode_adv_to_mii_adv_x(advertise,
0161                     ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
0162         break;
0163 
0164     default:
0165         return 0;
0166     }
0167 
0168     err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
0169     if (err)
0170         return err;
0171 
0172     changed = val != adv;
0173     if (changed) {
0174         err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
0175         if (err)
0176             return err;
0177     }
0178 
0179     err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
0180     if (err)
0181         return err;
0182 
0183     if (phylink_autoneg_inband(mode))
0184         bmcr = val | BMCR_ANENABLE;
0185     else
0186         bmcr = val & ~BMCR_ANENABLE;
0187 
0188     if (bmcr == val)
0189         return changed;
0190 
0191     return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
0192 }
0193 
0194 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
0195                    int lane, struct phylink_link_state *state)
0196 {
0197     u16 bmsr, lpa, status;
0198     int err;
0199 
0200     err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
0201     if (err) {
0202         dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
0203         return err;
0204     }
0205 
0206     err = mv88e6352_serdes_read(chip, 0x11, &status);
0207     if (err) {
0208         dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
0209         return err;
0210     }
0211 
0212     err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
0213     if (err) {
0214         dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
0215         return err;
0216     }
0217 
0218     return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
0219 }
0220 
0221 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
0222                     int lane)
0223 {
0224     u16 bmcr;
0225     int err;
0226 
0227     err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
0228     if (err)
0229         return err;
0230 
0231     return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
0232 }
0233 
0234 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
0235                  int lane, int speed, int duplex)
0236 {
0237     u16 val, bmcr;
0238     int err;
0239 
0240     err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
0241     if (err)
0242         return err;
0243 
0244     bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
0245     switch (speed) {
0246     case SPEED_1000:
0247         bmcr |= BMCR_SPEED1000;
0248         break;
0249     case SPEED_100:
0250         bmcr |= BMCR_SPEED100;
0251         break;
0252     case SPEED_10:
0253         break;
0254     }
0255 
0256     if (duplex == DUPLEX_FULL)
0257         bmcr |= BMCR_FULLDPLX;
0258 
0259     if (bmcr == val)
0260         return 0;
0261 
0262     return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
0263 }
0264 
0265 int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
0266 {
0267     u8 cmode = chip->ports[port].cmode;
0268     int lane = -ENODEV;
0269 
0270     if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
0271         (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
0272         (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
0273         lane = 0xff; /* Unused */
0274 
0275     return lane;
0276 }
0277 
0278 struct mv88e6352_serdes_hw_stat {
0279     char string[ETH_GSTRING_LEN];
0280     int sizeof_stat;
0281     int reg;
0282 };
0283 
0284 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
0285     { "serdes_fibre_rx_error", 16, 21 },
0286     { "serdes_PRBS_error", 32, 24 },
0287 };
0288 
0289 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
0290 {
0291     int err;
0292 
0293     err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
0294     if (err <= 0)
0295         return err;
0296 
0297     return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
0298 }
0299 
0300 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
0301                  int port, uint8_t *data)
0302 {
0303     struct mv88e6352_serdes_hw_stat *stat;
0304     int err, i;
0305 
0306     err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
0307     if (err <= 0)
0308         return err;
0309 
0310     for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
0311         stat = &mv88e6352_serdes_hw_stats[i];
0312         memcpy(data + i * ETH_GSTRING_LEN, stat->string,
0313                ETH_GSTRING_LEN);
0314     }
0315     return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
0316 }
0317 
0318 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
0319                       struct mv88e6352_serdes_hw_stat *stat)
0320 {
0321     u64 val = 0;
0322     u16 reg;
0323     int err;
0324 
0325     err = mv88e6352_serdes_read(chip, stat->reg, &reg);
0326     if (err) {
0327         dev_err(chip->dev, "failed to read statistic\n");
0328         return 0;
0329     }
0330 
0331     val = reg;
0332 
0333     if (stat->sizeof_stat == 32) {
0334         err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
0335         if (err) {
0336             dev_err(chip->dev, "failed to read statistic\n");
0337             return 0;
0338         }
0339         val = val << 16 | reg;
0340     }
0341 
0342     return val;
0343 }
0344 
0345 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
0346                    uint64_t *data)
0347 {
0348     struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
0349     struct mv88e6352_serdes_hw_stat *stat;
0350     int i, err;
0351     u64 value;
0352 
0353     err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
0354     if (err <= 0)
0355         return err;
0356 
0357     BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
0358              ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
0359 
0360     for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
0361         stat = &mv88e6352_serdes_hw_stats[i];
0362         value = mv88e6352_serdes_get_stat(chip, stat);
0363         mv88e6xxx_port->serdes_stats[i] += value;
0364         data[i] = mv88e6xxx_port->serdes_stats[i];
0365     }
0366 
0367     return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
0368 }
0369 
0370 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
0371 {
0372     u16 bmsr;
0373     int err;
0374 
0375     /* If the link has dropped, we want to know about it. */
0376     err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
0377     if (err) {
0378         dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
0379         return;
0380     }
0381 
0382     dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
0383 }
0384 
0385 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
0386                     int lane)
0387 {
0388     irqreturn_t ret = IRQ_NONE;
0389     u16 status;
0390     int err;
0391 
0392     err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
0393     if (err)
0394         return ret;
0395 
0396     if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
0397         ret = IRQ_HANDLED;
0398         mv88e6352_serdes_irq_link(chip, port);
0399     }
0400 
0401     return ret;
0402 }
0403 
0404 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
0405                 bool enable)
0406 {
0407     u16 val = 0;
0408 
0409     if (enable)
0410         val |= MV88E6352_SERDES_INT_LINK_CHANGE;
0411 
0412     return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
0413 }
0414 
0415 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
0416 {
0417     return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
0418 }
0419 
0420 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
0421 {
0422     int err;
0423 
0424     mv88e6xxx_reg_lock(chip);
0425     err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
0426     mv88e6xxx_reg_unlock(chip);
0427     if (err <= 0)
0428         return err;
0429 
0430     return 32 * sizeof(u16);
0431 }
0432 
0433 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
0434 {
0435     u16 *p = _p;
0436     u16 reg;
0437     int err;
0438     int i;
0439 
0440     err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
0441     if (err <= 0)
0442         return;
0443 
0444     for (i = 0 ; i < 32; i++) {
0445         err = mv88e6352_serdes_read(chip, i, &reg);
0446         if (!err)
0447             p[i] = reg;
0448     }
0449 }
0450 
0451 int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
0452 {
0453     u8 cmode = chip->ports[port].cmode;
0454     int lane = -ENODEV;
0455 
0456     switch (port) {
0457     case 5:
0458         if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0459             cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0460             cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
0461             lane = MV88E6341_PORT5_LANE;
0462         break;
0463     }
0464 
0465     return lane;
0466 }
0467 
0468 int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
0469                bool up)
0470 {
0471     /* The serdes power can't be controlled on this switch chip but we need
0472      * to supply this function to avoid returning -EOPNOTSUPP in
0473      * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
0474      */
0475     return 0;
0476 }
0477 
0478 int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
0479 {
0480     /* There are no configurable serdes lanes on this switch chip but we
0481      * need to return a non-negative lane number so that callers of
0482      * mv88e6xxx_serdes_get_lane() know this is a serdes port.
0483      */
0484     switch (chip->ports[port].cmode) {
0485     case MV88E6185_PORT_STS_CMODE_SERDES:
0486     case MV88E6185_PORT_STS_CMODE_1000BASE_X:
0487         return 0;
0488     default:
0489         return -ENODEV;
0490     }
0491 }
0492 
0493 int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
0494                    int lane, struct phylink_link_state *state)
0495 {
0496     int err;
0497     u16 status;
0498 
0499     err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
0500     if (err)
0501         return err;
0502 
0503     state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
0504 
0505     if (state->link) {
0506         state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
0507 
0508         switch (status &  MV88E6XXX_PORT_STS_SPEED_MASK) {
0509         case MV88E6XXX_PORT_STS_SPEED_1000:
0510             state->speed = SPEED_1000;
0511             break;
0512         case MV88E6XXX_PORT_STS_SPEED_100:
0513             state->speed = SPEED_100;
0514             break;
0515         case MV88E6XXX_PORT_STS_SPEED_10:
0516             state->speed = SPEED_10;
0517             break;
0518         default:
0519             dev_err(chip->dev, "invalid PHY speed\n");
0520             return -EINVAL;
0521         }
0522     } else {
0523         state->duplex = DUPLEX_UNKNOWN;
0524         state->speed = SPEED_UNKNOWN;
0525     }
0526 
0527     return 0;
0528 }
0529 
0530 int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
0531                 bool enable)
0532 {
0533     u8 cmode = chip->ports[port].cmode;
0534 
0535     /* The serdes interrupts are enabled in the G2_INT_MASK register. We
0536      * need to return 0 to avoid returning -EOPNOTSUPP in
0537      * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable
0538      */
0539     switch (cmode) {
0540     case MV88E6185_PORT_STS_CMODE_SERDES:
0541     case MV88E6185_PORT_STS_CMODE_1000BASE_X:
0542         return 0;
0543     }
0544 
0545     return -EOPNOTSUPP;
0546 }
0547 
0548 static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
0549 {
0550     u16 status;
0551     int err;
0552 
0553     err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
0554     if (err) {
0555         dev_err(chip->dev, "can't read port status: %d\n", err);
0556         return;
0557     }
0558 
0559     dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK));
0560 }
0561 
0562 irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
0563                     int lane)
0564 {
0565     u8 cmode = chip->ports[port].cmode;
0566 
0567     switch (cmode) {
0568     case MV88E6185_PORT_STS_CMODE_SERDES:
0569     case MV88E6185_PORT_STS_CMODE_1000BASE_X:
0570         mv88e6097_serdes_irq_link(chip, port);
0571         return IRQ_HANDLED;
0572     }
0573 
0574     return IRQ_NONE;
0575 }
0576 
0577 int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
0578 {
0579     u8 cmode = chip->ports[port].cmode;
0580     int lane = -ENODEV;
0581 
0582     switch (port) {
0583     case 9:
0584         if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0585             cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0586             cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
0587             lane = MV88E6390_PORT9_LANE0;
0588         break;
0589     case 10:
0590         if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0591             cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0592             cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
0593             lane = MV88E6390_PORT10_LANE0;
0594         break;
0595     }
0596 
0597     return lane;
0598 }
0599 
0600 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
0601 {
0602     u8 cmode_port = chip->ports[port].cmode;
0603     u8 cmode_port10 = chip->ports[10].cmode;
0604     u8 cmode_port9 = chip->ports[9].cmode;
0605     int lane = -ENODEV;
0606 
0607     switch (port) {
0608     case 2:
0609         if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0610             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0611             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
0612             if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
0613                 lane = MV88E6390_PORT9_LANE1;
0614         break;
0615     case 3:
0616         if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0617             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0618             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
0619             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
0620             if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
0621                 lane = MV88E6390_PORT9_LANE2;
0622         break;
0623     case 4:
0624         if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0625             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0626             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
0627             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
0628             if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
0629                 lane = MV88E6390_PORT9_LANE3;
0630         break;
0631     case 5:
0632         if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0633             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0634             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
0635             if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
0636                 lane = MV88E6390_PORT10_LANE1;
0637         break;
0638     case 6:
0639         if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0640             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0641             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
0642             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
0643             if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
0644                 lane = MV88E6390_PORT10_LANE2;
0645         break;
0646     case 7:
0647         if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0648             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0649             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
0650             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
0651             if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
0652                 lane = MV88E6390_PORT10_LANE3;
0653         break;
0654     case 9:
0655         if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0656             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0657             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
0658             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
0659             cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
0660             lane = MV88E6390_PORT9_LANE0;
0661         break;
0662     case 10:
0663         if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0664             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0665             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
0666             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
0667             cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
0668             lane = MV88E6390_PORT10_LANE0;
0669         break;
0670     }
0671 
0672     return lane;
0673 }
0674 
0675 /* Only Ports 0, 9 and 10 have SERDES lanes. Return the SERDES lane address
0676  * a port is using else Returns -ENODEV.
0677  */
0678 int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
0679 {
0680     u8 cmode = chip->ports[port].cmode;
0681     int lane = -ENODEV;
0682 
0683     if (port != 0 && port != 9 && port != 10)
0684         return -EOPNOTSUPP;
0685 
0686     if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
0687         cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
0688         cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
0689         cmode == MV88E6393X_PORT_STS_CMODE_5GBASER ||
0690         cmode == MV88E6393X_PORT_STS_CMODE_10GBASER)
0691         lane = port;
0692 
0693     return lane;
0694 }
0695 
0696 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
0697 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane,
0698                       bool up)
0699 {
0700     u16 val, new_val;
0701     int err;
0702 
0703     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0704                     MV88E6390_10G_CTRL1, &val);
0705 
0706     if (err)
0707         return err;
0708 
0709     if (up)
0710         new_val = val & ~(MDIO_CTRL1_RESET |
0711                   MDIO_PCS_CTRL1_LOOPBACK |
0712                   MDIO_CTRL1_LPOWER);
0713     else
0714         new_val = val | MDIO_CTRL1_LPOWER;
0715 
0716     if (val != new_val)
0717         err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
0718                          MV88E6390_10G_CTRL1, new_val);
0719 
0720     return err;
0721 }
0722 
0723 /* Set power up/down for SGMII and 1000Base-X */
0724 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
0725                     bool up)
0726 {
0727     u16 val, new_val;
0728     int err;
0729 
0730     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0731                     MV88E6390_SGMII_BMCR, &val);
0732     if (err)
0733         return err;
0734 
0735     if (up)
0736         new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
0737     else
0738         new_val = val | BMCR_PDOWN;
0739 
0740     if (val != new_val)
0741         err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
0742                          MV88E6390_SGMII_BMCR, new_val);
0743 
0744     return err;
0745 }
0746 
0747 struct mv88e6390_serdes_hw_stat {
0748     char string[ETH_GSTRING_LEN];
0749     int reg;
0750 };
0751 
0752 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
0753     { "serdes_rx_pkts", 0xf021 },
0754     { "serdes_rx_bytes", 0xf024 },
0755     { "serdes_rx_pkts_error", 0xf027 },
0756 };
0757 
0758 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
0759 {
0760     if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
0761         return 0;
0762 
0763     return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
0764 }
0765 
0766 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
0767                  int port, uint8_t *data)
0768 {
0769     struct mv88e6390_serdes_hw_stat *stat;
0770     int i;
0771 
0772     if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
0773         return 0;
0774 
0775     for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
0776         stat = &mv88e6390_serdes_hw_stats[i];
0777         memcpy(data + i * ETH_GSTRING_LEN, stat->string,
0778                ETH_GSTRING_LEN);
0779     }
0780     return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
0781 }
0782 
0783 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
0784                       struct mv88e6390_serdes_hw_stat *stat)
0785 {
0786     u16 reg[3];
0787     int err, i;
0788 
0789     for (i = 0; i < 3; i++) {
0790         err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0791                         stat->reg + i, &reg[i]);
0792         if (err) {
0793             dev_err(chip->dev, "failed to read statistic\n");
0794             return 0;
0795         }
0796     }
0797 
0798     return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
0799 }
0800 
0801 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
0802                    uint64_t *data)
0803 {
0804     struct mv88e6390_serdes_hw_stat *stat;
0805     int lane;
0806     int i;
0807 
0808     lane = mv88e6xxx_serdes_get_lane(chip, port);
0809     if (lane < 0)
0810         return 0;
0811 
0812     for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
0813         stat = &mv88e6390_serdes_hw_stats[i];
0814         data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
0815     }
0816 
0817     return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
0818 }
0819 
0820 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, int lane)
0821 {
0822     u16 reg;
0823     int err;
0824 
0825     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0826                     MV88E6390_PG_CONTROL, &reg);
0827     if (err)
0828         return err;
0829 
0830     reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
0831     return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
0832                       MV88E6390_PG_CONTROL, reg);
0833 }
0834 
0835 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
0836                bool up)
0837 {
0838     u8 cmode = chip->ports[port].cmode;
0839     int err;
0840 
0841     switch (cmode) {
0842     case MV88E6XXX_PORT_STS_CMODE_SGMII:
0843     case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
0844     case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
0845         err = mv88e6390_serdes_power_sgmii(chip, lane, up);
0846         break;
0847     case MV88E6XXX_PORT_STS_CMODE_XAUI:
0848     case MV88E6XXX_PORT_STS_CMODE_RXAUI:
0849         err = mv88e6390_serdes_power_10g(chip, lane, up);
0850         break;
0851     default:
0852         err = -EINVAL;
0853         break;
0854     }
0855 
0856     if (!err && up)
0857         err = mv88e6390_serdes_enable_checker(chip, lane);
0858 
0859     return err;
0860 }
0861 
0862 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
0863                 int lane, unsigned int mode,
0864                 phy_interface_t interface,
0865                 const unsigned long *advertise)
0866 {
0867     u16 val, bmcr, adv;
0868     bool changed;
0869     int err;
0870 
0871     switch (interface) {
0872     case PHY_INTERFACE_MODE_SGMII:
0873         adv = 0x0001;
0874         break;
0875 
0876     case PHY_INTERFACE_MODE_1000BASEX:
0877         adv = linkmode_adv_to_mii_adv_x(advertise,
0878                     ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
0879         break;
0880 
0881     case PHY_INTERFACE_MODE_2500BASEX:
0882         adv = linkmode_adv_to_mii_adv_x(advertise,
0883                     ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
0884         break;
0885 
0886     default:
0887         return 0;
0888     }
0889 
0890     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0891                     MV88E6390_SGMII_ADVERTISE, &val);
0892     if (err)
0893         return err;
0894 
0895     changed = val != adv;
0896     if (changed) {
0897         err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
0898                          MV88E6390_SGMII_ADVERTISE, adv);
0899         if (err)
0900             return err;
0901     }
0902 
0903     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0904                     MV88E6390_SGMII_BMCR, &val);
0905     if (err)
0906         return err;
0907 
0908     if (phylink_autoneg_inband(mode))
0909         bmcr = val | BMCR_ANENABLE;
0910     else
0911         bmcr = val & ~BMCR_ANENABLE;
0912 
0913     /* setting ANENABLE triggers a restart of negotiation */
0914     if (bmcr == val)
0915         return changed;
0916 
0917     return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
0918                       MV88E6390_SGMII_BMCR, bmcr);
0919 }
0920 
0921 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
0922     int port, int lane, struct phylink_link_state *state)
0923 {
0924     u16 bmsr, lpa, status;
0925     int err;
0926 
0927     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0928                     MV88E6390_SGMII_BMSR, &bmsr);
0929     if (err) {
0930         dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
0931         return err;
0932     }
0933 
0934     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0935                     MV88E6390_SGMII_PHY_STATUS, &status);
0936     if (err) {
0937         dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
0938         return err;
0939     }
0940 
0941     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0942                     MV88E6390_SGMII_LPA, &lpa);
0943     if (err) {
0944         dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
0945         return err;
0946     }
0947 
0948     return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
0949 }
0950 
0951 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
0952     int port, int lane, struct phylink_link_state *state)
0953 {
0954     u16 status;
0955     int err;
0956 
0957     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0958                     MV88E6390_10G_STAT1, &status);
0959     if (err)
0960         return err;
0961 
0962     state->link = !!(status & MDIO_STAT1_LSTATUS);
0963     if (state->link) {
0964         state->speed = SPEED_10000;
0965         state->duplex = DUPLEX_FULL;
0966     }
0967 
0968     return 0;
0969 }
0970 
0971 static int mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
0972                            int port, int lane,
0973                            struct phylink_link_state *state)
0974 {
0975     u16 status;
0976     int err;
0977 
0978     err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
0979                     MV88E6390_10G_STAT1, &status);
0980     if (err)
0981         return err;
0982 
0983     state->link = !!(status & MDIO_STAT1_LSTATUS);
0984     if (state->link) {
0985         if (state->interface == PHY_INTERFACE_MODE_5GBASER)
0986             state->speed = SPEED_5000;
0987         else
0988             state->speed = SPEED_10000;
0989         state->duplex = DUPLEX_FULL;
0990     }
0991 
0992     return 0;
0993 }
0994 
0995 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
0996                    int lane, struct phylink_link_state *state)
0997 {
0998     switch (state->interface) {
0999     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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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], &reg);
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 
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 
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, &reg);
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 
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, &reg);
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 
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 
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, &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 
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, &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 
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, &reg);
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 
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 }