<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/drivers/net/phy/phy.c, branch v6.18.21</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v6.18.21</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v6.18.21'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2025-09-18T22:43:26+00:00</updated>
<entry>
<title>net: phy: clear link parameters on admin link down</title>
<updated>2025-09-18T22:43:26+00:00</updated>
<author>
<name>Oleksij Rempel</name>
<email>o.rempel@pengutronix.de</email>
</author>
<published>2025-09-17T09:47:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=60f887b1290b43a4f5a3497982a725687b193fa4'/>
<id>urn:sha1:60f887b1290b43a4f5a3497982a725687b193fa4</id>
<content type='text'>
When a PHY is halted (e.g. `ip link set dev lan2 down`), several
fields in struct phy_device may still reflect the last active
connection. This leads to ethtool showing stale values even though
the link is down.

Reset selected fields in _phy_state_machine() when transitioning
to PHY_HALTED and the link was previously up:

- speed/duplex -&gt; UNKNOWN, but only in autoneg mode (in forced mode
  these fields carry configuration, not status)
- master_slave_state -&gt; UNKNOWN if previously supported
- mdix -&gt; INVALID (state only, same meaning as "unknown")
- lp_advertising -&gt; always cleared

The cleanup is skipped if the PHY is in PHY_ERROR state, so the
last values remain available for diagnostics.

Signed-off-by: Oleksij Rempel &lt;o.rempel@pengutronix.de&gt;
Reviewed-by: Andrew Lunn &lt;andrew@lunn.ch&gt;
Link: https://patch.msgid.link/20250917094751.2101285-1-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>net: phy: clear EEE runtime state in PHY_HALTED/PHY_ERROR</title>
<updated>2025-09-15T23:16:03+00:00</updated>
<author>
<name>Oleksij Rempel</name>
<email>o.rempel@pengutronix.de</email>
</author>
<published>2025-09-12T13:20:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=0915cb22452723407ca9606b7e5cc3fe6ce767d5'/>
<id>urn:sha1:0915cb22452723407ca9606b7e5cc3fe6ce767d5</id>
<content type='text'>
Clear EEE runtime flags when the PHY transitions to HALTED or ERROR
and the state machine drops the link. This avoids stale EEE state being
reported via ethtool after the PHY is stopped or hits an error.

This change intentionally only clears software runtime flags and avoids
MDIO accesses in HALTED/ERROR. A follow-up patch will address other
link state variables.

Suggested-by: Russell King (Oracle) &lt;linux@armlinux.org.uk&gt;
Signed-off-by: Oleksij Rempel &lt;o.rempel@pengutronix.de&gt;
Reviewed-by: Andrew Lunn &lt;andrew@lunn.ch&gt;
Reviewed-by: Russell King (Oracle) &lt;rmk+kernel@armlinux.org.uk&gt;
Link: https://patch.msgid.link/20250912132000.1598234-1-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>net: phy: transfer phy_config_inband() locking responsibility to phylink</title>
<updated>2025-09-06T00:49:43+00:00</updated>
<author>
<name>Vladimir Oltean</name>
<email>vladimir.oltean@nxp.com</email>
</author>
<published>2025-09-04T12:52:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=e2a10daba84968f6b5777d150985fd7d6abc9c84'/>
<id>urn:sha1:e2a10daba84968f6b5777d150985fd7d6abc9c84</id>
<content type='text'>
Problem description
===================

Lockdep reports a possible circular locking dependency (AB/BA) between
&amp;pl-&gt;state_mutex and &amp;phy-&gt;lock, as follows.

phylink_resolve() // acquires &amp;pl-&gt;state_mutex
-&gt; phylink_major_config()
   -&gt; phy_config_inband() // acquires &amp;pl-&gt;phydev-&gt;lock

whereas all the other call sites where &amp;pl-&gt;state_mutex and
&amp;pl-&gt;phydev-&gt;lock have the locking scheme reversed. Everywhere else,
&amp;pl-&gt;phydev-&gt;lock is acquired at the top level, and &amp;pl-&gt;state_mutex at
the lower level. A clear example is phylink_bringup_phy().

The outlier is the newly introduced phy_config_inband() and the existing
lock order is the correct one. To understand why it cannot be the other
way around, it is sufficient to consider phylink_phy_change(), phylink's
callback from the PHY device's phy-&gt;phy_link_change() virtual method,
invoked by the PHY state machine.

phy_link_up() and phy_link_down(), the (indirect) callers of
phylink_phy_change(), are called with &amp;phydev-&gt;lock acquired.
Then phylink_phy_change() acquires its own &amp;pl-&gt;state_mutex, to
serialize changes made to its pl-&gt;phy_state and pl-&gt;link_config.
So all other instances of &amp;pl-&gt;state_mutex and &amp;phydev-&gt;lock must be
consistent with this order.

Problem impact
==============

I think the kernel runs a serious deadlock risk if an existing
phylink_resolve() thread, which results in a phy_config_inband() call,
is concurrent with a phy_link_up() or phy_link_down() call, which will
deadlock on &amp;pl-&gt;state_mutex in phylink_phy_change(). Practically
speaking, the impact may be limited by the slow speed of the medium
auto-negotiation protocol, which makes it unlikely for the current state
to still be unresolved when a new one is detected, but I think the
problem is there. Nonetheless, the problem was discovered using lockdep.

