[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <b1888530-1bf8-4ced-948d-d3989f9896b6@lunn.ch>
Date: Thu, 21 Nov 2024 15:25:32 +0100
From: Andrew Lunn <andrew@...n.ch>
To: Krzysztof Hałasa <khalasa@...p.pl>
Cc: netdev <netdev@...r.kernel.org>, Oliver Neukum <oneukum@...e.com>,
Andrew Lunn <andrew+netdev@...n.ch>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>,
linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org,
Jose Ignacio Tornos Martinez <jtornosm@...hat.com>,
Ming Lei <ming.lei@...hat.com>
Subject: Re: [PATCH] usbnet_link_change() fails to call netif_carrier_on()
On Thu, Nov 21, 2024 at 07:51:24AM +0100, Krzysztof Hałasa wrote:
> Hi Andrew,
> thanks for a looking at this.
>
> Andrew Lunn <andrew@...n.ch> writes:
>
> >> void usbnet_link_change(struct usbnet *dev, bool link, bool need_reset)
> >> {
> >> /* update link after link is reseted */
> >> if (link && !need_reset)
> >> netif_carrier_on(dev->net);
> >> else
> >> netif_carrier_off(dev->net);
> >>
> >> if (need_reset && link)
> >> usbnet_defer_kevent(dev, EVENT_LINK_RESET);
> >> else
> >> usbnet_defer_kevent(dev, EVENT_LINK_CHANGE);
> >> }
> >
> > This device is using phylink to manage the PHY. phylink will than
> > manage the carrier. It assumes it is solely responsible for the
> > carrier. So i think your fix is wrong. You probably should be removing
> > all code in this driver which touches the carrier.
>
> Ok, I wasn't aware that phylink manages netdev's carrier state.
>
> Then, is the patch wrong just because the asix driver shouldn't use the
> function, or is it wrong because the function should work differently
> (i.e., the semantics are different)?
>
> Surely the function is broken, isn't it? Calling netif_carrier_off()
> on link up event can't be right?
>
>
> Now the ASIX driver, I'm looking at it for some time now. It consists
> of two parts linked together. The ax88172a.c part doesn't use phylink,
> while the main asix_devices.c does. So I'm leaving ax88172a.c alone for
> now (while it could probably be better ported to the same framework,
> i.e., phylink).
>
> The main part uses usbnet.c, which does netif_carrier_{on,off}() in the
> above usbnet_link_change(). I guess I can make it use directly
> usbnet_defer_kevent() only so it won't be a problem.
>
> Also, usbnet.c calls usbnet_defer_kevent() and thus netif_carrier_off()
> in usbnet_probe, removing FLAG_LINK_INTR from asix_devices.c will stop
> that.
>
> The last place interacting with carrier status is asix_status(), called
> about 8 times a second by usbnet.c intr_complete(). This is independent
> of any MDIO traffic. Should I now remove this as well? I guess removing
> asix_status would suffice.
I've not looked at this driver in detail, nor usbnet. So i can only
make general comments. I do see there are a number of drivers which
re-invent the wheel and do their own PHY handling, when they should
allow Linux to do it via phylib/phylink.
When the MAC driver is using phylink, or phylib, it should not touch
the carrier, nor access the PHY directly. The exception can be during
probe, when it can turn the carrier off. What the MAC driver should be
doing is exposing its MDIO bus as a Linux MDIO bus. phylib will then
enumerate the bus and find the PHYs on it. The MAC driver which does
not have access to device tree then typically uses phy_find_first() to
find a PHY on the bus, and uses phy_connect() to bind the PHY to the
MAC. The MAC driver then uses phy_start() when the interface is
opened. phylib will poll the PHY for changing in link status, and call
the callback function registered via phy_connect() to let the MAC know
about what the PHY has negotiated. Other than that, the MAC driver
does nothing with the PHY.
It could well be there are historical discrepancies in usbnet, in that
having Linux drive the PHY is somewhat new for usbnet, historically
the wheel was reinvented, and maybe part of that is in the usbnet
core.
Andrew
Powered by blists - more mailing lists