Skip to content

Commit aa015a2

Browse files
committed
Merge branch 'net-phy-mscc-support-vsc8501'
David Epping says: ==================== net: phy: mscc: support VSC8501 this updated series of patches adds support for the VSC8501 Ethernet PHY and fixes support for the VSC8502 PHY in cases where no other software (like U-Boot) has initialized the PHY after power up. The first patch simply adds the VSC8502 to the MODULE_DEVICE_TABLE, where I guess it was unintentionally missing. I have no hardware to test my change. The second patch adds the VSC8501 PHY with exactly the same driver implementation as the existing VSC8502. The (new) third patch removes phydev locking from vsc85xx_rgmii_set_skews(), as discussed for v2 of the patch set. The (now) fourth patch fixes the initialization for VSC8501 and VSC8502. I have tested this patch with VSC8501 on hardware in RGMII mode only. https://ww1.microchip.com/downloads/aemDocuments/documents/UNG/ProductDocuments/DataSheets/VSC8501-03_Datasheet_60001741A.PDF https://ww1.microchip.com/downloads/aemDocuments/documents/UNG/ProductDocuments/DataSheets/VSC8502-03_Datasheet_60001742B.pdf Table 4-42 "RGMII CONTROL, ADDRESS 20E2 (0X14)" Bit 11 for each of them. By default the RX_CLK is disabled for these PHYs. In cases where no other software, like U-Boot, enabled the clock, this results in no received packets being handed to the MAC. The patch enables this clock output. According to Microchip support (case number 01268776) this applies to all modes (RGMII, GMII, and MII). Other PHYs sharing the same register map and code, like VSC8530/31/40/41 have the clock enabled and the relevant bit 11 is reserved and read-only for them. As per previous discussion the patch still clears the bit on these PHYs, too, possibly more easily supporting other future PHYs implementing this functionality. For the VSC8572 family of PHYs, having a different register map, no such changes are applied. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 1de5900 + 71460c9 commit aa015a2

File tree

2 files changed

+55
-29
lines changed

2 files changed

+55
-29
lines changed

drivers/net/phy/mscc/mscc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ enum rgmii_clock_delay {
179179
#define VSC8502_RGMII_CNTL 20
180180
#define VSC8502_RGMII_RX_DELAY_MASK 0x0070
181181
#define VSC8502_RGMII_TX_DELAY_MASK 0x0007
182+
#define VSC8502_RGMII_RX_CLK_DISABLE 0x0800
182183

183184
#define MSCC_PHY_WOL_LOWER_MAC_ADDR 21
184185
#define MSCC_PHY_WOL_MID_MAC_ADDR 22
@@ -276,6 +277,7 @@ enum rgmii_clock_delay {
276277
/* Microsemi PHY ID's
277278
* Code assumes lowest nibble is 0
278279
*/
280+
#define PHY_ID_VSC8501 0x00070530
279281
#define PHY_ID_VSC8502 0x00070630
280282
#define PHY_ID_VSC8504 0x000704c0
281283
#define PHY_ID_VSC8514 0x00070670

drivers/net/phy/mscc/mscc_main.c

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -519,16 +519,27 @@ static int vsc85xx_mac_if_set(struct phy_device *phydev,
519519
* * 2.0 ns (which causes the data to be sampled at exactly half way between
520520
* clock transitions at 1000 Mbps) if delays should be enabled
521521
*/
522-
static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
523-
u16 rgmii_rx_delay_mask,
524-
u16 rgmii_tx_delay_mask)
522+
static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl,
523+
u16 rgmii_rx_delay_mask,
524+
u16 rgmii_tx_delay_mask)
525525
{
526526
u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
527527
u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
528528
u16 reg_val = 0;
529-
int rc;
529+
u16 mask = 0;
530+
int rc = 0;
530531

531-
mutex_lock(&phydev->lock);
532+
/* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit
533+
* to be unset for all PHY modes, so do that as part of the paged
534+
* register modification.
535+
* For some family members (like VSC8530/31/40/41) this bit is reserved
536+
* and read-only, and the RX clock is enabled by default.
537+
*/
538+
if (rgmii_cntl == VSC8502_RGMII_CNTL)
539+
mask |= VSC8502_RGMII_RX_CLK_DISABLE;
540+
541+
if (phy_interface_is_rgmii(phydev))
542+
mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask;
532543

533544
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
534545
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
@@ -537,31 +548,20 @@ static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
537548
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
538549
reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos;
539550

540-
rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
541-
rgmii_cntl,
542-
rgmii_rx_delay_mask | rgmii_tx_delay_mask,
543-
reg_val);
544-
545-
mutex_unlock(&phydev->lock);
551+
if (mask)
552+
rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
553+
rgmii_cntl, mask, reg_val);
546554

