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