Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: phy: mscc: report and configure in-band auto-negotiation for SGMII/QSGMII

The following Vitesse/Microsemi/Microchip PHYs, among those supported by
this driver, have the host interface configurable as SGMII or QSGMII:
- VSC8504
- VSC8514
- VSC8552
- VSC8562
- VSC8572
- VSC8574
- VSC8575
- VSC8582
- VSC8584

All these PHYs are documented to have bit 7 of "MAC SerDes PCS Control"
as "MAC SerDes ANEG enable".

Out of these, I could test the VSC8514 quad PHY in QSGMII. This works
both with the in-band autoneg on and off, on the NXP LS1028A-RDB and
T1040-RDB boards.

Notably, the bit is sticky (survives soft resets), so giving Linux the
tools to read and modify this settings makes it robust to changes made
to it by previous boot layers (U-Boot).

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://patch.msgid.link/20250813074454.63224-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Vladimir Oltean and committed by
Jakub Kicinski
df979273 20e1b75b

+43
+3
drivers/net/phy/mscc/mscc.h
··· 196 196 #define MSCC_PHY_EXTENDED_INT_MS_EGR BIT(9) 197 197 198 198 /* Extended Page 3 Registers */ 199 + #define MSCC_PHY_SERDES_PCS_CTRL 16 200 + #define MSCC_PHY_SERDES_ANEG BIT(7) 201 + 199 202 #define MSCC_PHY_SERDES_TX_VALID_CNT 21 200 203 #define MSCC_PHY_SERDES_TX_CRC_ERR_CNT 22 201 204 #define MSCC_PHY_SERDES_RX_VALID_CNT 28
+40
drivers/net/phy/mscc/mscc_main.c
··· 2202 2202 return genphy_read_status(phydev); 2203 2203 } 2204 2204 2205 + static unsigned int vsc85xx_inband_caps(struct phy_device *phydev, 2206 + phy_interface_t interface) 2207 + { 2208 + if (interface != PHY_INTERFACE_MODE_SGMII && 2209 + interface != PHY_INTERFACE_MODE_QSGMII) 2210 + return 0; 2211 + 2212 + return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; 2213 + } 2214 + 2215 + static int vsc85xx_config_inband(struct phy_device *phydev, unsigned int modes) 2216 + { 2217 + u16 reg_val = 0; 2218 + 2219 + if (modes == LINK_INBAND_ENABLE) 2220 + reg_val = MSCC_PHY_SERDES_ANEG; 2221 + 2222 + return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_3, 2223 + MSCC_PHY_SERDES_PCS_CTRL, MSCC_PHY_SERDES_ANEG, 2224 + reg_val); 2225 + } 2226 + 2205 2227 static int vsc8514_probe(struct phy_device *phydev) 2206 2228 { 2207 2229 struct vsc8531_private *vsc8531; ··· 2431 2409 .get_sset_count = &vsc85xx_get_sset_count, 2432 2410 .get_strings = &vsc85xx_get_strings, 2433 2411 .get_stats = &vsc85xx_get_stats, 2412 + .inband_caps = vsc85xx_inband_caps, 2413 + .config_inband = vsc85xx_config_inband, 2434 2414 }, 2435 2415 { 2436 2416 .phy_id = PHY_ID_VSC8514, ··· 2456 2432 .get_sset_count = &vsc85xx_get_sset_count, 2457 2433 .get_strings = &vsc85xx_get_strings, 2458 2434 .get_stats = &vsc85xx_get_stats, 2435 + .inband_caps = vsc85xx_inband_caps, 2436 + .config_inband = vsc85xx_config_inband, 2459 2437 }, 2460 2438 { 2461 2439 .phy_id = PHY_ID_VSC8530, ··· 2578 2552 .get_sset_count = &vsc85xx_get_sset_count, 2579 2553 .get_strings = &vsc85xx_get_strings, 2580 2554 .get_stats = &vsc85xx_get_stats, 2555 + .inband_caps = vsc85xx_inband_caps, 2556 + .config_inband = vsc85xx_config_inband, 2581 2557 }, 2582 2558 { 2583 2559 .phy_id = PHY_ID_VSC856X, ··· 2602 2574 .get_sset_count = &vsc85xx_get_sset_count, 2603 2575 .get_strings = &vsc85xx_get_strings, 2604 2576 .get_stats = &vsc85xx_get_stats, 2577 + .inband_caps = vsc85xx_inband_caps, 2578 + .config_inband = vsc85xx_config_inband, 2605 2579 }, 2606 2580 { 2607 2581 .phy_id = PHY_ID_VSC8572, ··· 2629 2599 .get_sset_count = &vsc85xx_get_sset_count, 2630 2600 .get_strings = &vsc85xx_get_strings, 2631 2601 .get_stats = &vsc85xx_get_stats, 2602 + .inband_caps = vsc85xx_inband_caps, 2603 + .config_inband = vsc85xx_config_inband, 2632 2604 }, 2633 2605 { 2634 2606 .phy_id = PHY_ID_VSC8574, ··· 2656 2624 .get_sset_count = &vsc85xx_get_sset_count, 2657 2625 .get_strings = &vsc85xx_get_strings, 2658 2626 .get_stats = &vsc85xx_get_stats, 2627 + .inband_caps = vsc85xx_inband_caps, 2628 + .config_inband = vsc85xx_config_inband, 2659 2629 }, 2660 2630 { 2661 2631 .phy_id = PHY_ID_VSC8575, ··· 2681 2647 .get_sset_count = &vsc85xx_get_sset_count, 2682 2648 .get_strings = &vsc85xx_get_strings, 2683 2649 .get_stats = &vsc85xx_get_stats, 2650 + .inband_caps = vsc85xx_inband_caps, 2651 + .config_inband = vsc85xx_config_inband, 2684 2652 }, 2685 2653 { 2686 2654 .phy_id = PHY_ID_VSC8582, ··· 2706 2670 .get_sset_count = &vsc85xx_get_sset_count, 2707 2671 .get_strings = &vsc85xx_get_strings, 2708 2672 .get_stats = &vsc85xx_get_stats, 2673 + .inband_caps = vsc85xx_inband_caps, 2674 + .config_inband = vsc85xx_config_inband, 2709 2675 }, 2710 2676 { 2711 2677 .phy_id = PHY_ID_VSC8584, ··· 2732 2694 .get_strings = &vsc85xx_get_strings, 2733 2695 .get_stats = &vsc85xx_get_stats, 2734 2696 .link_change_notify = &vsc85xx_link_change_notify, 2697 + .inband_caps = vsc85xx_inband_caps, 2698 + .config_inband = vsc85xx_config_inband, 2735 2699 } 2736 2700 2737 2701 };