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_10G_CTRL1, &val); 538 539 if (err) 540 return err; 541 542 if (up) 543 new_val = val & ~(MDIO_CTRL1_RESET | 544 MDIO_PCS_CTRL1_LOOPBACK | 545 MDIO_CTRL1_LPOWER); 546 else 547 new_val = val | MDIO_CTRL1_LPOWER; 548 549 if (val != new_val) 550 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 551 MV88E6390_10G_CTRL1, 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 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, 752 int port, 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 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip, 775 int port, u8 lane, struct phylink_link_state *state) 776 { 777 u16 status; 778 int err; 779 780 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 781 MV88E6390_10G_STAT1, &status); 782 if (err) 783 return err; 784 785 state->link = !!(status & MDIO_STAT1_LSTATUS); 786 if (state->link) { 787 state->speed = SPEED_10000; 788 state->duplex = DUPLEX_FULL; 789 } 790 791 return 0; 792 } 793 794 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 795 u8 lane, struct phylink_link_state *state) 796 { 797 switch (state->interface) { 798 case PHY_INTERFACE_MODE_SGMII: 799 case PHY_INTERFACE_MODE_1000BASEX: 800 case PHY_INTERFACE_MODE_2500BASEX: 801 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane, 802 state); 803 case PHY_INTERFACE_MODE_XAUI: 804 case PHY_INTERFACE_MODE_RXAUI: 805 return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane, 806 state); 807 808 default: 809 return -EOPNOTSUPP; 810 } 811 } 812 813 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, 814 u8 lane) 815 { 816 u16 bmcr; 817 int err; 818 819 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 820 MV88E6390_SGMII_BMCR, &bmcr); 821 if (err) 822 return err; 823 824 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 825 MV88E6390_SGMII_BMCR, 826 bmcr | BMCR_ANRESTART); 827 } 828 829 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port, 830 u8 lane, int speed, int duplex) 831 { 832 u16 val, bmcr; 833 int err; 834 835 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 836 MV88E6390_SGMII_BMCR, &val); 837 if (err) 838 return err; 839 840 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000); 841 switch (speed) { 842 case SPEED_2500: 843 case SPEED_1000: 844 bmcr |= BMCR_SPEED1000; 845 break; 846 case SPEED_100: 847 bmcr |= BMCR_SPEED100; 848 break; 849 case SPEED_10: 850 break; 851 } 852 853 if (duplex == DUPLEX_FULL) 854 bmcr |= BMCR_FULLDPLX; 855 856 if (bmcr == val) 857 return 0; 858 859 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 860 MV88E6390_SGMII_BMCR, bmcr); 861 } 862 863 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, 864 int port, u8 lane) 865 { 866 u16 bmsr; 867 int err; 868 869 /* If the link has dropped, we want to know about it. */ 870 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 871 MV88E6390_SGMII_BMSR, &bmsr); 872 if (err) { 873 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err); 874 return; 875 } 876 877 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS)); 878 } 879 880 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip, 881 u8 lane, bool enable) 882 { 883 u16 val = 0; 884 885 if (enable) 886 val |= MV88E6390_SGMII_INT_LINK_DOWN | 887 MV88E6390_SGMII_INT_LINK_UP; 888 889 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 890 MV88E6390_SGMII_INT_ENABLE, val); 891 } 892 893 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, 894 bool enable) 895 { 896 u8 cmode = chip->ports[port].cmode; 897 898 switch (cmode) { 899 case MV88E6XXX_PORT_STS_CMODE_SGMII: 900 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 901 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 902 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable); 903 } 904 905 return 0; 906 } 907 908 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip, 909 u8 lane, u16 *status) 910 { 911 int err; 912 913 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 914 MV88E6390_SGMII_INT_STATUS, status); 915 916 return err; 917 } 918 919 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 920 u8 lane) 921 { 922 u8 cmode = chip->ports[port].cmode; 923 irqreturn_t ret = IRQ_NONE; 924 u16 status; 925 int err; 926 927 switch (cmode) { 928 case MV88E6XXX_PORT_STS_CMODE_SGMII: 929 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 930 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 931 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status); 932 if (err) 933 return ret; 934 if (status & (MV88E6390_SGMII_INT_LINK_DOWN | 935 MV88E6390_SGMII_INT_LINK_UP)) { 936 ret = IRQ_HANDLED; 937 mv88e6390_serdes_irq_link_sgmii(chip, port, lane); 938 } 939 } 940 941 return ret; 942 } 943 944 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 945 { 946 return irq_find_mapping(chip->g2_irq.domain, port); 947 } 948 949 static const u16 mv88e6390_serdes_regs[] = { 950 /* SERDES common registers */ 951 0xf00a, 0xf00b, 0xf00c, 952 0xf010, 0xf011, 0xf012, 0xf013, 953 0xf016, 0xf017, 0xf018, 954 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 955 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027, 956 0xf028, 0xf029, 957 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 958 0xf038, 0xf039, 959 /* SGMII */ 960 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 961 0x2008, 962 0x200f, 963 0xa000, 0xa001, 0xa002, 0xa003, 964 /* 10Gbase-X */ 965 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 966 0x1008, 967 0x100e, 0x100f, 968 0x1018, 0x1019, 969 0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 970 0x9006, 971 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016, 972 /* 10Gbase-R */ 973 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, 974 0x1028, 0x1029, 0x102a, 0x102b, 975 }; 976 977 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port) 978 { 979 if (mv88e6xxx_serdes_get_lane(chip, port) == 0) 980 return 0; 981 982 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16); 983 } 984 985 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) 986 { 987 u16 *p = _p; 988 int lane; 989 u16 reg; 990 int i; 991 992 lane = mv88e6xxx_serdes_get_lane(chip, port); 993 if (lane == 0) 994 return; 995 996 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) { 997 mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 998 mv88e6390_serdes_regs[i], ®); 999 p[i] = reg; 1000 } 1001 } 1002