diff options
Diffstat (limited to 'drivers/net/phy/phy_caps.c')
| -rw-r--r-- | drivers/net/phy/phy_caps.c | 18 | 
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/net/phy/phy_caps.c b/drivers/net/phy/phy_caps.c index 703321689726..38417e288611 100644 --- a/drivers/net/phy/phy_caps.c +++ b/drivers/net/phy/phy_caps.c @@ -188,6 +188,9 @@ phy_caps_lookup_by_linkmode_rev(const unsigned long *linkmodes, bool fdx_only)   * When @exact is not set, we return either an exact match, or matching capabilities   * at lower speed, or the lowest matching speed, or NULL.   * + * Non-exact matches will try to return an exact speed and duplex match, but may + * return matching capabilities with same speed but a different duplex. + *   * Returns: a matched link_capabilities according to the above process, NULL   *	    otherwise.   */ @@ -195,7 +198,7 @@ const struct link_capabilities *  phy_caps_lookup(int speed, unsigned int duplex, const unsigned long *supported,  		bool exact)  { -	const struct link_capabilities *lcap, *last = NULL; +	const struct link_capabilities *lcap, *match = NULL, *last = NULL;  	for_each_link_caps_desc_speed(lcap) {  		if (linkmode_intersects(lcap->linkmodes, supported)) { @@ -204,16 +207,19 @@ phy_caps_lookup(int speed, unsigned int duplex, const unsigned long *supported,  			if (lcap->speed == speed && lcap->duplex == duplex) {  				return lcap;  			} else if (!exact) { -				if (lcap->speed <= speed) -					return lcap; +				if (!match && lcap->speed <= speed) +					match = lcap; + +				if (lcap->speed < speed) +					break;  			}  		}  	} -	if (!exact) -		return last; +	if (!match && !exact) +		match = last; -	return NULL; +	return match;  }  EXPORT_SYMBOL_GPL(phy_caps_lookup);  | 