Proposed solution
=================

Practically speaking, the phy_config_inband() requirement of having
phydev-&gt;lock acquired must transfer to the caller (phylink is the only
caller). There, it must bubble up until immediately before
&amp;pl-&gt;state_mutex is acquired, for the cases where that takes place.

Solution details, considerations, notes
=======================================

This is the phy_config_inband() call graph:

                          sfp_upstream_ops :: connect_phy()
                          |
                          v
                          phylink_sfp_connect_phy()
                          |
                          v
                          phylink_sfp_config_phy()
                          |
                          |   sfp_upstream_ops :: module_insert()
                          |   |
                          |   v
                          |   phylink_sfp_module_insert()
                          |   |
                          |   |   sfp_upstream_ops :: module_start()
                          |   |   |
                          |   |   v
                          |   |   phylink_sfp_module_start()
                          |   |   |
                          |   v   v
                          |   phylink_sfp_config_optical()
 phylink_start()          |   |
   |   phylink_resume()   v   v
   |   |  phylink_sfp_set_config()
   |   |  |
   v   v  v
 phylink_mac_initial_config()
   |   phylink_resolve()
   |   |  phylink_ethtool_ksettings_set()
   v   v  v
   phylink_major_config()
            |
            v
    phy_config_inband()

phylink_major_config() caller #1, phylink_mac_initial_config(), does not
acquire &amp;pl-&gt;state_mutex nor do its callers. It must acquire
&amp;pl-&gt;phydev-&gt;lock prior to calling phylink_major_config().

phylink_major_config() caller #2, phylink_resolve() acquires
&amp;pl-&gt;state_mutex, thus also needs to acquire &amp;pl-&gt;phydev-&gt;lock.

phylink_major_config() caller #3, phylink_ethtool_ksettings_set(), is
completely uninteresting, because it only calls phylink_major_config()
if pl-&gt;phydev is NULL (otherwise it calls phy_ethtool_ksettings_set()).
We need to change nothing there.

Other solutions
===============

