Skip to content

Commit ab2bf93

Browse files
QSchulzdavem330
authored andcommitted
net: phy: mscc: 1588 block initialization
This patch adds the first parts of the 1588 support in the MSCC PHY, with registers definition and the 1588 block initialization. Those PHYs are distributed in hardware packages containing multiple times the PHY. The VSC8584 for example is composed of 4 PHYs. With hardware packages, parts of the logic is usually common and one of the PHY has to be used for some parts of the initialization. Following this logic, the 1588 blocks of those PHYs are shared between two PHYs and accessing the registers has to be done using the "base" PHY of the group. This is handled thanks to helpers in the PTP code (and locks). We also need the MDIO bus lock while performing a single read or write to the 1588 registers as the read/write are composed of multiple MDIO transactions (and we don't want other threads updating the page). Co-developed-by: Antoine Tenart <[email protected]> Signed-off-by: Quentin Schulz <[email protected]> Signed-off-by: Antoine Tenart <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4c8c5dc commit ab2bf93

File tree

5 files changed

+1552
-2
lines changed

5 files changed

+1552
-2
lines changed

drivers/net/phy/mscc/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ mscc-objs := mscc_main.o
88
ifdef CONFIG_MACSEC
99
mscc-objs += mscc_macsec.o
1010
endif
11+
12+
ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
13+
mscc-objs += mscc_ptp.o
14+
endif

drivers/net/phy/mscc/mscc.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ enum rgmii_clock_delay {
133133
* in the same package.
134134
*/
135135
#define MSCC_PHY_PAGE_EXTENDED_GPIO 0x0010 /* Extended reg - GPIO */
136+
#define MSCC_PHY_PAGE_1588 0x1588 /* PTP (1588) */
136137
#define MSCC_PHY_PAGE_TEST 0x2a30 /* Test reg */
137138
#define MSCC_PHY_PAGE_TR 0x52b5 /* Token ring registers */
138139

@@ -373,6 +374,20 @@ struct vsc8531_private {
373374
unsigned long ingr_flows;
374375
unsigned long egr_flows;
375376
#endif
377+
378+
bool input_clk_init;
379+
struct vsc85xx_ptp *ptp;
380+
381+
/* For multiple port PHYs; the MDIO address of the base PHY in the
382+
* pair of two PHYs that share a 1588 engine. PHY0 and PHY2 are coupled.
383+
* PHY1 and PHY3 as well. PHY0 and PHY1 are base PHYs for their
384+
* respective pair.
385+
*/
386+
unsigned int ts_base_addr;
387+
u8 ts_base_phy;
388+
389+
/* ts_lock: used for per-PHY timestamping operations. */
390+
struct mutex ts_lock;
376391
};
377392

378393
#if IS_ENABLED(CONFIG_OF_MDIO)
@@ -399,4 +414,22 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
399414
}
400415
#endif
401416

417+
#if IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING)
418+
void vsc85xx_link_change_notify(struct phy_device *phydev);
419+
int vsc8584_ptp_init(struct phy_device *phydev);
420+
int vsc8584_ptp_probe(struct phy_device *phydev);
421+
#else
422+
static inline void vsc85xx_link_change_notify(struct phy_device *phydev)
423+
{
424+
}
425+
static inline int vsc8584_ptp_init(struct phy_device *phydev)
426+
{
427+
return 0;
428+
}
429+
static inline int vsc8584_ptp_probe(struct phy_device *phydev)
430+
{
431+
return 0;
432+
}
433+
#endif
434+
402435
#endif /* _MSCC_PHY_H_ */

drivers/net/phy/mscc/mscc_main.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,10 +1299,26 @@ static void vsc8584_get_base_addr(struct phy_device *phydev)
12991299
__phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
13001300
mutex_unlock(&phydev->mdio.bus->mdio_lock);
13011301

1302-
if (val & PHY_ADDR_REVERSED)
1302+
/* In the package, there are two pairs of PHYs (PHY0 + PHY2 and
1303+
* PHY1 + PHY3). The first PHY of each pair (PHY0 and PHY1) is
1304+
* the base PHY for timestamping operations.
1305+
*/
1306+
vsc8531->ts_base_addr = phydev->mdio.addr;
1307+
vsc8531->ts_base_phy = addr;
1308+
1309+
if (val & PHY_ADDR_REVERSED) {
13031310
vsc8531->base_addr = phydev->mdio.addr + addr;
1304-
else
1311+
if (addr > 1) {
1312+
vsc8531->ts_base_addr += 2;
1313+
vsc8531->ts_base_phy += 2;
1314+
}
1315+
} else {
13051316
vsc8531->base_addr = phydev->mdio.addr - addr;
1317+
if (addr > 1) {
1318+
vsc8531->ts_base_addr -= 2;
1319+
vsc8531->ts_base_phy -= 2;
1320+
}
1321+
}
13061322

13071323
vsc8531->addr = addr;
13081324
}
@@ -1418,6 +1434,10 @@ static int vsc8584_config_init(struct phy_device *phydev)
14181434
if (ret)
14191435
return ret;
14201436

1437+
ret = vsc8584_ptp_init(phydev);
1438+
if (ret)
1439+
goto err;
1440+
14211441
phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
14221442

14231443
val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
@@ -1999,6 +2019,7 @@ static int vsc8584_probe(struct phy_device *phydev)
19992019
u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
20002020
VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
20012021
VSC8531_DUPLEX_COLLISION};
2022+
int ret;
20022023

20032024
if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
20042025
dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
@@ -2024,6 +2045,10 @@ static int vsc8584_probe(struct phy_device *phydev)
20242045
if (!vsc8531->stats)
20252046
return -ENOMEM;
20262047

2048+
ret = vsc8584_ptp_probe(phydev);
2049+
if (ret)
2050+
return ret;
2051+
20272052
return vsc85xx_dt_led_modes_get(phydev, default_mode);
20282053
}
20292054

@@ -2403,6 +2428,7 @@ static struct phy_driver vsc85xx_driver[] = {
24032428
.get_sset_count = &vsc85xx_get_sset_count,
24042429
.get_strings = &vsc85xx_get_strings,
24052430
.get_stats = &vsc85xx_get_stats,
2431+
.link_change_notify = &vsc85xx_link_change_notify,
24062432
}
24072433

24082434
};

0 commit comments

Comments
 (0)