marvell10g.c (8d8963c3db6c3895eadf028d8c782cf18c1b3ff2) | marvell10g.c (a585c03e63fd3537cdf94e52485699617424453c) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Marvell 10G 88x3310 PHY driver 4 * 5 * Based upon the ID registers, this PHY appears to be a mixture of IPs 6 * from two different companies. 7 * 8 * There appears to be several different data paths through the PHY which --- 27 unchanged lines hidden (view full) --- 36 MV_PMA_BOOT = 0xc050, 37 MV_PMA_BOOT_FATAL = BIT(0), 38 39 MV_PCS_BASE_T = 0x0000, 40 MV_PCS_BASE_R = 0x1000, 41 MV_PCS_1000BASEX = 0x2000, 42 43 MV_PCS_CSCR1 = 0x8000, | 1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Marvell 10G 88x3310 PHY driver 4 * 5 * Based upon the ID registers, this PHY appears to be a mixture of IPs 6 * from two different companies. 7 * 8 * There appears to be several different data paths through the PHY which --- 27 unchanged lines hidden (view full) --- 36 MV_PMA_BOOT = 0xc050, 37 MV_PMA_BOOT_FATAL = BIT(0), 38 39 MV_PCS_BASE_T = 0x0000, 40 MV_PCS_BASE_R = 0x1000, 41 MV_PCS_1000BASEX = 0x2000, 42 43 MV_PCS_CSCR1 = 0x8000, |
44 MV_PCS_CSCR1_ED_MASK = 0x0300, 45 MV_PCS_CSCR1_ED_OFF = 0x0000, 46 MV_PCS_CSCR1_ED_RX = 0x0200, 47 MV_PCS_CSCR1_ED_NLP = 0x0300, |
|
44 MV_PCS_CSCR1_MDIX_MASK = 0x0060, 45 MV_PCS_CSCR1_MDIX_MDI = 0x0000, 46 MV_PCS_CSCR1_MDIX_MDIX = 0x0020, 47 MV_PCS_CSCR1_MDIX_AUTO = 0x0060, 48 49 MV_PCS_CSSR1 = 0x8008, 50 MV_PCS_CSSR1_SPD1_MASK = 0xc000, 51 MV_PCS_CSSR1_SPD1_SPD2 = 0xc000, --- 186 unchanged lines hidden (view full) --- 238 val = phy_read_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1); 239 if (val < 0) 240 return val; 241 } while (val & MDIO_CTRL1_RESET && --retries); 242 243 return val & MDIO_CTRL1_RESET ? -ETIMEDOUT : 0; 244} 245 | 48 MV_PCS_CSCR1_MDIX_MASK = 0x0060, 49 MV_PCS_CSCR1_MDIX_MDI = 0x0000, 50 MV_PCS_CSCR1_MDIX_MDIX = 0x0020, 51 MV_PCS_CSCR1_MDIX_AUTO = 0x0060, 52 53 MV_PCS_CSSR1 = 0x8008, 54 MV_PCS_CSSR1_SPD1_MASK = 0xc000, 55 MV_PCS_CSSR1_SPD1_SPD2 = 0xc000, --- 186 unchanged lines hidden (view full) --- 242 val = phy_read_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1); 243 if (val < 0) 244 return val; 245 } while (val & MDIO_CTRL1_RESET && --retries); 246 247 return val & MDIO_CTRL1_RESET ? -ETIMEDOUT : 0; 248} 249 |
250static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd) 251{ 252 int val; 253 254 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1); 255 if (val < 0) 256 return val; 257 258 switch (val & MV_PCS_CSCR1_ED_MASK) { 259 case MV_PCS_CSCR1_ED_NLP: 260 *edpd = 1000; 261 break; 262 case MV_PCS_CSCR1_ED_RX: 263 *edpd = ETHTOOL_PHY_EDPD_NO_TX; 264 break; 265 default: 266 *edpd = ETHTOOL_PHY_EDPD_DISABLE; 267 break; 268 } 269 return 0; 270} 271 272static int mv3310_set_edpd(struct phy_device *phydev, u16 edpd) 273{ 274 u16 val; 275 int err; 276 277 switch (edpd) { 278 case 1000: 279 case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS: 280 val = MV_PCS_CSCR1_ED_NLP; 281 break; 282 283 case ETHTOOL_PHY_EDPD_NO_TX: 284 val = MV_PCS_CSCR1_ED_RX; 285 break; 286 287 case ETHTOOL_PHY_EDPD_DISABLE: 288 val = MV_PCS_CSCR1_ED_OFF; 289 break; 290 291 default: 292 return -EINVAL; 293 } 294 295 err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1, 296 MV_PCS_CSCR1_ED_MASK, val); 297 if (err > 0) 298 err = mv3310_reset(phydev, MV_PCS_BASE_T); 299 300 return err; 301} 302 |
|
246static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) 247{ 248 struct phy_device *phydev = upstream; 249 __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; 250 phy_interface_t iface; 251 252 sfp_parse_support(phydev->sfp_bus, id, support); 253 iface = sfp_select_interface(phydev->sfp_bus, support); --- 86 unchanged lines hidden (view full) --- 340 phydev->interface != PHY_INTERFACE_MODE_2500BASEX && 341 phydev->interface != PHY_INTERFACE_MODE_XAUI && 342 phydev->interface != PHY_INTERFACE_MODE_RXAUI && 343 phydev->interface != PHY_INTERFACE_MODE_10GBASER) 344 return -ENODEV; 345 346 phydev->mdix_ctrl = ETH_TP_MDI_AUTO; 347 | 303static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) 304{ 305 struct phy_device *phydev = upstream; 306 __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; 307 phy_interface_t iface; 308 309 sfp_parse_support(phydev->sfp_bus, id, support); 310 iface = sfp_select_interface(phydev->sfp_bus, support); --- 86 unchanged lines hidden (view full) --- 397 phydev->interface != PHY_INTERFACE_MODE_2500BASEX && 398 phydev->interface != PHY_INTERFACE_MODE_XAUI && 399 phydev->interface != PHY_INTERFACE_MODE_RXAUI && 400 phydev->interface != PHY_INTERFACE_MODE_10GBASER) 401 return -ENODEV; 402 403 phydev->mdix_ctrl = ETH_TP_MDI_AUTO; 404 |
348 return 0; | 405 /* Enable EDPD mode - saving 600mW */ 406 return mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS); |
349} 350 351static int mv3310_get_features(struct phy_device *phydev) 352{ 353 int ret, val; 354 355 ret = genphy_c45_pma_read_abilities(phydev); 356 if (ret) --- 232 unchanged lines hidden (view full) --- 589 return err; 590 591 if (phydev->link) 592 mv3310_update_interface(phydev); 593 594 return 0; 595} 596 | 407} 408 409static int mv3310_get_features(struct phy_device *phydev) 410{ 411 int ret, val; 412 413 ret = genphy_c45_pma_read_abilities(phydev); 414 if (ret) --- 232 unchanged lines hidden (view full) --- 647 return err; 648 649 if (phydev->link) 650 mv3310_update_interface(phydev); 651 652 return 0; 653} 654 |
655static int mv3310_get_tunable(struct phy_device *phydev, 656 struct ethtool_tunable *tuna, void *data) 657{ 658 switch (tuna->id) { 659 case ETHTOOL_PHY_EDPD: 660 return mv3310_get_edpd(phydev, data); 661 default: 662 return -EOPNOTSUPP; 663 } 664} 665 666static int mv3310_set_tunable(struct phy_device *phydev, 667 struct ethtool_tunable *tuna, const void *data) 668{ 669 switch (tuna->id) { 670 case ETHTOOL_PHY_EDPD: 671 return mv3310_set_edpd(phydev, *(u16 *)data); 672 default: 673 return -EOPNOTSUPP; 674 } 675} 676 |
|
597static struct phy_driver mv3310_drivers[] = { 598 { 599 .phy_id = MARVELL_PHY_ID_88X3310, 600 .phy_id_mask = MARVELL_PHY_ID_MASK, 601 .name = "mv88x3310", 602 .get_features = mv3310_get_features, 603 .soft_reset = genphy_no_soft_reset, 604 .config_init = mv3310_config_init, 605 .probe = mv3310_probe, 606 .suspend = mv3310_suspend, 607 .resume = mv3310_resume, 608 .config_aneg = mv3310_config_aneg, 609 .aneg_done = mv3310_aneg_done, 610 .read_status = mv3310_read_status, | 677static struct phy_driver mv3310_drivers[] = { 678 { 679 .phy_id = MARVELL_PHY_ID_88X3310, 680 .phy_id_mask = MARVELL_PHY_ID_MASK, 681 .name = "mv88x3310", 682 .get_features = mv3310_get_features, 683 .soft_reset = genphy_no_soft_reset, 684 .config_init = mv3310_config_init, 685 .probe = mv3310_probe, 686 .suspend = mv3310_suspend, 687 .resume = mv3310_resume, 688 .config_aneg = mv3310_config_aneg, 689 .aneg_done = mv3310_aneg_done, 690 .read_status = mv3310_read_status, |
691 .get_tunable = mv3310_get_tunable, 692 .set_tunable = mv3310_set_tunable, |
|
611 }, 612 { 613 .phy_id = MARVELL_PHY_ID_88E2110, 614 .phy_id_mask = MARVELL_PHY_ID_MASK, 615 .name = "mv88x2110", 616 .probe = mv3310_probe, 617 .suspend = mv3310_suspend, 618 .resume = mv3310_resume, 619 .soft_reset = genphy_no_soft_reset, 620 .config_init = mv3310_config_init, 621 .config_aneg = mv3310_config_aneg, 622 .aneg_done = mv3310_aneg_done, 623 .read_status = mv3310_read_status, | 693 }, 694 { 695 .phy_id = MARVELL_PHY_ID_88E2110, 696 .phy_id_mask = MARVELL_PHY_ID_MASK, 697 .name = "mv88x2110", 698 .probe = mv3310_probe, 699 .suspend = mv3310_suspend, 700 .resume = mv3310_resume, 701 .soft_reset = genphy_no_soft_reset, 702 .config_init = mv3310_config_init, 703 .config_aneg = mv3310_config_aneg, 704 .aneg_done = mv3310_aneg_done, 705 .read_status = mv3310_read_status, |
706 .get_tunable = mv3310_get_tunable, 707 .set_tunable = mv3310_set_tunable, |
|
624 }, 625}; 626 627module_phy_driver(mv3310_drivers); 628 629static struct mdio_device_id __maybe_unused mv3310_tbl[] = { 630 { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK }, 631 { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK }, 632 { }, 633}; 634MODULE_DEVICE_TABLE(mdio, mv3310_tbl); 635MODULE_DESCRIPTION("Marvell Alaska X 10Gigabit Ethernet PHY driver (MV88X3310)"); 636MODULE_LICENSE("GPL"); | 708 }, 709}; 710 711module_phy_driver(mv3310_drivers); 712 713static struct mdio_device_id __maybe_unused mv3310_tbl[] = { 714 { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK }, 715 { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK }, 716 { }, 717}; 718MODULE_DEVICE_TABLE(mdio, mv3310_tbl); 719MODULE_DESCRIPTION("Marvell Alaska X 10Gigabit Ethernet PHY driver (MV88X3310)"); 720MODULE_LICENSE("GPL"); |