Re: [PATCH net-next v5 1/2] net: macb: Poll for link state changes when using the internal PCS.

Nathan Whitehorn <[email protected]>
Newsgroups org.kernel.vger.netdev
Message-ID <[email protected]>

On 8/18/26 09:14, Paolo Abeni wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> Full review at: https://urldefense.com/v3/__https://netdev-ai.bots.linux.dev/sashiko/__;!!HXCxUKc!1c62Nd-KqBSJoooZYqRXvyr1xBH2SrYG0Qj-vjwRbTXeO230CuhteNJg0IKZip8kZa8eox-PjTqUg6Jbyg$
> ---
> net: macb: Poll for link state changes when using the internal PCS.
>
> This sets poll = true on the macb internal SGMII phylink PCS so phylink
> arms its periodic link poll timer, letting link state changes be observed
> at the PCS instead of at an onboard PHY (for example with an SFP).
>
>> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
>> index d394f1f43b685..c15a9c7e69d37 100644
>> --- a/drivers/net/ethernet/cadence/macb_main.c
>> +++ b/drivers/net/ethernet/cadence/macb_main.c
>> @@ -1025,6 +1025,7 @@ static int macb_mii_probe(struct net_device *dev)
>>   	struct macb *bp = netdev_priv(dev);
>>   
>>   	bp->phylink_sgmii_pcs.ops = &macb_phylink_pcs_ops;
>> +	bp->phylink_sgmii_pcs.poll = true;
>>   	bp->phylink_usx_pcs.ops = &macb_phylink_usx_pcs_ops;
> [Severity: Low]
> This isn't a bug introduced by this patch, but should phylink_usx_pcs also
> get poll = true?  The commit message speaks generally about "an offboard
> transceiver (e.g. an SFP)" and about polling "when the PCS is active", yet
> only the SGMII PCS is updated.
>
> macb_mac_select_pcs() returns &bp->phylink_usx_pcs for
> PHY_INTERFACE_MODE_10GBASER, and phylink only arms the timer for the
> currently selected PCS:
>
> drivers/net/phy/phylink.c:phylink_pcs_poll_start() {
> 	if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
> 		mod_timer(&pl->link_poll, jiffies + HZ);
> }
>
> PHY_INTERFACE_MODE_10GBASER is one of the modes accepted as in-band by
> phylink_parse_mode(), so with managed = "in-band-status" the USX PCS ends up
> in MLO_AN_INBAND but with poll == false.
>
> macb_usx_pcs_get_state() is a pure register read:
>
> 	val = gem_readl(bp, USX_STATUS);
> 	state->link = !!(val & GEM_BIT(USX_BLOCK_LOCK));
>
> and macb has no phylink_pcs_change()/phylink_mac_change() call anywhere, and
> poll_fixed_state/get_fixed_state are only installed for SGMII.  Does that
> mean USX_BLOCK_LOCK transitions are only sampled when something else (such
> as an SFP loss-of-signal transition) forces a resolve?
>
> The USX PCS behaves exactly as it did before this patch, so this is a
> pre-existing gap rather than a new failure.  Could the commit message say
> whether leaving the USX PCS unpolled is deliberate?

Very happy to update the commit message here. I don't have the 10G 
version of this hardware and had avoided touching it. Longer-term, as I 
mentioned in the cover letter, I think we want to set up an interrupt 
handler for the link-state change notifications from the PCS, which 
would remove this, remove the similar polling on fixed links, and 
obviate the need for similar behavior in the 10G PCS case.

> [Severity: Medium]
> This is a pre-existing issue, but arming the poll timer adds one more
> asynchronous context that touches the hardware, and macb_suspend() does not
> stop phylink on the Wake-on-LAN path:
>
> drivers/net/ethernet/cadence/macb_main.c:macb_suspend() {
> 	if (!(bp->wol & MACB_WOL_ENABLED)) {
> 		rtnl_lock();
> 		phylink_stop(bp->phylink);
> 		rtnl_unlock();
> 	...
> }
>
> phylink_suspend() is never called either, so with WoL enabled
> pl->phylink_disable_state stays 0 and phylink_resolve() keeps running (clocks
> stay on because macb_suspend() skips pm_runtime_force_suspend() when
> device_may_wakeup() is true).
>
> If the PCS link state changes after the WoL arming sequence, can the resolve
> undo it?  macb_mac_link_down() clears the receive engine that magic-packet
> and ARP wake detection rely on:
>
> 	ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | MACB_BIT(TE));
> 	macb_writel(bp, NCR, ctrl);
>
> and macb_mac_link_up() goes the other way, re-unmasking every queue while
> NAPI is disabled and re-enabling RE|TE:
>
> 	queue_writel(queue, IER,
> 		     bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP));
> 	...
> 	macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));
>
> phylink_resolve() does not consult netif_device_present(), so nothing appears
> to gate this against the suspended state.
>
> The same 1 Hz poll already existed in the baseline for MLO_AN_FIXED SGMII:
>
> 	if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
> 		bp->phylink_config.poll_fixed_state = true;
> 		bp->phylink_config.get_fixed_state = macb_get_pcs_fixed_state;
>
> and phylink_phy_change()/phylink_sfp_link_down() can already drive a resolve
> during a WoL-armed suspend, so this patch only adds another trigger for the
> in-band SGMII case.  Would calling phylink_suspend() (or phylink_stop()) on
> the WoL path in macb_suspend() be the right fix?

I think probably, but I don't know enough here to be certain. As you 
note, this slightly expands the scope of the pre-existing fixed-link 
case, but I don't know enough about the pieces here to be sure of how 
best to resolve this or the rationale for the current fixed-link polling.
-Nathan

-- 
Nathan Whitehorn (he/him)
Associate Professor
Department of Physics and Astronomy
Michigan State University
Biomedical and Physical Sciences 3225
East Lansing, MI 48824
(517) 884-5563
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.