1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Marvell 88E6xxx SERDES manipulation, via SMI bus 4 * 5 * Copyright (c) 2008 Marvell Semiconductor 6 * 7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch> 8 */ 9 10 #include <linux/interrupt.h> 11 #include <linux/irqdomain.h> 12 #include <linux/mii.h> 13 14 #include "chip.h" 15 #include "global2.h" 16 #include "phy.h" 17 #include "port.h" 18 #include "serdes.h" 19 20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg, 21 u16 *val) 22 { 23 return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES, 24 MV88E6352_SERDES_PAGE_FIBER, 25 reg, val); 26 } 27 28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg, 29 u16 val) 30 { 31 return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES, 32 MV88E6352_SERDES_PAGE_FIBER, 33 reg, val); 34 } 35 36 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip, 37 int lane, int device, int reg, u16 *val) 38 { 39 int reg_c45 = MII_ADDR_C45 | device << 16 | reg; 40 41 return mv88e6xxx_phy_read(chip, lane, reg_c45, val); 42 } 43 44 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, 45 int lane, int device, int reg, u16 val) 46 { 47 int reg_c45 = MII_ADDR_C45 | device << 16 | reg; 48 49 return mv88e6xxx_phy_write(chip, lane, reg_c45, val); 50 } 51 52 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, 53 u16 status, u16 lpa, 54 struct phylink_link_state *state) 55 { 56 if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) { 57 state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK); 58 state->duplex = status & 59 MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ? 60 DUPLEX_FULL : DUPLEX_HALF; 61 62 if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE) 63 state->pause |= MLO_PAUSE_TX; 64 if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE) 65 state->pause |= MLO_PAUSE_RX; 66 67 switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) { 68 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000: 69 if (state->interface == PHY_INTERFACE_MODE_2500BASEX) 70 state->speed = SPEED_2500; 71 else 72 state->speed = SPEED_1000; 73 break; 74 case MV88E6390_SGMII_PHY_STATUS_SPEED_100: 75 state->speed = SPEED_100; 76 break; 77 case MV88E6390_SGMII_PHY_STATUS_SPEED_10: 78 state->speed = SPEED_10; 79 break; 80 default: 81 dev_err(chip->dev, "invalid PHY speed\n"); 82 return -EINVAL; 83 } 84 } else { 85 state->link = false; 86 } 87 88 if (state->interface == PHY_INTERFACE_MODE_2500BASEX) 89 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa, 90 ETHTOOL_LINK_MODE_2500baseX_Full_BIT); 91 else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) 92 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa, 93 ETHTOOL_LINK_MODE_1000baseX_Full_BIT); 94 95 return 0; 96 } 97 98 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, 99 bool up) 100 { 101 u16 val, new_val; 102 int err; 103 104 err = mv88e6352_serdes_read(chip, MII_BMCR, &val); 105 if (err) 106 return err; 107 108 if (up) 109 new_val = val & ~BMCR_PDOWN; 110 else 111 new_val = val | BMCR_PDOWN; 112 113 if (val != new_val) 114 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val); 115 116 return err; 117 } 118 119 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, 120 u8 lane, unsigned int mode, 121 phy_interface_t interface, 122 const unsigned long *advertise) 123 { 124 u16 adv, bmcr, val; 125 bool changed; 126 int err; 127 128 switch (interface) { 129 case PHY_INTERFACE_MODE_SGMII: 130 adv = 0x0001; 131 break; 132 133 case PHY_INTERFACE_MODE_1000BASEX: 134 adv = linkmode_adv_to_mii_adv_x(advertise, 135 ETHTOOL_LINK_MODE_1000baseX_Full_BIT); 136 break; 137 138 default: 139 return 0; 140 } 141 142 err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val); 143 if (err) 144 return err; 145 146 changed = val != adv; 147 if (changed) { 148 err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv); 149 if (err) 150 return err; 151 } 152 153 err = mv88e6352_serdes_read(chip, MII_BMCR, &val); 154 if (err) 155 return err; 156 157 if (phylink_autoneg_inband(mode)) 158 bmcr = val | BMCR_ANENABLE; 159 else 160 bmcr = val & ~BMCR_ANENABLE; 161 162 if (bmcr == val) 163 return changed; 164 165 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr); 166 } 167 168 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 169 u8 lane, struct phylink_link_state *state) 170 { 171 u16 lpa, status; 172 int err; 173 174 err = mv88e6352_serdes_read(chip, 0x11, &status); 175 if (err) { 176 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err); 177 return err; 178 } 179 180 err = mv88e6352_serdes_read(chip, MII_LPA, &lpa); 181 if (err) { 182 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err); 183 return err; 184 } 185 186 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state); 187 } 188 189 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, 190 u8 lane) 191 { 192 u16 bmcr; 193 int err; 194 195 err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr); 196 if (err) 197 return err; 198 199 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART); 200 } 201 202 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port, 203 u8 lane, int speed, int duplex) 204 { 205 u16 val, bmcr; 206 int err; 207 208 err = mv88e6352_serdes_read(chip, MII_BMCR, &val); 209 if (err) 210 return err; 211 212 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000); 213 switch (speed) { 214 case SPEED_1000: 215 bmcr |= BMCR_SPEED1000; 216 break; 217 case SPEED_100: 218 bmcr |= BMCR_SPEED100; 219 break; 220 case SPEED_10: 221 break; 222 } 223 224 if (duplex == DUPLEX_FULL) 225 bmcr |= BMCR_FULLDPLX; 226 227 if (bmcr == val) 228 return 0; 229 230 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr); 231 } 232 233 u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 234 { 235 u8 cmode = chip->ports[port].cmode; 236 u8 lane = 0; 237 238 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) || 239 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) || 240 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII)) 241 lane = 0xff; /* Unused */ 242 243 return lane; 244 } 245 246 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port) 247 { 248 if (mv88e6xxx_serdes_get_lane(chip, port)) 249 return true; 250 251 return false; 252 } 253 254 struct mv88e6352_serdes_hw_stat { 255 char string[ETH_GSTRING_LEN]; 256 int sizeof_stat; 257 int reg; 258 }; 259 260 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = { 261 { "serdes_fibre_rx_error", 16, 21 }, 262 { "serdes_PRBS_error", 32, 24 }, 263 }; 264 265 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) 266 { 267 if (mv88e6352_port_has_serdes(chip, port)) 268 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 269 270 return 0; 271 } 272 273 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, 274 int port, uint8_t *data) 275 { 276 struct mv88e6352_serdes_hw_stat *stat; 277 int i; 278 279 if (!mv88e6352_port_has_serdes(chip, port)) 280 return 0; 281 282 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) { 283 stat = &mv88e6352_serdes_hw_stats[i]; 284 memcpy(data + i * ETH_GSTRING_LEN, stat->string, 285 ETH_GSTRING_LEN); 286 } 287 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 288 } 289 290 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip, 291 struct mv88e6352_serdes_hw_stat *stat) 292 { 293 u64 val = 0; 294 u16 reg; 295 int err; 296 297 err = mv88e6352_serdes_read(chip, stat->reg, ®); 298 if (err) { 299 dev_err(chip->dev, "failed to read statistic\n"); 300 return 0; 301 } 302 303 val = reg; 304 305 if (stat->sizeof_stat == 32) { 306 err = mv88e6352_serdes_read(chip, stat->reg + 1, ®); 307 if (err) { 308 dev_err(chip->dev, "failed to read statistic\n"); 309 return 0; 310 } 311 val = val << 16 | reg; 312 } 313 314 return val; 315 } 316 317 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 318 uint64_t *data) 319 { 320 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port]; 321 struct mv88e6352_serdes_hw_stat *stat; 322 u64 value; 323 int i; 324 325 if (!mv88e6352_port_has_serdes(chip, port)) 326 return 0; 327 328 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) > 329 ARRAY_SIZE(mv88e6xxx_port->serdes_stats)); 330 331 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) { 332 stat = &mv88e6352_serdes_hw_stats[i]; 333 value = mv88e6352_serdes_get_stat(chip, stat); 334 mv88e6xxx_port->serdes_stats[i] += value; 335 data[i] = mv88e6xxx_port->serdes_stats[i]; 336 } 337 338 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 339 } 340 341 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port) 342 { 343 u16 bmsr; 344 int err; 345 346 /* If the link has dropped, we want to know about it. */ 347 err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr); 348 if (err) { 349 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err); 350 return; 351 } 352 353 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS)); 354 } 355 356 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 357 u8 lane) 358 { 359 irqreturn_t ret = IRQ_NONE; 360 u16 status; 361 int err; 362 363 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status); 364 if (err) 365 return ret; 366 367 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) { 368 ret = IRQ_HANDLED; 369 mv88e6352_serdes_irq_link(chip, port); 370 } 371 372 return ret; 373 } 374 375 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, 376 bool enable) 377 { 378 u16 val = 0; 379 380 if (enable) 381 val |= MV88E6352_SERDES_INT_LINK_CHANGE; 382 383 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val); 384 } 385 386 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 387 { 388 return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ); 389 } 390 391 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port) 392 { 393 if (!mv88e6352_port_has_serdes(chip, port)) 394 return 0; 395 396 return 32 * sizeof(u16); 397 } 398 399 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) 400 { 401 u16 *p = _p; 402 u16 reg; 403 int i; 404 405 if (!mv88e6352_port_has_serdes(chip, port)) 406 return; 407 408 for (i = 0 ; i < 32; i++) { 409 mv88e6352_serdes_read(chip, i, ®); 410 p[i] = reg; 411 } 412 } 413 414 u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 415 { 416 u8 cmode = chip->ports[port].cmode; 417 u8 lane = 0; 418 419 switch (port) { 420 case 5: 421 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 422 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 423 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 424 lane = MV88E6341_PORT5_LANE; 425 break; 426 } 427 428 return lane; 429 } 430 431 u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 432 { 433 u8 cmode = chip->ports[port].cmode; 434 u8 lane = 0; 435 436 switch (port) { 437 case 9: 438 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 439 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 440 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 441 lane = MV88E6390_PORT9_LANE0; 442 break; 443 case 10: 444 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 445 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 446 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 447 lane = MV88E6390_PORT10_LANE0; 448 break; 449 } 450 451 return lane; 452 } 453 454 u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 455 { 456 u8 cmode_port = chip->ports[port].cmode; 457 u8 cmode_port10 = chip->ports[10].cmode; 458 u8 cmode_port9 = chip->ports[9].cmode; 459 u8 lane = 0; 460 461 switch (port) { 462 case 2: 463 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 464 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 465 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 466 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 467 lane = MV88E6390_PORT9_LANE1; 468 break; 469 case 3: 470 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 471 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 472 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 473 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 474 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 475 lane = MV88E6390_PORT9_LANE2; 476 break; 477 case 4: 478 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 479 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 480 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 481 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 482 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 483 lane = MV88E6390_PORT9_LANE3; 484 break; 485 case 5: 486 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 487 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 488 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 489 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 490 lane = MV88E6390_PORT10_LANE1; 491 break; 492 case 6: 493 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 494 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 495 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 496 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 497 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 498 lane = MV88E6390_PORT10_LANE2; 499 break; 500 case 7: 501 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 502 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 503 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 504 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 505 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 506 lane = MV88E6390_PORT10_LANE3; 507 break; 508 case 9: 509 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 510 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 511 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 512 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI || 513 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 514 lane = MV88E6390_PORT9_LANE0; 515 break; 516 case 10: 517 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 518 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 519 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 520 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI || 521 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 522 lane = MV88E6390_PORT10_LANE0; 523 break; 524 } 525 526 return lane; 527 } 528 529 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */ 530 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, 531 bool up) 532 { 533 u16 val, new_val; 534 int err; 535 536 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 537 MV88E6390_PCS_CONTROL_1, &val); 538 539 if (err) 540 return err; 541 542 if (up) 543 new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET | 544 MV88E6390_PCS_CONTROL_1_LOOPBACK | 545 MV88E6390_PCS_CONTROL_1_PDOWN); 546 else 547 new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN; 548 549 if (val != new_val) 550 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 551 MV88E6390_PCS_CONTROL_1, new_val); 552 553 return err; 554 } 555 556 /* Set power up/down for SGMII and 1000Base-X */ 557 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, 558 bool up) 559 { 560 u16 val, new_val; 561 int err; 562 563 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 564 MV88E6390_SGMII_BMCR, &val); 565 if (err) 566 return err; 567 568 if (up) 569 new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN); 570 else 571 new_val = val | BMCR_PDOWN; 572 573 if (val != new_val) 574 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 575 MV88E6390_SGMII_BMCR, new_val); 576 577 return err; 578 } 579 580 struct mv88e6390_serdes_hw_stat { 581 char string[ETH_GSTRING_LEN]; 582 int reg; 583 }; 584 585 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = { 586 { "serdes_rx_pkts", 0xf021 }, 587 { "serdes_rx_bytes", 0xf024 }, 588 { "serdes_rx_pkts_error", 0xf027 }, 589 }; 590 591 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) 592 { 593 if (mv88e6390_serdes_get_lane(chip, port) == 0) 594 return 0; 595 596 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 597 } 598 599 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip, 600 int port, uint8_t *data) 601 { 602 struct mv88e6390_serdes_hw_stat *stat; 603 int i; 604 605 if (mv88e6390_serdes_get_lane(chip, port) == 0) 606 return 0; 607 608 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) { 609 stat = &mv88e6390_serdes_hw_stats[i]; 610 memcpy(data + i * ETH_GSTRING_LEN, stat->string, 611 ETH_GSTRING_LEN); 612 } 613 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 614 } 615 616 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane, 617 struct mv88e6390_serdes_hw_stat *stat) 618 { 619 u16 reg[3]; 620 int err, i; 621 622 for (i = 0; i < 3; i++) { 623 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 624 stat->reg + i, ®[i]); 625 if (err) { 626 dev_err(chip->dev, "failed to read statistic\n"); 627 return 0; 628 } 629 } 630 631 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32); 632 } 633 634 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 635 uint64_t *data) 636 { 637 struct mv88e6390_serdes_hw_stat *stat; 638 int lane; 639 int i; 640 641 lane = mv88e6390_serdes_get_lane(chip, port); 642 if (lane == 0) 643 return 0; 644 645 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) { 646 stat = &mv88e6390_serdes_hw_stats[i]; 647 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat); 648 } 649 650 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 651 } 652 653 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, u8 lane) 654 { 655 u16 reg; 656 int err; 657 658 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 659 MV88E6390_PG_CONTROL, ®); 660 if (err) 661 return err; 662 663 reg |= MV88E6390_PG_CONTROL_ENABLE_PC; 664 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 665 MV88E6390_PG_CONTROL, reg); 666 } 667 668 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, 669 bool up) 670 { 671 u8 cmode = chip->ports[port].cmode; 672 int err = 0; 673 674 switch (cmode) { 675 case MV88E6XXX_PORT_STS_CMODE_SGMII: 676 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 677 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 678 err = mv88e6390_serdes_power_sgmii(chip, lane, up); 679 break; 680 case MV88E6XXX_PORT_STS_CMODE_XAUI: 681 case MV88E6XXX_PORT_STS_CMODE_RXAUI: 682 err = mv88e6390_serdes_power_10g(chip, lane, up); 683 break; 684 } 685 686 if (!err && up) 687 err = mv88e6390_serdes_enable_checker(chip, lane); 688 689 return err; 690 } 691 692 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, 693 u8 lane, unsigned int mode, 694 phy_interface_t interface, 695 const unsigned long *advertise) 696 { 697 u16 val, bmcr, adv; 698 bool changed; 699 int err; 700 701 switch (interface) { 702 case PHY_INTERFACE_MODE_SGMII: 703 adv = 0x0001; 704 break; 705 706 case PHY_INTERFACE_MODE_1000BASEX: 707 adv = linkmode_adv_to_mii_adv_x(advertise, 708 ETHTOOL_LINK_MODE_1000baseX_Full_BIT); 709 break; 710 711 case PHY_INTERFACE_MODE_2500BASEX: 712 adv = linkmode_adv_to_mii_adv_x(advertise, 713 ETHTOOL_LINK_MODE_2500baseX_Full_BIT); 714 break; 715 716 default: 717 return 0; 718 } 719 720 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 721 MV88E6390_SGMII_ADVERTISE, &val); 722 if (err) 723 return err; 724 725 changed = val != adv; 726 if (changed) { 727 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 728 MV88E6390_SGMII_ADVERTISE, adv); 729 if (err) 730 return err; 731 } 732 733 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 734 MV88E6390_SGMII_BMCR, &val); 735 if (err) 736 return err; 737 738 if (phylink_autoneg_inband(mode)) 739 bmcr = val | BMCR_ANENABLE; 740 else 741 bmcr = val & ~BMCR_ANENABLE; 742 743 /* setting ANENABLE triggers a restart of negotiation */ 744 if (bmcr == val) 745 return changed; 746 747 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 748 MV88E6390_SGMII_BMCR, bmcr); 749 } 750 751 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 752 u8 lane, struct phylink_link_state *state) 753 { 754 u16 lpa, status; 755 int err; 756 757 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 758 MV88E6390_SGMII_PHY_STATUS, &status); 759 if (err) { 760 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err); 761 return err; 762 } 763 764 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 765 MV88E6390_SGMII_LPA, &lpa); 766 if (err) { 767 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err); 768 return err; 769 } 770 771 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state); 772 } 773 774 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, 775 u8 lane) 776 { 777 u16 bmcr; 778 int err; 779 780 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 781 MV88E6390_SGMII_BMCR, &bmcr); 782 if (err) 783 return err; 784 785 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 786 MV88E6390_SGMII_BMCR, 787 bmcr | BMCR_ANRESTART); 788 } 789 790 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port, 791 u8 lane, int speed, int duplex) 792 { 793 u16 val, bmcr; 794 int err; 795 796 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 797 MV88E6390_SGMII_BMCR, &val); 798 if (err) 799 return err; 800 801 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000); 802 switch (speed) { 803 case SPEED_2500: 804 case SPEED_1000: 805 bmcr |= BMCR_SPEED1000; 806 break; 807 case SPEED_100: 808 bmcr |= BMCR_SPEED100; 809 break; 810 case SPEED_10: 811 break; 812 } 813 814 if (duplex == DUPLEX_FULL) 815 bmcr |= BMCR_FULLDPLX; 816 817 if (bmcr == val) 818 return 0; 819 820 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 821 MV88E6390_SGMII_BMCR, bmcr); 822 } 823 824 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, 825 int port, u8 lane) 826 { 827 u16 bmsr; 828 int err; 829 830 /* If the link has dropped, we want to know about it. */ 831 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 832 MV88E6390_SGMII_BMSR, &bmsr); 833 if (err) { 834 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err); 835 return; 836 } 837 838 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS)); 839 } 840 841 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip, 842 u8 lane, bool enable) 843 { 844 u16 val = 0; 845 846 if (enable) 847 val |= MV88E6390_SGMII_INT_LINK_DOWN | 848 MV88E6390_SGMII_INT_LINK_UP; 849 850 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 851 MV88E6390_SGMII_INT_ENABLE, val); 852 } 853 854 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, 855 bool enable) 856 { 857 u8 cmode = chip->ports[port].cmode; 858 859 switch (cmode) { 860 case MV88E6XXX_PORT_STS_CMODE_SGMII: 861 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 862 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 863 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable); 864 } 865 866 return 0; 867 } 868 869 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip, 870 u8 lane, u16 *status) 871 { 872 int err; 873 874 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 875 MV88E6390_SGMII_INT_STATUS, status); 876 877 return err; 878 } 879 880 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 881 u8 lane) 882 { 883 u8 cmode = chip->ports[port].cmode; 884 irqreturn_t ret = IRQ_NONE; 885 u16 status; 886 int err; 887 888 switch (cmode) { 889 case MV88E6XXX_PORT_STS_CMODE_SGMII: 890 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 891 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 892 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status); 893 if (err) 894 return ret; 895 if (status & (MV88E6390_SGMII_INT_LINK_DOWN | 896 MV88E6390_SGMII_INT_LINK_UP)) { 897 ret = IRQ_HANDLED; 898 mv88e6390_serdes_irq_link_sgmii(chip, port, lane); 899 } 900 } 901 902 return ret; 903 } 904 905 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 906 { 907 return irq_find_mapping(chip->g2_irq.domain, port); 908 } 909 910 static const u16 mv88e6390_serdes_regs[] = { 911 /* SERDES common registers */ 912 0xf00a, 0xf00b, 0xf00c, 913 0xf010, 0xf011, 0xf012, 0xf013, 914 0xf016, 0xf017, 0xf018, 915 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 916 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027, 917 0xf028, 0xf029, 918 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 919 0xf038, 0xf039, 920 /* SGMII */ 921 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 922 0x2008, 923 0x200f, 924 0xa000, 0xa001, 0xa002, 0xa003, 925 /* 10Gbase-X */ 926 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 927 0x1008, 928 0x100e, 0x100f, 929 0x1018, 0x1019, 930 0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 931 0x9006, 932 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016, 933 /* 10Gbase-R */ 934 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, 935 0x1028, 0x1029, 0x102a, 0x102b, 936 }; 937 938 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port) 939 { 940 if (mv88e6xxx_serdes_get_lane(chip, port) == 0) 941 return 0; 942 943 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16); 944 } 945 946 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) 947 { 948 u16 *p = _p; 949 int lane; 950 u16 reg; 951 int i; 952 953 lane = mv88e6xxx_serdes_get_lane(chip, port); 954 if (lane == 0) 955 return; 956 957 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) { 958 mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 959 mv88e6390_serdes_regs[i], ®); 960 p[i] = reg; 961 } 962 } 963