xref: /linux/drivers/net/phy/phy_caps.c (revision 17fa6ee35bd4b78752a2d33b92614a1c230a1ced)
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 		capa = speed_duplex_to_capa(linkmode->speed, linkmode->duplex);
84 
85 		if (capa < 0) {
86 			if (linkmode->speed != SPEED_UNKNOWN) {
87 				pr_err("Unknown speed %d, please update LINK_CAPS\n",
88 				       linkmode->speed);
89 				return -EINVAL;
90 			}
91 			continue;
92 		}
93 
94 		__set_bit(i, link_caps[capa].linkmodes);
95 	}
96 
97 	return 0;
98 }
99 
100 /**
101  * phy_caps_speeds() - Fill an array of supported SPEED_* values for given modes
102  * @speeds: Output array to store the speeds list into
103  * @size: Size of the output array
104  * @linkmodes: Linkmodes to get the speeds from
105  *
106  * Fills the speeds array with all possible speeds that can be achieved with
107  * the specified linkmodes.
108  *
109  * Returns: The number of speeds filled into the array. If the input array isn't
110  *	    big enough to store all speeds, fill it as much as possible.
111  */
112 size_t phy_caps_speeds(unsigned int *speeds, size_t size,
113 		       unsigned long *linkmodes)
114 {
115 	struct link_capabilities *lcap;
116 	size_t count = 0;
117 
118 	for_each_link_caps_asc_speed(lcap) {
119 		if (linkmode_intersects(lcap->linkmodes, linkmodes) &&
120 		    (count == 0 || speeds[count - 1] != lcap->speed)) {
121 			speeds[count++] = lcap->speed;
122 			if (count >= size)
123 				break;
124 		}
125 	}
126 
127 	return count;
128 }
129 
130 /**
131  * phy_caps_lookup_by_linkmode() - Lookup the fastest matching link_capabilities
132  * @linkmodes: Linkmodes to match against
133  *
134  * Returns: The highest-speed link_capabilities that intersects the given
135  *	    linkmodes. In case several DUPLEX_ options exist at that speed,
136  *	    DUPLEX_FULL is matched first. NULL is returned if no match.
137  */
138 const struct link_capabilities *
139 phy_caps_lookup_by_linkmode(const unsigned long *linkmodes)
140 {
141 	struct link_capabilities *lcap;
142 
143 	for_each_link_caps_desc_speed(lcap)
144 		if (linkmode_intersects(lcap->linkmodes, linkmodes))
145 			return lcap;
146 
147 	return NULL;
148 }
149 
150 /**
151  * phy_caps_lookup_by_linkmode_rev() - Lookup the slowest matching link_capabilities
152  * @linkmodes: Linkmodes to match against
153  * @fdx_only: Full duplex match only when set
154  *
155  * Returns: The lowest-speed link_capabilities that intersects the given
156  *	    linkmodes. When set, fdx_only will ignore half-duplex matches.
157  *	    NULL is returned if no match.
158  */
159 const struct link_capabilities *
160 phy_caps_lookup_by_linkmode_rev(const unsigned long *linkmodes, bool fdx_only)
161 {
162 	struct link_capabilities *lcap;
163 
164 	for_each_link_caps_asc_speed(lcap) {
165 		if (fdx_only && lcap->duplex != DUPLEX_FULL)
166 			continue;
167 
168 		if (linkmode_intersects(lcap->linkmodes, linkmodes))
169 			return lcap;
170 	}
171 
172 	return NULL;
173 }
174 
175 /**
176  * phy_caps_lookup() - Lookup capabilities by speed/duplex that matches a mask
177  * @speed: Speed to match
178  * @duplex: Duplex to match
179  * @supported: Mask of linkmodes to match
180  * @exact: Perform an exact match or not.
181  *
182  * Lookup a link_capabilities entry that intersect the supported linkmodes mask,
183  * and that matches the passed speed and duplex.
184  *
185  * When @exact is set, an exact match is performed on speed and duplex, meaning
186  * that if the linkmodes for the given speed and duplex intersect the supported
187  * mask, this capability is returned, otherwise we don't have a match and return
188  * NULL.
189  *
190  * When @exact is not set, we return either an exact match, or matching capabilities
191  * at lower speed, or the lowest matching speed, or NULL.
192  *
193  * Non-exact matches will try to return an exact speed and duplex match, but may
194  * return matching capabilities with same speed but a different duplex.
195  *
196  * Returns: a matched link_capabilities according to the above process, NULL
197  *	    otherwise.
198  */
199 const struct link_capabilities *
200 phy_caps_lookup(int speed, unsigned int duplex, const unsigned long *supported,
201 		bool exact)
202 {
203 	const struct link_capabilities *lcap, *match = NULL, *last = NULL;
204 
205 	for_each_link_caps_desc_speed(lcap) {
206 		if (linkmode_intersects(lcap->linkmodes, supported)) {
207 			last = lcap;
208 			/* exact match on speed and duplex*/
209 			if (lcap->speed == speed && lcap->duplex == duplex) {
210 				return lcap;
211 			} else if (!exact) {
212 				if (!match && lcap->speed <= speed)
213 					match = lcap;
214 
215 				if (lcap->speed < speed)
216 					break;
217 			}
218 		}
219 	}
220 
221 	if (!match && !exact)
222 		match = last;
223 
224 	return match;
225 }
226 EXPORT_SYMBOL_GPL(phy_caps_lookup);
227 
228 /**
229  * phy_caps_linkmode_max_speed() - Clamp a linkmodes set to a max speed
230  * @max_speed: Speed limit for the linkmode set
231  * @linkmodes: Linkmodes to limit
232  */
233 void phy_caps_linkmode_max_speed(u32 max_speed, unsigned long *linkmodes)
234 {
235 	struct link_capabilities *lcap;
236 
237 	for_each_link_caps_desc_speed(lcap)
238 		if (lcap->speed > max_speed)
239 			linkmode_andnot(linkmodes, linkmodes, lcap->linkmodes);
240 		else
241 			break;
242 }
243 
244 /**
245  * phy_caps_valid() - Validate a linkmodes set agains given speed and duplex
246  * @speed: input speed to validate
247  * @duplex: input duplex to validate. Passing DUPLEX_UNKNOWN is always not valid
248  * @linkmodes: The linkmodes to validate
249  *
250  * Returns: True if at least one of the linkmodes in @linkmodes can function at
251  *          the given speed and duplex, false otherwise.
252  */
253 bool phy_caps_valid(int speed, int duplex, const unsigned long *linkmodes)
254 {
255 	int capa = speed_duplex_to_capa(speed, duplex);
256 
257 	if (capa < 0)
258 		return false;
259 
260 	return linkmode_intersects(link_caps[capa].linkmodes, linkmodes);
261 }
262 
263 /**
264  * phy_caps_linkmodes() - Convert a bitfield of capabilities into linkmodes
265  * @caps: The list of caps, each bit corresponding to a LINK_CAPA value
266  * @linkmodes: The set of linkmodes to fill. Must be previously initialized.
267  */
268 void phy_caps_linkmodes(unsigned long caps, unsigned long *linkmodes)
269 {
270 	unsigned long capa;
271 
272 	for_each_set_bit(capa, &caps, __LINK_CAPA_MAX)
273 		linkmode_or(linkmodes, linkmodes, link_caps[capa].linkmodes);
274 }
275 EXPORT_SYMBOL_GPL(phy_caps_linkmodes);
276 
277 /**
278  * phy_caps_from_interface() - Get the link capa from a given PHY interface
279  * @interface: The PHY interface we want to get the possible Speed/Duplex from
280  *
281  * Returns: A bitmask of LINK_CAPA_xxx values that can be achieved with the
282  *          provided interface.
283  */
284 unsigned long phy_caps_from_interface(phy_interface_t interface)
285 {
286 	unsigned long link_caps = 0;
287 
288 	switch (interface) {
289 	case PHY_INTERFACE_MODE_USXGMII:
290 		link_caps |= BIT(LINK_CAPA_10000FD) | BIT(LINK_CAPA_5000FD);
291 		fallthrough;
292 
293 	case PHY_INTERFACE_MODE_10G_QXGMII:
294 		link_caps |= BIT(LINK_CAPA_2500FD);
295 		fallthrough;
296 
297 	case PHY_INTERFACE_MODE_RGMII_TXID:
298 	case PHY_INTERFACE_MODE_RGMII_RXID:
299 	case PHY_INTERFACE_MODE_RGMII_ID:
300 	case PHY_INTERFACE_MODE_RGMII:
301 	case PHY_INTERFACE_MODE_PSGMII:
302 	case PHY_INTERFACE_MODE_QSGMII:
303 	case PHY_INTERFACE_MODE_QUSGMII:
304 	case PHY_INTERFACE_MODE_SGMII:
305 	case PHY_INTERFACE_MODE_GMII:
306 		link_caps |= BIT(LINK_CAPA_1000HD) | BIT(LINK_CAPA_1000FD);
307 		fallthrough;
308 
309 	case PHY_INTERFACE_MODE_REVRMII:
310 	case PHY_INTERFACE_MODE_RMII:
311 	case PHY_INTERFACE_MODE_SMII:
312 	case PHY_INTERFACE_MODE_REVMII:
313 	case PHY_INTERFACE_MODE_MII:
314 		link_caps |= BIT(LINK_CAPA_10HD) | BIT(LINK_CAPA_10FD);
315 		fallthrough;
316 
317 	case PHY_INTERFACE_MODE_100BASEX:
318 		link_caps |= BIT(LINK_CAPA_100HD) | BIT(LINK_CAPA_100FD);
319 		break;
320 
321 	case PHY_INTERFACE_MODE_MIILITE:
322 		link_caps |= BIT(LINK_CAPA_10FD) | BIT(LINK_CAPA_100FD);
323 		break;
324 
325 	case PHY_INTERFACE_MODE_TBI:
326 	case PHY_INTERFACE_MODE_MOCA:
327 	case PHY_INTERFACE_MODE_RTBI:
328 	case PHY_INTERFACE_MODE_1000BASEX:
329 		link_caps |= BIT(LINK_CAPA_1000HD);
330 		fallthrough;
331 	case PHY_INTERFACE_MODE_1000BASEKX:
332 	case PHY_INTERFACE_MODE_TRGMII:
333 		link_caps |= BIT(LINK_CAPA_1000FD);
334 		break;
335 
336 	case PHY_INTERFACE_MODE_2500BASEX:
337 		link_caps |= BIT(LINK_CAPA_2500FD);
338 		break;
339 
340 	case PHY_INTERFACE_MODE_5GBASER:
341 		link_caps |= BIT(LINK_CAPA_5000FD);
342 		break;
343 
344 	case PHY_INTERFACE_MODE_XGMII:
345 	case PHY_INTERFACE_MODE_RXAUI:
346 	case PHY_INTERFACE_MODE_XAUI:
347 	case PHY_INTERFACE_MODE_10GBASER:
348 	case PHY_INTERFACE_MODE_10GKR:
349 		link_caps |= BIT(LINK_CAPA_10000FD);
350 		break;
351 
352 	case PHY_INTERFACE_MODE_25GBASER:
353 		link_caps |= BIT(LINK_CAPA_25000FD);
354 		break;
355 
356 	case PHY_INTERFACE_MODE_XLGMII:
357 		link_caps |= BIT(LINK_CAPA_40000FD);
358 		break;
359 
360 	case PHY_INTERFACE_MODE_50GBASER:
361 	case PHY_INTERFACE_MODE_LAUI:
362 		link_caps |= BIT(LINK_CAPA_50000FD);
363 		break;
364 
365 	case PHY_INTERFACE_MODE_100GBASEP:
366 		link_caps |= BIT(LINK_CAPA_100000FD);
367 		break;
368 
369 	case PHY_INTERFACE_MODE_INTERNAL:
370 		link_caps |= LINK_CAPA_ALL;
371 		break;
372 
373 	case PHY_INTERFACE_MODE_NA:
374 	case PHY_INTERFACE_MODE_MAX:
375 		break;
376 	}
377 
378 	return link_caps;
379 }
380 EXPORT_SYMBOL_GPL(phy_caps_from_interface);
381