Skip to content

Commit d4e6cb3

Browse files
minimaxwellkuba-moo
authored andcommitted
net: phy: phy_caps: Don't skip better duplex macth on non-exact match
When performing a non-exact phy_caps lookup, we are looking for a supported mode that matches as closely as possible the passed speed/duplex. Blamed patch broke that logic by returning a match too early in case the caller asks for half-duplex, as a full-duplex linkmode may match first, and returned as a non-exact match without even trying to mach on half-duplex modes. Reported-by: Jijie Shao <[email protected]> Closes: https://lore.kernel.org/netdev/20250603102500.4ec743cf@fedora/T/#m22ed60ca635c67dc7d9cbb47e8995b2beb5c1576 Tested-by: Jijie Shao <[email protected]> Reviewed-by: Larysa Zaremba <[email protected]> Fixes: fc81e25 ("net: phy: phy_caps: Allow looking-up link caps based on speed and duplex") Signed-off-by: Maxime Chevallier <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 27cea0e commit d4e6cb3

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

drivers/net/phy/phy_caps.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,17 @@ phy_caps_lookup_by_linkmode_rev(const unsigned long *linkmodes, bool fdx_only)
188188
* When @exact is not set, we return either an exact match, or matching capabilities
189189
* at lower speed, or the lowest matching speed, or NULL.
190190
*
191+
* Non-exact matches will try to return an exact speed and duplex match, but may
192+
* return matching capabilities with same speed but a different duplex.
193+
*
191194
* Returns: a matched link_capabilities according to the above process, NULL
192195
* otherwise.
193196
*/
194197
const struct link_capabilities *
195198
phy_caps_lookup(int speed, unsigned int duplex, const unsigned long *supported,
196199
bool exact)
197200
{
198-
const struct link_capabilities *lcap, *last = NULL;
201+
const struct link_capabilities *lcap, *match = NULL, *last = NULL;
199202

200203
for_each_link_caps_desc_speed(lcap) {
201204
if (linkmode_intersects(lcap->linkmodes, supported)) {
@@ -204,16 +207,19 @@ phy_caps_lookup(int speed, unsigned int duplex, const unsigned long *supported,
204207
if (lcap->speed == speed && lcap->duplex == duplex) {
205208
return lcap;
206209
} else if (!exact) {
207-
if (lcap->speed <= speed)
208-
return lcap;
210+
if (!match && lcap->speed <= speed)
211+
match = lcap;
212+
213+
if (lcap->speed < speed)
214+
break;
209215
}
210216
}
211217
}
212218

213-
if (!exact)
214-
return last;
219+
if (!match && !exact)
220+
match = last;
215221

216-
return NULL;
222+
return match;
217223
}
218224
EXPORT_SYMBOL_GPL(phy_caps_lookup);
219225

0 commit comments

Comments
 (0)