The lock inversion between &amp;pl-&gt;state_mutex and &amp;pl-&gt;phydev-&gt;lock has
occurred at least once before, as seen in commit c718af2d00a3 ("net:
phylink: fix ethtool -A with attached PHYs"). The solution there was to
simply not call phy_set_asym_pause() under the &amp;pl-&gt;state_mutex. That
cannot be extended to our case though, where the phy_config_inband()
call is much deeper inside the &amp;pl-&gt;state_mutex section.

Fixes: 5fd0f1a02e75 ("net: phylink: add negotiation of in-band capabilities")
Signed-off-by: Vladimir Oltean &lt;vladimir.oltean@nxp.com&gt;
Reviewed-by: Russell King (Oracle) &lt;rmk+kernel@armlinux.org.uk&gt;
Link: https://patch.msgid.link/20250904125238.193990-2-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>net: phy: Support speed selection for PHY loopback</title>
<updated>2025-03-20T07:45:08+00:00</updated>
<author>
<name>Gerhard Engleder</name>
<email>gerhard@engleder-embedded.com</email>
</author>
<published>2025-03-12T20:30:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=0d60fd50328a96a901b09ed653704ce7f41d15ce'/>
<id>urn:sha1:0d60fd50328a96a901b09ed653704ce7f41d15ce</id>
<content type='text'>
phy_loopback() leaves it to the PHY driver to select the speed of the
loopback mode. Thus, the speed of the loopback mode depends on the PHY
driver in use.

Add support for speed selection to phy_loopback() to enable loopback
with defined speeds. Ensure that link up is signaled if speed changes
as speed is not allowed to change during link up. Link down and up is
necessary for a new speed.

Signed-off-by: Gerhard Engleder &lt;gerhard@engleder-embedded.com&gt;
Link: https://patch.msgid.link/20250312203010.47429-3-gerhard@engleder-embedded.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;

</content>
</entry>
<entry>
<title>net: phy: phy_caps: Allow looking-up link caps based on speed and duplex</title>
<updated>2025-03-18T08:03:11+00:00</updated>
<author>
<name>Maxime Chevallier</name>
<email>maxime.chevallier@bootlin.com</email>
</author>
<published>2025-03-07T17:36:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=fc81e257d19f5733c22732eef29fa15ee8bef221'/>
<id>urn:sha1:fc81e257d19f5733c22732eef29fa15ee8bef221</id>
<content type='text'>
As the link_caps array is efficient for &lt;speed,duplex&gt; lookups,
implement a function for speed/duplex lookups that matches a given
mask. This replicates to some extent the phy_lookup_settings()
behaviour, matching full link_capabilities instead of a single linkmode.

phy.c's phy_santize_settings() and phylink's
phylink_ethtool_ksettings_set() performs such lookup using the
phy_settings table, but are only interested in the actual speed/duplex
that were matched, rathet than the individual linkmode.

Similar to phy_lookup_settings(), the newly introduced phy_caps_lookup()
will run through the link_caps[] array by descending speed/duplex order.

If the link_capabilities for a given &lt;speed/duplex&gt; tuple intersects the
passed linkmodes, we consider that a match.

Similar to phy_lookup_settings(), we also allow passing an 'exact'
boolean, allowing non-exact match. Here, we MUST always match the
linkmodes mask, but we allow matching on lower speed settings.

Signed-off-by: Maxime Chevallier &lt;maxime.chevallier@bootlin.com&gt;
Link: https://patch.msgid.link/20250307173611.129125-8-maxime.chevallier@bootlin.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;

</content>
</entry>
<entry>
<title>net: phy: phy_caps: Introduce phy_caps_valid</title>
<updated>2025-03-18T08:03:11+00:00</updated>
<author>
<name>Maxime Chevallier</name>
<email>maxime.chevallier@bootlin.com</email>
</author>
<published>2025-03-07T17:36:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=87b22ce312350170af5e970c5abfb2bb87e39964'/>
<id>urn:sha1:87b22ce312350170af5e970c5abfb2bb87e39964</id>
<content type='text'>
With the link_capabilities array, it's trivial to validate a given mask
againts a &lt;speed, duplex&gt; tuple. Create a helper for that purpose, and
use it to replace a phy_settings lookup in phy_check_valid();

Signed-off-by: Maxime Chevallier &lt;maxime.chevallier@bootlin.com&gt;
Link: https://patch.msgid.link/20250307173611.129125-6-maxime.chevallier@bootlin.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;

</content>
</entry>
<entry>
<title>net: phy: phy_caps: Move phy_speeds to phy_caps</title>
<updated>2025-03-18T08:03:11+00:00</updated>
<author>
<name>Maxime Chevallier</name>
<email>maxime.chevallier@bootlin.com</email>
</author>
<published>2025-03-07T17:36:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=8c8c4a87933dd924f9fb56dfd35bae7e8f30a4b5'/>
<id>urn:sha1:8c8c4a87933dd924f9fb56dfd35bae7e8f30a4b5</id>
<content type='text'>
Use the newly introduced link_capabilities array to derive the list of
possible speeds when given a combination of linkmodes. As
link_capabilities is indexed by speed, we don't have to iterate the
whole phy_settings array.

Signed-off-by: Maxime Chevallier &lt;maxime.chevallier@bootlin.com&gt;
Link: https://patch.msgid.link/20250307173611.129125-4-maxime.chevallier@bootlin.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;

</content>
</entry>
<entry>
<title>net: phy: add phylib-internal.h</title>
<updated>2025-02-25T03:14:31+00:00</updated>
<author>
<name>Heiner Kallweit</name>
<email>hkallweit1@gmail.com</email>
</author>
<published>2025-02-22T08:36:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a3e51d4711793be001220784bd7d8ce81517003e'/>
<id>urn:sha1:a3e51d4711793be001220784bd7d8ce81517003e</id>
<content type='text'>
This patch is a starting point for moving phylib-internal
declarations to a private header file.

Signed-off-by: Heiner Kallweit &lt;hkallweit1@gmail.com&gt;
Link: https://patch.msgid.link/082eacd2-a888-4716-8797-b3491ce02820@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>net: phy: c45: remove local advertisement parameter from genphy_c45_eee_is_active</title>
<updated>2025-02-19T02:07:09+00:00</updated>
<author>
<name>Heiner Kallweit</name>
<email>hkallweit1@gmail.com</email>
</author>
<published>2025-02-16T21:20:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=809265fe96fe3eb7a85a9260356767587c482cb7'/>
<id>urn:sha1:809265fe96fe3eb7a85a9260356767587c482cb7</id>
<content type='text'>
After the last user has gone, we can remove the local advertisement
parameter from genphy_c45_eee_is_active.

Signed-off-by: Heiner Kallweit &lt;hkallweit1@gmail.com&gt;
Reviewed-by: Andrew Lunn &lt;andrew@lunn.ch&gt;
Reviewed-by: Russell King (Oracle) &lt;rmk+kernel@armlinux.org.uk&gt;
Link: https://patch.msgid.link/bd121330-9e28-4bc8-8422-794bd54d561f@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>net: phy: remove helper phy_is_internal</title>
<updated>2025-02-15T01:07:46+00:00</updated>
<author>
<name>Heiner Kallweit</name>
<email>hkallweit1@gmail.com</email>
</author>
<published>2025-02-13T21:51:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6b2edfba74696e0defd181989c9effe911e6f54f'/>
<id>urn:sha1:6b2edfba74696e0defd181989c9effe911e6f54f</id>
<content type='text'>
Helper phy_is_internal() is just used in two places phylib-internally.
So let's remove it from the API.

Signed-off-by: Heiner Kallweit &lt;hkallweit1@gmail.com&gt;
Reviewed-by: Mateusz Polchlopek &lt;mateusz.polchlopek@intel.com&gt;
Reviewed-by: Russell King (Oracle) &lt;rmk+kernel@armlinux.org.uk&gt;
Link: https://patch.msgid.link/f3f35265-80a9-4ed7-ad78-ae22c21e288b@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
</feed>
