0001
0002
0003
0004
0005
0006
0007
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
0059
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
0069
0070
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
0101
0102
0103
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;
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, ®);
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, ®);
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
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, ®);
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
0472
0473
0474
0475 return 0;
0476 }
0477
0478 int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
0479 {
0480
0481
0482
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
0536
0537
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
0676
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
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
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, ®[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, ®);
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
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
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
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
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
1274 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1275 0x2008,
1276 0x200f,
1277 0xa000, 0xa001, 0xa002, 0xa003,
1278
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
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], ®);
1314 if (!err)
1315 p[i] = reg;
1316 }
1317 }
1318
1319 static const int mv88e6352_serdes_p2p_to_reg[] = {
1320
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, ®);
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
1385
1386
1387
1388
1389
1390
1391
1392 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1393 MV88E6393X_SERDES_POC, ®);
1394 if (err)
1395 return err;
1396
1397 reg &= ~MV88E6393X_SERDES_POC_PDOWN;
1398 reg |= MV88E6393X_SERDES_POC_RESET;
1399
1400 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1401 MV88E6393X_SERDES_POC, reg);
1402 if (err)
1403 return err;
1404
1405 err = mv88e6390_serdes_power_sgmii(chip, lane, false);
1406 if (err)
1407 return err;
1408
1409 return mv88e6393x_serdes_power_lane(chip, lane, false);
1410 }
1411
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
1433
1434
1435
1436
1437
1438 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1439 MV88E6393X_SERDES_POC, &pcs);
1440 if (err)
1441 return err;
1442
1443 pcs &= MV88E6393X_SERDES_POC_PCS_MASK;
1444
1445 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1446 MV88E6393X_ERRATA_4_8_REG, ®);
1447 if (err)
1448 return err;
1449
1450 if (pcs == MV88E6393X_SERDES_POC_PCS_1000BASEX ||
1451 pcs == MV88E6393X_SERDES_POC_PCS_SGMII_PHY ||
1452 pcs == MV88E6393X_SERDES_POC_PCS_SGMII_MAC)
1453 reg |= MV88E6393X_ERRATA_4_8_BIT;
1454 else
1455 reg &= ~MV88E6393X_ERRATA_4_8_BIT;
1456
1457 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1458 MV88E6393X_ERRATA_4_8_REG, reg);
1459 }
1460
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
1480
1481
1482
1483
1484 if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER)
1485 return 0;
1486
1487 for (i = 0; i < ARRAY_SIZE(fixes); ++i) {
1488 err = mv88e6390_serdes_read(chip, lane, fixes[i].dev,
1489 fixes[i].reg, ®);
1490 if (err)
1491 return err;
1492
1493 reg &= ~fixes[i].mask;
1494 reg |= fixes[i].val;
1495
1496 err = mv88e6390_serdes_write(chip, lane, fixes[i].dev,
1497 fixes[i].reg, reg);
1498 if (err)
1499 return err;
1500 }
1501
1502 return 0;
1503 }
1504
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
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1529 MV88E6393X_SERDES_POC, ®);
1530 if (err)
1531 return err;
1532
1533 reg &= ~(MV88E6393X_SERDES_POC_PCS_MASK | MV88E6393X_SERDES_POC_AN);
1534 if (on)
1535 reg |= MV88E6393X_SERDES_POC_PCS_1000BASEX |
1536 MV88E6393X_SERDES_POC_AN;
1537 else
1538 reg |= MV88E6393X_SERDES_POC_PCS_2500BASEX;
1539 reg |= MV88E6393X_SERDES_POC_RESET;
1540
1541 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1542 MV88E6393X_SERDES_POC, reg);
1543 if (err)
1544 return err;
1545
1546 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_VEND1, 0x8000, 0x58);
1547 if (err)
1548 return err;
1549
1550 return 0;
1551 }
1552
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 }