diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2026-02-26 19:19:27 -0800 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-02-26 19:19:28 -0800 |
| commit | ed02c6b8b570d49e9766d60b1d9b48ea5e2cfaed (patch) | |
| tree | 4c19a79cdf47f1bae087b73edcb7824a9993da84 | |
| parent | 363c5108e4e2b3b5f99243e61d524dd9c23d8c1b (diff) | |
| parent | d3549e2b48187dc042c0b37bac387948146a023b (diff) | |
Merge branch 'support-phys-that-have-inband-autoneg-disabled-with-gem'
Charles Perry says:
====================
Support PHYs that have inband autoneg disabled with GEM
I'm testing SGMII with a VSC8574 PHY [1] and microchip HPSC SoC [2].
The link can work with or without autoneg, as long as the MAC and the PHY
are configured the same way. This doesn't work with the current MAC driver
because the MAC inband autoneg is always enabled (in the ->mac_config()
phylink_mac_ops). More precisely, the PHY driver (mscc_main.c) has
phylink's ->config_inband() implemented while the MAC ->pcs_config() ops
has an empty body.
This is based on code written by Sean Anderson [3]. Let me know if I
should add a From: or Co-developed-by: tag.
Logs with inband autoneg (managed = "in-band-status"):
root@p64h:~# ifconfig eth1 up 10.180.59.33
macb 40004184000.ethernet eth1: PHY 4000c21e000.mdio-mdio:02 doesn't supply possible interfaces
macb 40004184000.ethernet eth1: PHY [4000c21e000.mdio-mdio:02] driver [Microsemi GE VSC8574 SyncE] (irq=POLL)
macb 40004184000.ethernet eth1: phy: sgmii setting supported 00000000,00000000,00000000,000042ff advertising 00000000,00000000,00000000,000042ff
macb 40004184000.ethernet eth1: configuring for inband/sgmii link mode
macb 40004184000.ethernet eth1: major config, requested inband/sgmii
macb 40004184000.ethernet eth1: interface sgmii inband modes: pcs=03 phy=03
macb 40004184000.ethernet eth1: major config, active inband/inband,an-enabled/sgmii
macb 40004184000.ethernet eth1: phylink_mac_config: mode=inband/sgmii/none adv=00000000,00000000,00000000,000042ff pause=00
macb_pcs_config: PCSANADV=0x1 PCSCNTRL=0x1040
macb_pcs_get_state: PCSSTS=0x109 PCSANLPBASE=0x1
macb_pcs_get_state: PCSSTS=0x12d PCSANLPBASE=0x1801
macb 40004184000.ethernet eth1: phy link down sgmii/Unknown/Unknown/none/off/nolpi
macb_pcs_get_state: PCSSTS=0x12d PCSANLPBASE=0x1801
macb_pcs_get_state: PCSSTS=0x12d PCSANLPBASE=0x1801
macb 40004184000.ethernet eth1: phy link up sgmii/1Gbps/Full/none/tx/nolpi
macb_pcs_get_state: PCSSTS=0x129 PCSANLPBASE=0x9801
macb_pcs_get_state: PCSSTS=0x12d PCSANLPBASE=0x9801
macb 40004184000.ethernet eth1: Link is Up - 1Gbps/Full - flow control tx
Logs without inband autoneg:
root@p64h:~# ifconfig eth1 up 10.180.59.33
macb 40004184000.ethernet eth1: PHY 4000c21e000.mdio-mdio:02 doesn't supply possible interfaces
macb 40004184000.ethernet eth1: PHY [4000c21e000.mdio-mdio:02] driver [Microsemi GE VSC8574 SyncE] (irq=POLL)
macb 40004184000.ethernet eth1: phy: sgmii setting supported 00000000,00000000,00000000,000042ff advertising 00000000,00000000,00000000,000042ff
macb 40004184000.ethernet eth1: configuring for phy/sgmii link mode
macb 40004184000.ethernet eth1: major config, requested phy/sgmii
macb 40004184000.ethernet eth1: interface sgmii inband modes: pcs=03 phy=03
macb 40004184000.ethernet eth1: major config, active phy/outband/sgmii
macb 40004184000.ethernet eth1: phylink_mac_config: mode=phy/sgmii/none adv=00000000,00000000,00000000,00000000 pause=00
macb_pcs_config: PCSANADV=0x1 PCSCNTRL=0x40
macb 40004184000.ethernet eth1: phy link down sgmii/Unknown/Unknown/none/off/nolpi
macb 40004184000.ethernet eth1: phy link up sgmii/1Gbps/Full/none/tx/nolpi
macb 40004184000.ethernet eth1: Link is Up - 1Gbps/Full - flow control tx
The above logs are generated with an additional printk() in macb_psc_config()
and macb_pcs_get_state() and "#define DEBUG" in phylink.c.
[1]: https://www.microchip.com/en-us/product/vsc8574
[2]: https://www.microchip.com/en-us/products/microprocessors/64-bit-mpus/pic64-hpsc
[3]: https://lore.kernel.org/all/20250610233547.3588356-1-sean.anderson@linux.dev/
====================
Link: https://patch.msgid.link/20260224202854.112813-1-charles.perry@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/ethernet/cadence/macb_main.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 3709b2224879..02eab26fd98b 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -557,10 +557,21 @@ static int macb_usx_pcs_config(struct phylink_pcs *pcs, return 0; } +static unsigned int macb_pcs_inband_caps(struct phylink_pcs *pcs, + phy_interface_t interface) +{ + return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; +} + static void macb_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode, struct phylink_link_state *state) { - state->link = 0; + struct macb *bp = container_of(pcs, struct macb, phylink_sgmii_pcs); + u16 bmsr, lpa; + + bmsr = gem_readl(bp, PCSSTS); + lpa = gem_readl(bp, PCSANLPBASE); + phylink_mii_c22_pcs_decode_state(state, neg_mode, bmsr, lpa); } static void macb_pcs_an_restart(struct phylink_pcs *pcs) @@ -574,6 +585,26 @@ static int macb_pcs_config(struct phylink_pcs *pcs, const unsigned long *advertising, bool permit_pause_to_mac) { + struct macb *bp = container_of(pcs, struct macb, phylink_sgmii_pcs); + u32 old, new; + + old = gem_readl(bp, PCSANADV); + new = phylink_mii_c22_pcs_encode_advertisement(interface, advertising); + if (new != -EINVAL && old != new) + gem_writel(bp, PCSANADV, new); + + /* Disable AN if it's not to be used, enable otherwise. + * Must be written after PCSSEL is set in NCFGR which is done in + * macb_mac_config(), otherwise writes will not take effect. + */ + old = gem_readl(bp, PCSCNTRL); + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) + new = old | BMCR_ANENABLE; + else + new = old & ~BMCR_ANENABLE; + if (old != new) + gem_writel(bp, PCSCNTRL, new); + return 0; } @@ -584,6 +615,7 @@ static const struct phylink_pcs_ops macb_phylink_usx_pcs_ops = { }; static const struct phylink_pcs_ops macb_phylink_pcs_ops = { + .pcs_inband_caps = macb_pcs_inband_caps, .pcs_get_state = macb_pcs_get_state, .pcs_an_restart = macb_pcs_an_restart, .pcs_config = macb_pcs_config, @@ -628,22 +660,6 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode, if (old_ncr ^ ncr) macb_or_gem_writel(bp, NCR, ncr); - /* Disable AN for SGMII fixed link configuration, enable otherwise. - * Must be written after PCSSEL is set in NCFGR, - * otherwise writes will not take effect. - */ - if (macb_is_gem(bp) && state->interface == PHY_INTERFACE_MODE_SGMII) { - u32 pcsctrl, old_pcsctrl; - - old_pcsctrl = gem_readl(bp, PCSCNTRL); - if (mode == MLO_AN_FIXED) - pcsctrl = old_pcsctrl & ~GEM_BIT(PCSAUTONEG); - else - pcsctrl = old_pcsctrl | GEM_BIT(PCSAUTONEG); - if (old_pcsctrl != pcsctrl) - gem_writel(bp, PCSCNTRL, pcsctrl); - } - spin_unlock_irqrestore(&bp->lock, flags); } |
