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 struct dsa_switch *ds = chip->ds; 344 u16 status; 345 bool up; 346 int err; 347 348 err = mv88e6352_serdes_read(chip, MII_BMSR, &status); 349 if (err) 350 return; 351 352 /* Status must be read twice in order to give the current link 353 * status. Otherwise the change in link status since the last 354 * read of the register is returned. 355 */ 356 err = mv88e6352_serdes_read(chip, MII_BMSR, &status); 357 if (err) 358 return; 359 360 up = status & BMSR_LSTATUS; 361 362 dsa_port_phylink_mac_change(ds, port, up); 363 } 364 365 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 366 u8 lane) 367 { 368 irqreturn_t ret = IRQ_NONE; 369 u16 status; 370 int err; 371 372 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status); 373 if (err) 374 return ret; 375 376 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) { 377 ret = IRQ_HANDLED; 378 mv88e6352_serdes_irq_link(chip, port); 379 } 380 381 return ret; 382 } 383 384 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, 385 bool enable) 386 { 387 u16 val = 0; 388 389 if (enable) 390 val |= MV88E6352_SERDES_INT_LINK_CHANGE; 391 392 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val); 393 } 394 395 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 396 { 397 return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ); 398 } 399 400 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port) 401 { 402 if (!mv88e6352_port_has_serdes(chip, port)) 403 return 0; 404 405 return 32 * sizeof(u16); 406 } 407 408 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) 409 { 410 u16 *p = _p; 411 u16 reg; 412 int i; 413 414 if (!mv88e6352_port_has_serdes(chip, port)) 415 return; 416 417 for (i = 0 ; i < 32; i++) { 418 mv88e6352_serdes_read(chip, i, ®); 419 p[i] = reg; 420 } 421 } 422 423 u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 424 { 425 u8 cmode = chip->ports[port].cmode; 426 u8 lane = 0; 427 428 switch (port) { 429 case 5: 430 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 431 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 432 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 433 lane = MV88E6341_PORT5_LANE; 434 break; 435 } 436 437 return lane; 438 } 439 440 u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 441 { 442 u8 cmode = chip->ports[port].cmode; 443 u8 lane = 0; 444 445 switch (port) { 446 case 9: 447 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 448 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 449 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 450 lane = MV88E6390_PORT9_LANE0; 451 break; 452 case 10: 453 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 454 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 455 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 456 lane = MV88E6390_PORT10_LANE0; 457 break; 458 } 459 460 return lane; 461 } 462 463 u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 464 { 465 u8 cmode_port = chip->ports[port].cmode; 466 u8 cmode_port10 = chip->ports[10].cmode; 467 u8 cmode_port9 = chip->ports[9].cmode; 468 u8 lane = 0; 469 470 switch (port) { 471 case 2: 472 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 473 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 474 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 475 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 476 lane = MV88E6390_PORT9_LANE1; 477 break; 478 case 3: 479 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 480 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 481 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 482 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 483 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 484 lane = MV88E6390_PORT9_LANE2; 485 break; 486 case 4: 487 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 488 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 489 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 490 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 491 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 492 lane = MV88E6390_PORT9_LANE3; 493 break; 494 case 5: 495 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 496 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 497 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 498 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 499 lane = MV88E6390_PORT10_LANE1; 500 break; 501 case 6: 502 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 503 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 504 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 505 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 506 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 507 lane = MV88E6390_PORT10_LANE2; 508 break; 509 case 7: 510 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 511 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 512 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 513 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 514 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 515 lane = MV88E6390_PORT10_LANE3; 516 break; 517 case 9: 518 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 519 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 520 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 521 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI || 522 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 523 lane = MV88E6390_PORT9_LANE0; 524 break; 525 case 10: 526 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 527 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 528 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 529 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI || 530 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 531 lane = MV88E6390_PORT10_LANE0; 532 break; 533 } 534 535 return lane; 536 } 537 538 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */ 539 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, 540 bool up) 541 { 542 u16 val, new_val; 543 int err; 544 545 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 546 MV88E6390_PCS_CONTROL_1, &val); 547 548 if (err) 549 return err; 550 551 if (up) 552 new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET | 553 MV88E6390_PCS_CONTROL_1_LOOPBACK | 554 MV88E6390_PCS_CONTROL_1_PDOWN); 555 else 556 new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN; 557 558 if (val != new_val) 559 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 560 MV88E6390_PCS_CONTROL_1, new_val); 561 562 return err; 563 } 564 565 /* Set power up/down for SGMII and 1000Base-X */ 566 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, 567 bool up) 568 { 569 u16 val, new_val; 570 int err; 571 572 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 573 MV88E6390_SGMII_BMCR, &val); 574 if (err) 575 return err; 576 577 if (up) 578 new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN); 579 else 580 new_val = val | BMCR_PDOWN; 581 582 if (val != new_val) 583 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 584 MV88E6390_SGMII_BMCR, new_val); 585 586 return err; 587 } 588 589 struct mv88e6390_serdes_hw_stat { 590 char string[ETH_GSTRING_LEN]; 591 int reg; 592 }; 593 594 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = { 595 { "serdes_rx_pkts", 0xf021 }, 596 { "serdes_rx_bytes", 0xf024 }, 597 { "serdes_rx_pkts_error", 0xf027 }, 598 }; 599 600 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) 601 { 602 if (mv88e6390_serdes_get_lane(chip, port) == 0) 603 return 0; 604 605 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 606 } 607 608 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip, 609 int port, uint8_t *data) 610 { 611 struct mv88e6390_serdes_hw_stat *stat; 612 int i; 613 614 if (mv88e6390_serdes_get_lane(chip, port) == 0) 615 return 0; 616 617 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) { 618 stat = &mv88e6390_serdes_hw_stats[i]; 619 memcpy(data + i * ETH_GSTRING_LEN, stat->string, 620 ETH_GSTRING_LEN); 621 } 622 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 623 } 624 625 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane, 626 struct mv88e6390_serdes_hw_stat *stat) 627 { 628 u16 reg[3]; 629 int err, i; 630 631 for (i = 0; i < 3; i++) { 632 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 633 stat->reg + i, ®[i]); 634 if (err) { 635 dev_err(chip->dev, "failed to read statistic\n"); 636 return 0; 637 } 638 } 639 640 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32); 641 } 642 643 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 644 uint64_t *data) 645 { 646 struct mv88e6390_serdes_hw_stat *stat; 647 int lane; 648 int i; 649 650 lane = mv88e6390_serdes_get_lane(chip, port); 651 if (lane == 0) 652 return 0; 653 654 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) { 655 stat = &mv88e6390_serdes_hw_stats[i]; 656 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat); 657 } 658 659 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 660 } 661 662 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, u8 lane) 663 { 664 u16 reg; 665 int err; 666 667 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 668 MV88E6390_PG_CONTROL, ®); 669 if (err) 670 return err; 671 672 reg |= MV88E6390_PG_CONTROL_ENABLE_PC; 673 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 674 MV88E6390_PG_CONTROL, reg); 675 } 676 677 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, 678 bool up) 679 { 680 u8 cmode = chip->ports[port].cmode; 681 int err = 0; 682 683 switch (cmode) { 684 case MV88E6XXX_PORT_STS_CMODE_SGMII: 685 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 686 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 687 err = mv88e6390_serdes_power_sgmii(chip, lane, up); 688 break; 689 case MV88E6XXX_PORT_STS_CMODE_XAUI: 690 case MV88E6XXX_PORT_STS_CMODE_RXAUI: 691 err = mv88e6390_serdes_power_10g(chip, lane, up); 692 break; 693 } 694 695 if (!err && up) 696 err = mv88e6390_serdes_enable_checker(chip, lane); 697 698 return err; 699 } 700 701 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, 702 u8 lane, unsigned int mode, 703 phy_interface_t interface, 704 const unsigned long *advertise) 705 { 706 u16 val, bmcr, adv; 707 bool changed; 708 int err; 709 710 switch (interface) { 711 case PHY_INTERFACE_MODE_SGMII: 712 adv = 0x0001; 713 break; 714 715 case PHY_INTERFACE_MODE_1000BASEX: 716 adv = linkmode_adv_to_mii_adv_x(advertise, 717 ETHTOOL_LINK_MODE_1000baseX_Full_BIT); 718 break; 719 720 case PHY_INTERFACE_MODE_2500BASEX: 721 adv = linkmode_adv_to_mii_adv_x(advertise, 722 ETHTOOL_LINK_MODE_2500baseX_Full_BIT); 723 break; 724 725 default: 726 return 0; 727 } 728 729 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 730 MV88E6390_SGMII_ADVERTISE, &val); 731 if (err) 732 return err; 733 734 changed = val != adv; 735 if (changed) { 736 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 737 MV88E6390_SGMII_ADVERTISE, adv); 738 if (err) 739 return err; 740 } 741 742 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 743 MV88E6390_SGMII_BMCR, &val); 744 if (err) 745 return err; 746 747 if (phylink_autoneg_inband(mode)) 748 bmcr = val | BMCR_ANENABLE; 749 else 750 bmcr = val & ~BMCR_ANENABLE; 751 752 /* setting ANENABLE triggers a restart of negotiation */ 753 if (bmcr == val) 754 return changed; 755 756 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 757 MV88E6390_SGMII_BMCR, bmcr); 758 } 759 760 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 761 u8 lane, struct phylink_link_state *state) 762 { 763 u16 lpa, status; 764 int err; 765 766 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 767 MV88E6390_SGMII_PHY_STATUS, &status); 768 if (err) { 769 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err); 770 return err; 771 } 772 773 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 774 MV88E6390_SGMII_LPA, &lpa); 775 if (err) { 776 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err); 777 return err; 778 } 779 780 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state); 781 } 782 783 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, 784 u8 lane) 785 { 786 u16 bmcr; 787 int err; 788 789 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 790 MV88E6390_SGMII_BMCR, &bmcr); 791 if (err) 792 return err; 793 794 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 795 MV88E6390_SGMII_BMCR, 796 bmcr | BMCR_ANRESTART); 797 } 798 799 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port, 800 u8 lane, int speed, int duplex) 801 { 802 u16 val, bmcr; 803 int err; 804 805 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 806 MV88E6390_SGMII_BMCR, &val); 807 if (err) 808 return err; 809 810 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000); 811 switch (speed) { 812 case SPEED_2500: 813 case SPEED_1000: 814 bmcr |= BMCR_SPEED1000; 815 break; 816 case SPEED_100: 817 bmcr |= BMCR_SPEED100; 818 break; 819 case SPEED_10: 820 break; 821 } 822 823 if (duplex == DUPLEX_FULL) 824 bmcr |= BMCR_FULLDPLX; 825 826 if (bmcr == val) 827 return 0; 828 829 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 830 MV88E6390_SGMII_BMCR, bmcr); 831 } 832 833 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, 834 int port, u8 lane) 835 { 836 u16 status; 837 int err; 838 839 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 840 MV88E6390_SGMII_PHY_STATUS, &status); 841 if (err) { 842 dev_err(chip->dev, "can't read SGMII PHY status: %d\n", err); 843 return; 844 } 845 846 dsa_port_phylink_mac_change(chip->ds, port, 847 !!(status & MV88E6390_SGMII_PHY_STATUS_LINK)); 848 } 849 850 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip, 851 u8 lane, bool enable) 852 { 853 u16 val = 0; 854 855 if (enable) 856 val |= MV88E6390_SGMII_INT_LINK_DOWN | 857 MV88E6390_SGMII_INT_LINK_UP; 858 859 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 860 MV88E6390_SGMII_INT_ENABLE, val); 861 } 862 863 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, 864 bool enable) 865 { 866 u8 cmode = chip->ports[port].cmode; 867 868 switch (cmode) { 869 case MV88E6XXX_PORT_STS_CMODE_SGMII: 870 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 871 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 872 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable); 873 } 874 875 return 0; 876 } 877 878 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip, 879 u8 lane, u16 *status) 880 { 881 int err; 882 883 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 884 MV88E6390_SGMII_INT_STATUS, status); 885 886 return err; 887 } 888 889 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 890 u8 lane) 891 { 892 u8 cmode = chip->ports[port].cmode; 893 irqreturn_t ret = IRQ_NONE; 894 u16 status; 895 int err; 896 897 switch (cmode) { 898 case MV88E6XXX_PORT_STS_CMODE_SGMII: 899 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 900 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 901 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status); 902 if (err) 903 return ret; 904 if (status & (MV88E6390_SGMII_INT_LINK_DOWN | 905 MV88E6390_SGMII_INT_LINK_UP)) { 906 ret = IRQ_HANDLED; 907 mv88e6390_serdes_irq_link_sgmii(chip, port, lane); 908 } 909 } 910 911 return ret; 912 } 913 914 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 915 { 916 return irq_find_mapping(chip->g2_irq.domain, port); 917 } 918 919 static const u16 mv88e6390_serdes_regs[] = { 920 /* SERDES common registers */ 921 0xf00a, 0xf00b, 0xf00c, 922 0xf010, 0xf011, 0xf012, 0xf013, 923 0xf016, 0xf017, 0xf018, 924 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 925 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027, 926 0xf028, 0xf029, 927 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 928 0xf038, 0xf039, 929 /* SGMII */ 930 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 931 0x2008, 932 0x200f, 933 0xa000, 0xa001, 0xa002, 0xa003, 934 /* 10Gbase-X */ 935 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 936 0x1008, 937 0x100e, 0x100f, 938 0x1018, 0x1019, 939 0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 940 0x9006, 941 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016, 942 /* 10Gbase-R */ 943 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, 944 0x1028, 0x1029, 0x102a, 0x102b, 945 }; 946 947 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port) 948 { 949 if (mv88e6xxx_serdes_get_lane(chip, port) == 0) 950 return 0; 951 952 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16); 953 } 954 955 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) 956 { 957 u16 *p = _p; 958 int lane; 959 u16 reg; 960 int i; 961 962 lane = mv88e6xxx_serdes_get_lane(chip, port); 963 if (lane == 0) 964 return; 965 966 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) { 967 mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 968 mv88e6390_serdes_regs[i], ®); 969 p[i] = reg; 970 } 971 } 972