summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-02-26 19:19:27 -0800
committerJakub Kicinski <kuba@kernel.org>2026-02-26 19:19:28 -0800
commited02c6b8b570d49e9766d60b1d9b48ea5e2cfaed (patch)
tree4c19a79cdf47f1bae087b73edcb7824a9993da84
parent363c5108e4e2b3b5f99243e61d524dd9c23d8c1b (diff)
parentd3549e2b48187dc042c0b37bac387948146a023b (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.c50
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);
}