547555
return rc;
548556
}
549557

550558
static int vsc85xx_default_config(struct phy_device *phydev)
551559
{
552-
int rc;
553-
554560
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
555561

556-
if (phy_interface_mode_is_rgmii(phydev->interface)) {
557-
rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL,
558-
VSC8502_RGMII_RX_DELAY_MASK,
559-
VSC8502_RGMII_TX_DELAY_MASK);
560-
if (rc)
561-
return rc;
562-
}
563-
564-
return 0;
562+
return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL,
563+
VSC8502_RGMII_RX_DELAY_MASK,
564+
VSC8502_RGMII_TX_DELAY_MASK);
565565
}
566566

567567
static int vsc85xx_get_tunable(struct phy_device *phydev,
@@ -1758,13 +1758,11 @@ static int vsc8584_config_init(struct phy_device *phydev)
17581758
if (ret)
17591759
return ret;
17601760

1761-
if (phy_interface_is_rgmii(phydev)) {
1762-
ret = vsc85xx_rgmii_set_skews(phydev, VSC8572_RGMII_CNTL,
1763-
VSC8572_RGMII_RX_DELAY_MASK,
1764-
VSC8572_RGMII_TX_DELAY_MASK);
1765-
if (ret)
1766-
return ret;
1767-
}
1761+
ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL,
1762+
VSC8572_RGMII_RX_DELAY_MASK,
1763+
VSC8572_RGMII_TX_DELAY_MASK);
1764+
if (ret)
1765+
return ret;
17681766

17691767
ret = genphy_soft_reset(phydev);
17701768
if (ret)
@@ -2316,6 +2314,30 @@ static int vsc85xx_probe(struct phy_device *phydev)
23162314

23172315
/* Microsemi VSC85xx PHYs */
23182316
static struct phy_driver vsc85xx_driver[] = {
2317+
{
2318+
.phy_id = PHY_ID_VSC8501,
2319+
.name = "Microsemi GE VSC8501 SyncE",
2320+
.phy_id_mask = 0xfffffff0,
2321+
/* PHY_BASIC_FEATURES */
2322+
.soft_reset = &genphy_soft_reset,
2323+
.config_init = &vsc85xx_config_init,
2324+
.config_aneg = &vsc85xx_config_aneg,
2325+
.read_status = &vsc85xx_read_status,
2326+
.handle_interrupt = vsc85xx_handle_interrupt,
2327+
.config_intr = &vsc85xx_config_intr,
2328+
.suspend = &genphy_suspend,
2329+
.resume = &genphy_resume,
2330+
.probe = &vsc85xx_probe,
2331+
.set_wol = &vsc85xx_wol_set,
2332+
.get_wol = &vsc85xx_wol_get,
2333+
.get_tunable = &vsc85xx_get_tunable,
2334+
.set_tunable = &vsc85xx_set_tunable,
2335+
.read_page = &vsc85xx_phy_read_page,
2336+
.write_page = &vsc85xx_phy_write_page,
2337+
.get_sset_count = &vsc85xx_get_sset_count,
2338+
.get_strings = &vsc85xx_get_strings,
2339+
.get_stats = &vsc85xx_get_stats,
2340+
},
23192341
{
23202342
.phy_id = PHY_ID_VSC8502,
23212343
.name = "Microsemi GE VSC8502 SyncE",
@@ -2656,6 +2678,8 @@ static struct phy_driver vsc85xx_driver[] = {
26562678
module_phy_driver(vsc85xx_driver);
26572679

26582680
static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
2681+
{ PHY_ID_VSC8501, 0xfffffff0, },
2682+
{ PHY_ID_VSC8502, 0xfffffff0, },
26592683
{ PHY_ID_VSC8504, 0xfffffff0, },
26602684
{ PHY_ID_VSC8514, 0xfffffff0, },
26612685
{ PHY_ID_VSC8530, 0xfffffff0, },

0 commit comments

Comments
 (0)