|
50 | 50 | #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14)
|
51 | 51 | #define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11)
|
52 | 52 | #define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)
|
| 53 | +#define MDIO_AN_VEND_PROV_EXC_PHYID_INFO BIT(6) |
53 | 54 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)
|
54 | 55 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)
|
55 | 56 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4
|
@@ -333,6 +334,238 @@ static int aqr_read_status(struct phy_device *phydev)
|
333 | 334 | return genphy_c45_read_status(phydev);
|
334 | 335 | }
|
335 | 336 |
|
| 337 | +static int aqr105_get_features(struct phy_device *phydev) |
| 338 | +{ |
| 339 | + int ret; |
| 340 | + |
| 341 | + /* Normal feature discovery */ |
| 342 | + ret = genphy_c45_pma_read_abilities(phydev); |
| 343 | + if (ret) |
| 344 | + return ret; |
| 345 | + |
| 346 | + /* The AQR105 PHY misses to indicate the 2.5G and 5G modes, so add them |
| 347 | + * here |
| 348 | + */ |
| 349 | + linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, |
| 350 | + phydev->supported); |
| 351 | + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, |
| 352 | + phydev->supported); |
| 353 | + |
| 354 | + /* The AQR105 PHY suppports both RJ45 and SFP+ interfaces */ |
| 355 | + linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, phydev->supported); |
| 356 | + linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); |
| 357 | + |
| 358 | + return 0; |
| 359 | +} |
| 360 | + |
| 361 | +static int aqr105_setup_forced(struct phy_device *phydev) |
| 362 | +{ |
| 363 | + int vend = MDIO_AN_VEND_PROV_EXC_PHYID_INFO; |
| 364 | + int ctrl10 = 0; |
| 365 | + int adv = ADVERTISE_CSMA; |
| 366 | + int ret; |
| 367 | + |
| 368 | + switch (phydev->speed) { |
| 369 | + case SPEED_100: |
| 370 | + adv |= ADVERTISE_100FULL; |
| 371 | + break; |
| 372 | + case SPEED_1000: |
| 373 | + adv |= ADVERTISE_NPAGE; |
| 374 | + if (phydev->duplex == DUPLEX_FULL) |
| 375 | + vend |= MDIO_AN_VEND_PROV_1000BASET_FULL; |
| 376 | + else |
| 377 | + vend |= MDIO_AN_VEND_PROV_1000BASET_HALF; |
| 378 | + break; |
| 379 | + case SPEED_2500: |
| 380 | + adv |= (ADVERTISE_NPAGE | ADVERTISE_RESV); |
| 381 | + vend |= MDIO_AN_VEND_PROV_2500BASET_FULL; |
| 382 | + break; |
| 383 | + case SPEED_5000: |
| 384 | + adv |= (ADVERTISE_NPAGE | ADVERTISE_RESV); |
| 385 | + vend |= MDIO_AN_VEND_PROV_5000BASET_FULL; |
| 386 | + break; |
| 387 | + case SPEED_10000: |
| 388 | + adv |= (ADVERTISE_NPAGE | ADVERTISE_RESV); |
| 389 | + ctrl10 |= MDIO_AN_10GBT_CTRL_ADV10G; |
| 390 | + break; |
| 391 | + default: |
| 392 | + return -EINVAL; |
| 393 | + } |
| 394 | + ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, adv); |
| 395 | + if (ret < 0) |
| 396 | + return ret; |
| 397 | + ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, vend); |
| 398 | + if (ret < 0) |
| 399 | + return ret; |
| 400 | + ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, ctrl10); |
| 401 | + if (ret < 0) |
| 402 | + return ret; |
| 403 | + |
| 404 | + /* set by vendor driver, but should be on by default */ |
| 405 | + ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, |
| 406 | + MDIO_AN_CTRL1_XNP); |
| 407 | + if (ret < 0) |
| 408 | + return ret; |
| 409 | + |
| 410 | + return genphy_c45_an_disable_aneg(phydev); |
| 411 | +} |
| 412 | + |
| 413 | +static int aqr105_config_aneg(struct phy_device *phydev) |
| 414 | +{ |
| 415 | + bool changed = false; |
| 416 | + u16 reg; |
| 417 | + int ret; |
| 418 | + |
| 419 | + ret = aqr_set_mdix(phydev, phydev->mdix_ctrl); |
| 420 | + if (ret < 0) |
| 421 | + return ret; |
| 422 | + if (ret > 0) |
| 423 | + changed = true; |
| 424 | + |
| 425 | + if (phydev->autoneg == AUTONEG_DISABLE) |
| 426 | + return aqr105_setup_forced(phydev); |
| 427 | + |
| 428 | + ret = genphy_c45_an_config_aneg(phydev); |
| 429 | + if (ret < 0) |
| 430 | + return ret; |
| 431 | + if (ret > 0) |
| 432 | + changed = true; |
| 433 | + |
| 434 | + /* Clause 45 has no standardized support for 1000BaseT, therefore |
| 435 | + * use vendor registers for this mode. |
| 436 | + */ |
| 437 | + reg = 0; |
| 438 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, |
| 439 | + phydev->advertising)) |
| 440 | + reg |= MDIO_AN_VEND_PROV_1000BASET_FULL; |
| 441 | + |
| 442 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
| 443 | + phydev->advertising)) |
| 444 | + reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; |
| 445 | + |
| 446 | + /* Handle the case when the 2.5G and 5G speeds are not advertised */ |
| 447 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, |
| 448 | + phydev->advertising)) |
| 449 | + reg |= MDIO_AN_VEND_PROV_2500BASET_FULL; |
| 450 | + |
| 451 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, |
| 452 | + phydev->advertising)) |
| 453 | + reg |= MDIO_AN_VEND_PROV_5000BASET_FULL; |
| 454 | + |
| 455 | + ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, |
| 456 | + MDIO_AN_VEND_PROV_1000BASET_HALF | |
| 457 | + MDIO_AN_VEND_PROV_1000BASET_FULL | |
| 458 | + MDIO_AN_VEND_PROV_2500BASET_FULL | |
| 459 | + MDIO_AN_VEND_PROV_5000BASET_FULL, reg); |
| 460 | + if (ret < 0) |
| 461 | + return ret; |
| 462 | + if (ret > 0) |
| 463 | + changed = true; |
| 464 | + |
| 465 | + return genphy_c45_check_and_restart_aneg(phydev, changed); |
| 466 | +} |
| 467 | + |
| 468 | +static int aqr105_read_rate(struct phy_device *phydev) |
| 469 | +{ |
| 470 | + int val; |
| 471 | + |
| 472 | + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1); |
| 473 | + if (val < 0) |
| 474 | + return val; |
| 475 | + |
| 476 | + if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX) |
| 477 | + phydev->duplex = DUPLEX_FULL; |
| 478 | + else |
| 479 | + phydev->duplex = DUPLEX_HALF; |
| 480 | + |
| 481 | + switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) { |
| 482 | + case MDIO_AN_TX_VEND_STATUS1_10BASET: |
| 483 | + phydev->speed = SPEED_10; |
| 484 | + break; |
| 485 | + case MDIO_AN_TX_VEND_STATUS1_100BASETX: |
| 486 | + phydev->speed = SPEED_100; |
| 487 | + break; |
| 488 | + case MDIO_AN_TX_VEND_STATUS1_1000BASET: |
| 489 | + phydev->speed = SPEED_1000; |
| 490 | + break; |
| 491 | + case MDIO_AN_TX_VEND_STATUS1_2500BASET: |
| 492 | + phydev->speed = SPEED_2500; |
| 493 | + break; |
| 494 | + case MDIO_AN_TX_VEND_STATUS1_5000BASET: |
| 495 | + phydev->speed = SPEED_5000; |
| 496 | + break; |
| 497 | + case MDIO_AN_TX_VEND_STATUS1_10GBASET: |
| 498 | + phydev->speed = SPEED_10000; |
| 499 | + break; |
| 500 | + default: |
| 501 | + phydev->speed = SPEED_UNKNOWN; |
| 502 | + } |
| 503 | + |
| 504 | + return 0; |
| 505 | +} |
| 506 | + |
| 507 | +static int aqr105_read_status(struct phy_device *phydev) |
| 508 | +{ |
| 509 | + int ret; |
| 510 | + int val; |
| 511 | + |
| 512 | + ret = aqr_read_status(phydev); |
| 513 | + if (ret) |
| 514 | + return ret; |
| 515 | + |
| 516 | + if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE) |
| 517 | + return 0; |
| 518 | + |
| 519 | + /** |
| 520 | + * The status register is not immediately correct on line side link up. |
| 521 | + * Poll periodically until it reflects the correct ON state. |
| 522 | + * Only return fail for read error, timeout defaults to OFF state. |
| 523 | + */ |
| 524 | + ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PHYXS, |
| 525 | + MDIO_PHYXS_VEND_IF_STATUS, val, |
| 526 | + (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val) != |
| 527 | + MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF), |
| 528 | + AQR107_OP_IN_PROG_SLEEP, |
| 529 | + AQR107_OP_IN_PROG_TIMEOUT, false); |
| 530 | + if (ret && ret != -ETIMEDOUT) |
| 531 | + return ret; |
| 532 | + |
| 533 | + switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) { |
| 534 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR: |
| 535 | + phydev->interface = PHY_INTERFACE_MODE_10GKR; |
| 536 | + break; |
| 537 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX: |
| 538 | + phydev->interface = PHY_INTERFACE_MODE_1000BASEKX; |
| 539 | + break; |
| 540 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI: |
| 541 | + phydev->interface = PHY_INTERFACE_MODE_10GBASER; |
| 542 | + break; |
| 543 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII: |
| 544 | + phydev->interface = PHY_INTERFACE_MODE_USXGMII; |
| 545 | + break; |
| 546 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI: |
| 547 | + phydev->interface = PHY_INTERFACE_MODE_XAUI; |
| 548 | + break; |
| 549 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII: |
| 550 | + phydev->interface = PHY_INTERFACE_MODE_SGMII; |
| 551 | + break; |
| 552 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI: |
| 553 | + phydev->interface = PHY_INTERFACE_MODE_RXAUI; |
| 554 | + break; |
| 555 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII: |
| 556 | + phydev->interface = PHY_INTERFACE_MODE_2500BASEX; |
| 557 | + break; |
| 558 | + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF: |
| 559 | + default: |
| 560 | + phydev->link = false; |
| 561 | + phydev->interface = PHY_INTERFACE_MODE_NA; |
| 562 | + break; |
| 563 | + } |
| 564 | + |
| 565 | + /* Read rate from vendor register */ |
| 566 | + return aqr105_read_rate(phydev); |
| 567 | +} |
| 568 | + |
336 | 569 | static int aqr107_read_rate(struct phy_device *phydev)
|
337 | 570 | {
|
338 | 571 | u32 config_reg;
|
@@ -911,11 +1144,13 @@ static struct phy_driver aqr_driver[] = {
|
911 | 1144 | {
|
912 | 1145 | PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
|
913 | 1146 | .name = "Aquantia AQR105",
|
914 |
| - .config_aneg = aqr_config_aneg, |
| 1147 | + .get_features = aqr105_get_features, |
915 | 1148 | .probe = aqr107_probe,
|
| 1149 | + .config_init = aqr107_config_init, |
| 1150 | + .config_aneg = aqr105_config_aneg, |
916 | 1151 | .config_intr = aqr_config_intr,
|
917 | 1152 | .handle_interrupt = aqr_handle_interrupt,
|
918 |
| - .read_status = aqr_read_status, |
| 1153 | + .read_status = aqr105_read_status, |
919 | 1154 | .suspend = aqr107_suspend,
|
920 | 1155 | .resume = aqr107_resume,
|
921 | 1156 | },
|
|
0 commit comments