xref: /linux/drivers/net/phy/phy_caps.c (revision c27022497dd9b8a8922dbb878c255e4260a90e6c)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #include <linux/ethtool.h>
4 #include <linux/linkmode.h>
5 #include <linux/phy.h>
6 
7 #include "phy-caps.h"
8 
9 static struct link_capabilities link_caps[__LINK_CAPA_MAX] __ro_after_init = {
10 	{ SPEED_10, DUPLEX_HALF, {0} }, /* LINK_CAPA_10HD */
11 	{ SPEED_10, DUPLEX_FULL, {0} }, /* LINK_CAPA_10FD */
12 	{ SPEED_100, DUPLEX_HALF, {0} }, /* LINK_CAPA_100HD */
13 	{ SPEED_100, DUPLEX_FULL, {0} }, /* LINK_CAPA_100FD */
14 	{ SPEED_1000, DUPLEX_HALF, {0} }, /* LINK_CAPA_1000HD */
15 	{ SPEED_1000, DUPLEX_FULL, {0} }, /* LINK_CAPA_1000FD */
16 	{ SPEED_2500, DUPLEX_FULL, {0} }, /* LINK_CAPA_2500FD */
17 	{ SPEED_5000, DUPLEX_FULL, {0} }, /* LINK_CAPA_5000FD */
18 	{ SPEED_10000, DUPLEX_FULL, {0} }, /* LINK_CAPA_10000FD */
19 	{ SPEED_20000, DUPLEX_FULL, {0} }, /* LINK_CAPA_20000FD */
20 	{ SPEED_25000, DUPLEX_FULL, {0} }, /* LINK_CAPA_25000FD */
21 	{ SPEED_40000, DUPLEX_FULL, {0} }, /* LINK_CAPA_40000FD */
22 	{ SPEED_50000, DUPLEX_FULL, {0} }, /* LINK_CAPA_50000FD */
23 	{ SPEED_56000, DUPLEX_FULL, {0} }, /* LINK_CAPA_56000FD */
24 	{ SPEED_100000, DUPLEX_FULL, {0} }, /* LINK_CAPA_100000FD */
25 	{ SPEED_200000, DUPLEX_FULL, {0} }, /* LINK_CAPA_200000FD */
26 	{ SPEED_400000, DUPLEX_FULL, {0} }, /* LINK_CAPA_400000FD */
27 	{ SPEED_800000, DUPLEX_FULL, {0} }, /* LINK_CAPA_800000FD */
28 	{ SPEED_1600000, DUPLEX_FULL, {0} }, /* LINK_CAPA_1600000FD */
29 };
30 
31 static int speed_duplex_to_capa(int speed, unsigned int duplex)
32 {
33 	if (duplex == DUPLEX_UNKNOWN ||
34 	    (speed > SPEED_1000 && duplex != DUPLEX_FULL))
35 		return -EINVAL;
36 
37 	switch (speed) {
38 	case SPEED_10: return duplex == DUPLEX_FULL ?
39 			      LINK_CAPA_10FD : LINK_CAPA_10HD;
40 	case SPEED_100: return duplex == DUPLEX_FULL ?
41 			       LINK_CAPA_100FD : LINK_CAPA_100HD;
42 	case SPEED_1000: return duplex == DUPLEX_FULL ?
43 				LINK_CAPA_1000FD : LINK_CAPA_1000HD;
44 	case SPEED_2500: return LINK_CAPA_2500FD;
45 	case SPEED_5000: return LINK_CAPA_5000FD;
46 	case SPEED_10000: return LINK_CAPA_10000FD;
47 	case SPEED_20000: return LINK_CAPA_20000FD;
48 	case SPEED_25000: return LINK_CAPA_25000FD;
49 	case SPEED_40000: return LINK_CAPA_40000FD;
50 	case SPEED_50000: return LINK_CAPA_50000FD;
51 	case SPEED_56000: return LINK_CAPA_56000FD;
52 	case SPEED_100000: return LINK_CAPA_100000FD;
53 	case SPEED_200000: return LINK_CAPA_200000FD;
54 	case SPEED_400000: return LINK_CAPA_400000FD;
55 	case SPEED_800000: return LINK_CAPA_800000FD;
56 	case SPEED_1600000: return LINK_CAPA_1600000FD;
57 	}
58 
59 	return -EINVAL;
60 }
61 
62 #define for_each_link_caps_asc_speed(cap) \
63 	for (cap = link_caps; cap < &link_caps[__LINK_CAPA_MAX]; cap++)
64 
65 #define for_each_link_caps_desc_speed(cap) \
66 	for (cap = &link_caps[__LINK_CAPA_MAX - 1]; cap >= link_caps; cap--)
67 
68 /**
69  * phy_caps_init() - Initializes the link_caps array from the link_mode_params.
70  *
71  * Returns: 0 if phy caps init was successful, -EINVAL if we found an
72  *	    unexpected linkmode setting that requires LINK_CAPS update.
73  *
74  */
75 int __init phy_caps_init(void)
76 {
77 	const struct link_mode_info *linkmode;
78 	int i, capa;
79 
80 	/* Fill the caps array from net/ethtool/common.c */
81 	for (i = 0; i < __ETHTOOL_LINK_MODE_MASK_NBITS; i++) {
82 		linkmode = &link_mode_params[i];
83 
84 		/* Sanity check the linkmodes array for number of pairs */
85 		if (linkmode->pairs < linkmode->min_pairs) {
86 			pr_err("Pairs count must not be under min_pairs for linkmode %d\n",
87 			       i);
88 			return -EINVAL;
89 		}
90 
91 		capa = speed_duplex_to_capa(linkmode->speed, linkmode->duplex);
92 
93 		if (capa < 0) {
94 			if (linkmode->speed != SPEED_UNKNOWN) {
95 				pr_err("Unknown speed %d, please update LINK_CAPS\n",
96 				       linkmode->speed);
97 				return -EINVAL;
98 			}
99 			continue;
100 		}
101 
102 		__set_bit(i, link_caps[capa].linkmodes);
103 	}
104 
105 	return 0;
106 }
107 
108 /**
109  * phy_caps_speeds() - Fill an array of supported SPEED_* values for given modes
110  * @speeds: Output array to store the speeds list into
111  * @size: Size of the output array
112  * @linkmodes: Linkmodes to get the speeds from
113  *
114  * Fills the speeds array with all possible speeds that can be achieved with
115  * the specified linkmodes.
116  *
117  * Returns: The number of speeds filled into the array. If the input array isn't
118  *	    big enough to store all speeds, fill it as much as possible.
119  */
120 size_t phy_caps_speeds(unsigned int *speeds, size_t size,
121 		       unsigned long *linkmodes)
122 {
123 	struct link_capabilities *lcap;
124 	size_t count = 0;
125 
126 	for_each_link_caps_asc_speed(lcap) {
127 		if (linkmode_intersects(lcap->linkmodes, linkmodes) &&
128 		    (count == 0 || speeds[count - 1] != lcap->speed)) {
129 			speeds[count++] = lcap->speed;
130 			if (count >= size)
131 				break;
132 		}
133 	}
134 
135 	return count;
136 }
137 
138 /**
139  * phy_caps_lookup_by_linkmode() - Lookup the fastest matching link_capabilities
140  * @linkmodes: Linkmodes to match against
141  *
142  * Returns: The highest-speed link_capabilities that intersects the given
143  *	    linkmodes. In case several DUPLEX_ options exist at that speed,
144  *	    DUPLEX_FULL is matched first. NULL is returned if no match.
145  */
146 const struct link_capabilities *
147 phy_caps_lookup_by_linkmode(const unsigned long *linkmodes)
148 {
149 	struct link_capabilities *lcap;
150 
151 	for_each_link_caps_desc_speed(lcap)
152 		if (linkmode_intersects(lcap->linkmodes, linkmodes))
153 			return lcap;
154 
155 	return NULL;
156 }
157 
158 /**
159  * phy_caps_lookup_by_linkmode_rev() - Lookup the slowest matching link_capabilities
160  * @linkmodes: Linkmodes to match against
161  * @fdx_only: Full duplex match only when set
162  *
163  * Returns: The lowest-speed link_capabilities that intersects the given
164  *	    linkmodes. When set, fdx_only will ignore half-duplex matches.
165  *	    NULL is returned if no match.
166  */
167 const struct link_capabilities *
168 phy_caps_lookup_by_linkmode_rev(const unsigned long *linkmodes, bool fdx_only)
169 {
170 	struct link_capabilities *lcap;
171 
172 	for_each_link_caps_asc_speed(lcap) {
173 		if (fdx_only && lcap->duplex != DUPLEX_FULL)
174 			continue;
175 
176 		if (linkmode_intersects(lcap->linkmodes, linkmodes))
177 			return lcap;
178 	}
179 
180 	return NULL;
181 }
182 
183 /**
184  * phy_caps_lookup() - Lookup capabilities by speed/duplex that matches a mask
185  * @speed: Speed to match
186  * @duplex: Duplex to match
187  * @supported: Mask of linkmodes to match
188  * @exact: Perform an exact match or not.
189  *
190  * Lookup a link_capabilities entry that intersect the supported linkmodes mask,
191  * and that matches the passed speed and duplex.
192  *
193  * When @exact is set, an exact match is performed on speed and duplex, meaning
194  * that if the linkmodes for the given speed and duplex intersect the supported
195  * mask, this capability is returned, otherwise we don't have a match and return
196  * NULL.
197  *
198  * When @exact is not set, we return either an exact match, or matching capabilities
199  * at lower speed, or the lowest matching speed, or NULL.
200  *
201  * Non-exact matches will try to return an exact speed and duplex match, but may
202  * return matching capabilities with same speed but a different duplex.
203  *
204  * Returns: a matched link_capabilities according to the above process, NULL
205  *	    otherwise.
206  */
207 const struct link_capabilities *
208 phy_caps_lookup(int speed, unsigned int duplex, const unsigned long *supported,
209 		bool exact)
210 {
211 	const struct link_capabilities *lcap, *match = NULL, *last = NULL;
212 
213 	for_each_link_caps_desc_speed(lcap) {
214 		if (linkmode_intersects(lcap->linkmodes, supported)) {
215 			last = lcap;
216 			/* exact match on speed and duplex*/
217 			if (lcap->speed == speed && lcap->duplex == duplex) {
218 				return lcap;
219 			} else if (!exact) {
220 				if (!match && lcap->speed <= speed)
221 					match = lcap;
222 
223 				if (lcap->speed < speed)
224 					break;
225 			}
226 		}
227 	}
228 
229 	if (!match && !exact)
230 		match = last;
231 
232 	return match;
233 }
234 EXPORT_SYMBOL_GPL(phy_caps_lookup);
235 
236 /**
237  * phy_caps_linkmode_max_speed() - Clamp a linkmodes set to a max speed
238  * @max_speed: Speed limit for the linkmode set
239  * @linkmodes: Linkmodes to limit
240  */
241 void phy_caps_linkmode_max_speed(u32 max_speed, unsigned long *linkmodes)
242 {
243 	struct link_capabilities *lcap;
244 
245 	for_each_link_caps_desc_speed(lcap)
246 		if (lcap->speed > max_speed)
247 			linkmode_andnot(linkmodes, linkmodes, lcap->linkmodes);
248 		else
249 			break;
250 }
251 
252 /**
253  * phy_caps_valid() - Validate a linkmodes set agains given speed and duplex
254  * @speed: input speed to validate
255  * @duplex: input duplex to validate. Passing DUPLEX_UNKNOWN is always not valid
256  * @linkmodes: The linkmodes to validate
257  *
258  * Returns: True if at least one of the linkmodes in @linkmodes can function at
259  *          the given speed and duplex, false otherwise.
260  */
261 bool phy_caps_valid(int speed, int duplex, const unsigned long *linkmodes)
262 {
263 	int capa = speed_duplex_to_capa(speed, duplex);
264 
265 	if (capa < 0)
266 		return false;
267 
268 	return linkmode_intersects(link_caps[capa].linkmodes, linkmodes);
269 }
270 
271 /**
272  * phy_caps_linkmodes() - Convert a bitfield of capabilities into linkmodes
273  * @caps: The list of caps, each bit corresponding to a LINK_CAPA value
274  * @linkmodes: The set of linkmodes to fill. Must be previously initialized.
275  */
276 void phy_caps_linkmodes(unsigned long caps, unsigned long *linkmodes)
277 {
278 	unsigned long capa;
279 
280 	for_each_set_bit(capa, &caps, __LINK_CAPA_MAX)
281 		linkmode_or(linkmodes, linkmodes, link_caps[capa].linkmodes);
282 }
283 EXPORT_SYMBOL_GPL(phy_caps_linkmodes);
284 
285 /**
286  * phy_caps_from_interface() - Get the link capa from a given PHY interface
287  * @interface: The PHY interface we want to get the possible Speed/Duplex from
288  *
289  * Returns: A bitmask of LINK_CAPA_xxx values that can be achieved with the
290  *          provided interface.
291  */
292 unsigned long phy_caps_from_interface(phy_interface_t interface)
293 {
294 	unsigned long link_caps = 0;
295 
296 	switch (interface) {
297 	case PHY_INTERFACE_MODE_USXGMII:
298 		link_caps |= BIT(LINK_CAPA_10000FD) | BIT(LINK_CAPA_5000FD);
299 		fallthrough;
300 
301 	case PHY_INTERFACE_MODE_10G_QXGMII:
302 		link_caps |= BIT(LINK_CAPA_2500FD);
303 		fallthrough;
304 
305 	case PHY_INTERFACE_MODE_RGMII_TXID:
306 	case PHY_INTERFACE_MODE_RGMII_RXID:
307 	case PHY_INTERFACE_MODE_RGMII_ID:
308 	case PHY_INTERFACE_MODE_RGMII:
309 	case PHY_INTERFACE_MODE_PSGMII:
310 	case PHY_INTERFACE_MODE_QSGMII:
311 	case PHY_INTERFACE_MODE_QUSGMII:
312 	case PHY_INTERFACE_MODE_SGMII:
313 	case PHY_INTERFACE_MODE_GMII:
314 		link_caps |= BIT(LINK_CAPA_1000HD) | BIT(LINK_CAPA_1000FD);
315 		fallthrough;
316 
317 	case PHY_INTERFACE_MODE_REVRMII:
318 	case PHY_INTERFACE_MODE_RMII:
319 	case PHY_INTERFACE_MODE_SMII:
320 	case PHY_INTERFACE_MODE_REVMII:
321 	case PHY_INTERFACE_MODE_MII:
322 		link_caps |= BIT(LINK_CAPA_10HD) | BIT(LINK_CAPA_10FD);
323 		fallthrough;
324 
325 	case PHY_INTERFACE_MODE_100BASEX:
326 		link_caps |= BIT(LINK_CAPA_100HD) | BIT(LINK_CAPA_100FD);
327 		break;
328 
329 	case PHY_INTERFACE_MODE_MIILITE:
330 		link_caps |= BIT(LINK_CAPA_10FD) | BIT(LINK_CAPA_100FD);
331 		break;
332 
333 	case PHY_INTERFACE_MODE_TBI:
334 	case PHY_INTERFACE_MODE_MOCA:
335 	case PHY_INTERFACE_MODE_RTBI:
336 	case PHY_INTERFACE_MODE_1000BASEX:
337 		link_caps |= BIT(LINK_CAPA_1000HD);
338 		fallthrough;
339 	case PHY_INTERFACE_MODE_1000BASEKX:
340 	case PHY_INTERFACE_MODE_TRGMII:
341 		link_caps |= BIT(LINK_CAPA_1000FD);
342 		break;
343 
344 	case PHY_INTERFACE_MODE_2500BASEX:
345 		link_caps |= BIT(LINK_CAPA_2500FD);
346 		break;
347 
348 	case PHY_INTERFACE_MODE_5GBASER:
349 		link_caps |= BIT(LINK_CAPA_5000FD);
350 		break;
351 
352 	case PHY_INTERFACE_MODE_XGMII:
353 	case PHY_INTERFACE_MODE_RXAUI:
354 	case PHY_INTERFACE_MODE_XAUI:
355 	case PHY_INTERFACE_MODE_10GBASER:
356 	case PHY_INTERFACE_MODE_10GKR:
357 		link_caps |= BIT(LINK_CAPA_10000FD);
358 		break;
359 
360 	case PHY_INTERFACE_MODE_25GBASER:
361 		link_caps |= BIT(LINK_CAPA_25000FD);
362 		break;
363 
364 	case PHY_INTERFACE_MODE_XLGMII:
365 		link_caps |= BIT(LINK_CAPA_40000FD);
366 		break;
367 
368 	case PHY_INTERFACE_MODE_50GBASER:
369 	case PHY_INTERFACE_MODE_LAUI:
370 		link_caps |= BIT(LINK_CAPA_50000FD);
371 		break;
372 
373 	case PHY_INTERFACE_MODE_100GBASEP:
374 		link_caps |= BIT(LINK_CAPA_100000FD);
375 		break;
376 
377 	case PHY_INTERFACE_MODE_INTERNAL:
378 		link_caps |= LINK_CAPA_ALL;
379 		break;
380 
381 	case PHY_INTERFACE_MODE_NA:
382 	case PHY_INTERFACE_MODE_MAX:
383 		break;
384 	}
385 
386 	return link_caps;
387 }
388 EXPORT_SYMBOL_GPL(phy_caps_from_interface);
389 
390 /**
391  * phy_caps_medium_get_supported() - Returns linkmodes supported on a given medium
392  * @supported: After this call, contains all possible linkmodes on a given medium,
393  *	       and with the given number of pairs, or less.
394  * @medium: The medium to get the support from
395  * @pairs: The number of pairs used on the given medium. Only relevant for modes
396  *	   that support this notion, such as BaseT. Pass 0 if not applicable.
397  *
398  * If no match exists, the supported field is left untouched.
399  */
400 void phy_caps_medium_get_supported(unsigned long *supported,
401 				   enum ethtool_link_medium medium,
402 				   int pairs)
403 {
404 	int i;
405 
406 	for (i = 0; i < __ETHTOOL_LINK_MODE_MASK_NBITS; i++) {
407 		/* Special bits such as Autoneg, Pause, Asym_pause, etc. are
408 		 * set and will be masked away by the port parent.
409 		 */
410 		if (link_mode_params[i].mediums == BIT(ETHTOOL_LINK_MEDIUM_NONE)) {
411 			linkmode_set_bit(i, supported);
412 			continue;
413 		}
414 
415 		/* If this medium matches, and had a non-zero min-pairs */
416 		if (link_mode_params[i].mediums & BIT(medium) &&
417 		    (!link_mode_params[i].min_pairs ||
418 		      (link_mode_params[i].min_pairs <= pairs &&
419 		      link_mode_params[i].pairs >= pairs)))
420 			linkmode_set_bit(i, supported);
421 	}
422 }
423 EXPORT_SYMBOL_GPL(phy_caps_medium_get_supported);
424 
425 /**
426  * phy_caps_mediums_from_linkmodes() - Get all mediums from a linkmodes list
427  * @linkmodes: A bitset of linkmodes to get the mediums from
428  *
429  * Returns: A bitset of ETHTOOL_MEDIUM_XXX values corresponding to all medium
430  *	    types in the linkmodes list
431  */
432 u32 phy_caps_mediums_from_linkmodes(unsigned long *linkmodes)
433 {
434 	const struct link_mode_info *linkmode;
435 	u32 mediums = 0;
436 	int i;
437 
438 	for_each_set_bit(i, linkmodes, __ETHTOOL_LINK_MODE_MASK_NBITS) {
439 		linkmode = &link_mode_params[i];
440 		mediums |= linkmode->mediums;
441 	}
442 
443 	return mediums;
444 }
445 EXPORT_SYMBOL_GPL(phy_caps_mediums_from_linkmodes);
446