| .. | .. |
|---|
| 527 | 527 | * * 2.0 ns (which causes the data to be sampled at exactly half way between |
|---|
| 528 | 528 | * clock transitions at 1000 Mbps) if delays should be enabled |
|---|
| 529 | 529 | */ |
|---|
| 530 | | -static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl, |
|---|
| 531 | | - u16 rgmii_rx_delay_mask, |
|---|
| 532 | | - u16 rgmii_tx_delay_mask) |
|---|
| 530 | +static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl, |
|---|
| 531 | + u16 rgmii_rx_delay_mask, |
|---|
| 532 | + u16 rgmii_tx_delay_mask) |
|---|
| 533 | 533 | { |
|---|
| 534 | 534 | u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1; |
|---|
| 535 | 535 | u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1; |
|---|
| 536 | 536 | u16 reg_val = 0; |
|---|
| 537 | | - int rc; |
|---|
| 537 | + u16 mask = 0; |
|---|
| 538 | + int rc = 0; |
|---|
| 539 | + |
|---|
| 540 | + /* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit |
|---|
| 541 | + * to be unset for all PHY modes, so do that as part of the paged |
|---|
| 542 | + * register modification. |
|---|
| 543 | + * For some family members (like VSC8530/31/40/41) this bit is reserved |
|---|
| 544 | + * and read-only, and the RX clock is enabled by default. |
|---|
| 545 | + */ |
|---|
| 546 | + if (rgmii_cntl == VSC8502_RGMII_CNTL) |
|---|
| 547 | + mask |= VSC8502_RGMII_RX_CLK_DISABLE; |
|---|
| 548 | + |
|---|
| 549 | + if (phy_interface_is_rgmii(phydev)) |
|---|
| 550 | + mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask; |
|---|
| 538 | 551 | |
|---|
| 539 | 552 | mutex_lock(&phydev->lock); |
|---|
| 540 | 553 | |
|---|
| .. | .. |
|---|
| 545 | 558 | phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) |
|---|
| 546 | 559 | reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos; |
|---|
| 547 | 560 | |
|---|
| 548 | | - rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2, |
|---|
| 549 | | - rgmii_cntl, |
|---|
| 550 | | - rgmii_rx_delay_mask | rgmii_tx_delay_mask, |
|---|
| 551 | | - reg_val); |
|---|
| 561 | + if (mask) |
|---|
| 562 | + rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2, |
|---|
| 563 | + rgmii_cntl, mask, reg_val); |
|---|
| 552 | 564 | |
|---|
| 553 | 565 | mutex_unlock(&phydev->lock); |
|---|
| 554 | 566 | |
|---|
| .. | .. |
|---|
| 557 | 569 | |
|---|
| 558 | 570 | static int vsc85xx_default_config(struct phy_device *phydev) |
|---|
| 559 | 571 | { |
|---|
| 560 | | - int rc; |
|---|
| 561 | | - |
|---|
| 562 | 572 | phydev->mdix_ctrl = ETH_TP_MDI_AUTO; |
|---|
| 563 | 573 | |
|---|
| 564 | | - if (phy_interface_mode_is_rgmii(phydev->interface)) { |
|---|
| 565 | | - rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL, |
|---|
| 566 | | - VSC8502_RGMII_RX_DELAY_MASK, |
|---|
| 567 | | - VSC8502_RGMII_TX_DELAY_MASK); |
|---|
| 568 | | - if (rc) |
|---|
| 569 | | - return rc; |
|---|
| 570 | | - } |
|---|
| 571 | | - |
|---|
| 572 | | - return 0; |
|---|
| 574 | + return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL, |
|---|
| 575 | + VSC8502_RGMII_RX_DELAY_MASK, |
|---|
| 576 | + VSC8502_RGMII_TX_DELAY_MASK); |
|---|
| 573 | 577 | } |
|---|
| 574 | 578 | |
|---|
| 575 | 579 | static int vsc85xx_get_tunable(struct phy_device *phydev, |
|---|
| .. | .. |
|---|
| 1646 | 1650 | if (ret) |
|---|
| 1647 | 1651 | return ret; |
|---|
| 1648 | 1652 | |
|---|
| 1649 | | - if (phy_interface_is_rgmii(phydev)) { |
|---|
| 1650 | | - ret = vsc85xx_rgmii_set_skews(phydev, VSC8572_RGMII_CNTL, |
|---|
| 1651 | | - VSC8572_RGMII_RX_DELAY_MASK, |
|---|
| 1652 | | - VSC8572_RGMII_TX_DELAY_MASK); |
|---|
| 1653 | | - if (ret) |
|---|
| 1654 | | - return ret; |
|---|
| 1655 | | - } |
|---|
| 1653 | + ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL, |
|---|
| 1654 | + VSC8572_RGMII_RX_DELAY_MASK, |
|---|
| 1655 | + VSC8572_RGMII_TX_DELAY_MASK); |
|---|
| 1656 | + if (ret) |
|---|
| 1657 | + return ret; |
|---|
| 1656 | 1658 | |
|---|
| 1657 | 1659 | ret = genphy_soft_reset(phydev); |
|---|
| 1658 | 1660 | if (ret) |
|---|
| .. | .. |
|---|
| 2563 | 2565 | module_phy_driver(vsc85xx_driver); |
|---|
| 2564 | 2566 | |
|---|
| 2565 | 2567 | static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = { |
|---|
| 2568 | + { PHY_ID_VSC8502, 0xfffffff0, }, |
|---|
| 2566 | 2569 | { PHY_ID_VSC8504, 0xfffffff0, }, |
|---|
| 2567 | 2570 | { PHY_ID_VSC8514, 0xfffffff0, }, |
|---|
| 2568 | 2571 | { PHY_ID_VSC8530, 0xfffffff0, }, |
|---|