@@ -188,14 +188,17 @@ phy_caps_lookup_by_linkmode_rev(const unsigned long *linkmodes, bool fdx_only)
188
188
* When @exact is not set, we return either an exact match, or matching capabilities
189
189
* at lower speed, or the lowest matching speed, or NULL.
190
190
*
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
+ *
191
194
* Returns: a matched link_capabilities according to the above process, NULL
192
195
* otherwise.
193
196
*/
194
197
const struct link_capabilities *
195
198
phy_caps_lookup (int speed , unsigned int duplex , const unsigned long * supported ,
196
199
bool exact )
197
200
{
198
- const struct link_capabilities * lcap , * last = NULL ;
201
+ const struct link_capabilities * lcap , * match = NULL , * last = NULL ;
199
202
200
203
for_each_link_caps_desc_speed (lcap ) {
201
204
if (linkmode_intersects (lcap -> linkmodes , supported )) {
@@ -204,16 +207,19 @@ phy_caps_lookup(int speed, unsigned int duplex, const unsigned long *supported,
204
207
if (lcap -> speed == speed && lcap -> duplex == duplex ) {
205
208
return lcap ;
206
209
} 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 ;
209
215
}
210
216
}
211
217
}
212
218
213
- if (!exact )
214
- return last ;
219
+ if (!match && ! exact )
220
+ match = last ;
215
221
216
- return NULL ;
222
+ return match ;
217
223
}
218
224
EXPORT_SYMBOL_GPL (phy_caps_lookup );
219
225
0 commit comments