1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * phylink models the MAC to optional PHY connection, supporting |
4 | * technologies such as SFP cages where the PHY is hot-pluggable. |
5 | * |
6 | * Copyright (C) 2015 Russell King |
7 | */ |
8 | #include <linux/acpi.h> |
9 | #include <linux/ethtool.h> |
10 | #include <linux/export.h> |
11 | #include <linux/gpio/consumer.h> |
12 | #include <linux/netdevice.h> |
13 | #include <linux/of.h> |
14 | #include <linux/of_mdio.h> |
15 | #include <linux/phy.h> |
16 | #include <linux/phy_fixed.h> |
17 | #include <linux/phylink.h> |
18 | #include <linux/rtnetlink.h> |
19 | #include <linux/spinlock.h> |
20 | #include <linux/timer.h> |
21 | #include <linux/workqueue.h> |
22 | |
23 | #include "phy-caps.h" |
24 | #include "sfp.h" |
25 | #include "swphy.h" |
26 | |
27 | enum { |
28 | PHYLINK_DISABLE_STOPPED, |
29 | PHYLINK_DISABLE_LINK, |
30 | PHYLINK_DISABLE_MAC_WOL, |
31 | |
32 | PCS_STATE_DOWN = 0, |
33 | PCS_STATE_STARTING, |
34 | PCS_STATE_STARTED, |
35 | }; |
36 | |
37 | /** |
38 | * struct phylink - internal data type for phylink |
39 | */ |
40 | struct phylink { |
41 | /* private: */ |
42 | struct net_device *netdev; |
43 | const struct phylink_mac_ops *mac_ops; |
44 | struct phylink_config *config; |
45 | struct phylink_pcs *pcs; |
46 | struct device *dev; |
47 | unsigned int old_link_state:1; |
48 | |
49 | unsigned long phylink_disable_state; /* bitmask of disables */ |
50 | struct phy_device *phydev; |
51 | phy_interface_t link_interface; /* PHY_INTERFACE_xxx */ |
52 | u8 cfg_link_an_mode; /* MLO_AN_xxx */ |
53 | u8 req_link_an_mode; /* Requested MLO_AN_xxx mode */ |
54 | u8 act_link_an_mode; /* Active MLO_AN_xxx mode */ |
55 | u8 link_port; /* The current non-phy ethtool port */ |
56 | __ETHTOOL_DECLARE_LINK_MODE_MASK(supported); |
57 | __ETHTOOL_DECLARE_LINK_MODE_MASK(supported_lpi); |
58 | |
59 | /* The link configuration settings */ |
60 | struct phylink_link_state link_config; |
61 | |
62 | /* The current settings */ |
63 | phy_interface_t cur_interface; |
64 | |
65 | struct gpio_desc *link_gpio; |
66 | unsigned int link_irq; |
67 | struct timer_list link_poll; |
68 | |
69 | struct mutex state_mutex; |
70 | struct phylink_link_state phy_state; |
71 | unsigned int phy_ib_mode; |
72 | struct work_struct resolve; |
73 | unsigned int pcs_neg_mode; |
74 | unsigned int pcs_state; |
75 | |
76 | bool link_failed; |
77 | bool suspend_link_up; |
78 | bool major_config_failed; |
79 | bool mac_supports_eee_ops; |
80 | bool mac_supports_eee; |
81 | bool phy_enable_tx_lpi; |
82 | bool mac_enable_tx_lpi; |
83 | bool mac_tx_clk_stop; |
84 | u32 mac_tx_lpi_timer; |
85 | u8 mac_rx_clk_stop_blocked; |
86 | |
87 | struct sfp_bus *sfp_bus; |
88 | bool sfp_may_have_phy; |
89 | DECLARE_PHY_INTERFACE_MASK(sfp_interfaces); |
90 | __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); |
91 | u8 sfp_port; |
92 | |
93 | struct eee_config eee_cfg; |
94 | }; |
95 | |
96 | #define phylink_printk(level, pl, fmt, ...) \ |
97 | do { \ |
98 | if ((pl)->config->type == PHYLINK_NETDEV) \ |
99 | netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \ |
100 | else if ((pl)->config->type == PHYLINK_DEV) \ |
101 | dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \ |
102 | } while (0) |
103 | |
104 | #define phylink_err(pl, fmt, ...) \ |
105 | phylink_printk(KERN_ERR, pl, fmt, ##__VA_ARGS__) |
106 | #define phylink_warn(pl, fmt, ...) \ |
107 | phylink_printk(KERN_WARNING, pl, fmt, ##__VA_ARGS__) |
108 | #define phylink_info(pl, fmt, ...) \ |
109 | phylink_printk(KERN_INFO, pl, fmt, ##__VA_ARGS__) |
110 | #if defined(CONFIG_DYNAMIC_DEBUG) |
111 | #define phylink_dbg(pl, fmt, ...) \ |
112 | do { \ |
113 | if ((pl)->config->type == PHYLINK_NETDEV) \ |
114 | netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \ |
115 | else if ((pl)->config->type == PHYLINK_DEV) \ |
116 | dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \ |
117 | } while (0) |
118 | #elif defined(DEBUG) |
119 | #define phylink_dbg(pl, fmt, ...) \ |
120 | phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__) |
121 | #else |
122 | #define phylink_dbg(pl, fmt, ...) \ |
123 | ({ \ |
124 | if (0) \ |
125 | phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__); \ |
126 | }) |
127 | #endif |
128 | |
129 | static const phy_interface_t phylink_sfp_interface_preference[] = { |
130 | PHY_INTERFACE_MODE_25GBASER, |
131 | PHY_INTERFACE_MODE_USXGMII, |
132 | PHY_INTERFACE_MODE_10GBASER, |
133 | PHY_INTERFACE_MODE_5GBASER, |
134 | PHY_INTERFACE_MODE_2500BASEX, |
135 | PHY_INTERFACE_MODE_SGMII, |
136 | PHY_INTERFACE_MODE_1000BASEX, |
137 | PHY_INTERFACE_MODE_100BASEX, |
138 | }; |
139 | |
140 | static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces); |
141 | |
142 | /** |
143 | * phylink_set_port_modes() - set the port type modes in the ethtool mask |
144 | * @mask: ethtool link mode mask |
145 | * |
146 | * Sets all the port type modes in the ethtool mask. MAC drivers should |
147 | * use this in their 'validate' callback. |
148 | */ |
149 | void phylink_set_port_modes(unsigned long *mask) |
150 | { |
151 | phylink_set(mask, TP); |
152 | phylink_set(mask, AUI); |
153 | phylink_set(mask, MII); |
154 | phylink_set(mask, FIBRE); |
155 | phylink_set(mask, BNC); |
156 | phylink_set(mask, Backplane); |
157 | } |
158 | EXPORT_SYMBOL_GPL(phylink_set_port_modes); |
159 | |
160 | static int phylink_is_empty_linkmode(const unsigned long *linkmode) |
161 | { |
162 | __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp) = { 0, }; |
163 | |
164 | phylink_set_port_modes(tmp); |
165 | phylink_set(tmp, Autoneg); |
166 | phylink_set(tmp, Pause); |
167 | phylink_set(tmp, Asym_Pause); |
168 | |
169 | return linkmode_subset(src1: linkmode, src2: tmp); |
170 | } |
171 | |
172 | static const char *phylink_an_mode_str(unsigned int mode) |
173 | { |
174 | static const char *modestr[] = { |
175 | [MLO_AN_PHY] = "phy", |
176 | [MLO_AN_FIXED] = "fixed", |
177 | [MLO_AN_INBAND] = "inband", |
178 | }; |
179 | |
180 | return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown"; |
181 | } |
182 | |
183 | static const char *phylink_pcs_mode_str(unsigned int mode) |
184 | { |
185 | if (!mode) |
186 | return "none"; |
187 | |
188 | if (mode & PHYLINK_PCS_NEG_OUTBAND) |
189 | return "outband"; |
190 | |
191 | if (mode & PHYLINK_PCS_NEG_INBAND) { |
192 | if (mode & PHYLINK_PCS_NEG_ENABLED) |
193 | return "inband,an-enabled"; |
194 | else |
195 | return "inband,an-disabled"; |
196 | } |
197 | |
198 | return "unknown"; |
199 | } |
200 | |
201 | static unsigned int phylink_interface_signal_rate(phy_interface_t interface) |
202 | { |
203 | switch (interface) { |
204 | case PHY_INTERFACE_MODE_SGMII: |
205 | case PHY_INTERFACE_MODE_1000BASEX: /* 1.25Mbd */ |
206 | return 1250; |
207 | case PHY_INTERFACE_MODE_2500BASEX: /* 3.125Mbd */ |
208 | return 3125; |
209 | case PHY_INTERFACE_MODE_5GBASER: /* 5.15625Mbd */ |
210 | return 5156; |
211 | case PHY_INTERFACE_MODE_10GBASER: /* 10.3125Mbd */ |
212 | return 10313; |
213 | default: |
214 | return 0; |
215 | } |
216 | } |
217 | |
218 | /** |
219 | * phylink_interface_max_speed() - get the maximum speed of a phy interface |
220 | * @interface: phy interface mode defined by &typedef phy_interface_t |
221 | * |
222 | * Determine the maximum speed of a phy interface. This is intended to help |
223 | * determine the correct speed to pass to the MAC when the phy is performing |
224 | * rate matching. |
225 | * |
226 | * Return: The maximum speed of @interface |
227 | */ |
228 | static int phylink_interface_max_speed(phy_interface_t interface) |
229 | { |
230 | switch (interface) { |
231 | case PHY_INTERFACE_MODE_100BASEX: |
232 | case PHY_INTERFACE_MODE_REVRMII: |
233 | case PHY_INTERFACE_MODE_RMII: |
234 | case PHY_INTERFACE_MODE_SMII: |
235 | case PHY_INTERFACE_MODE_REVMII: |
236 | case PHY_INTERFACE_MODE_MII: |
237 | return SPEED_100; |
238 | |
239 | case PHY_INTERFACE_MODE_TBI: |
240 | case PHY_INTERFACE_MODE_MOCA: |
241 | case PHY_INTERFACE_MODE_RTBI: |
242 | case PHY_INTERFACE_MODE_1000BASEX: |
243 | case PHY_INTERFACE_MODE_1000BASEKX: |
244 | case PHY_INTERFACE_MODE_TRGMII: |
245 | case PHY_INTERFACE_MODE_RGMII_TXID: |
246 | case PHY_INTERFACE_MODE_RGMII_RXID: |
247 | case PHY_INTERFACE_MODE_RGMII_ID: |
248 | case PHY_INTERFACE_MODE_RGMII: |
249 | case PHY_INTERFACE_MODE_PSGMII: |
250 | case PHY_INTERFACE_MODE_QSGMII: |
251 | case PHY_INTERFACE_MODE_QUSGMII: |
252 | case PHY_INTERFACE_MODE_SGMII: |
253 | case PHY_INTERFACE_MODE_GMII: |
254 | return SPEED_1000; |
255 | |
256 | case PHY_INTERFACE_MODE_2500BASEX: |
257 | case PHY_INTERFACE_MODE_10G_QXGMII: |
258 | return SPEED_2500; |
259 | |
260 | case PHY_INTERFACE_MODE_5GBASER: |
261 | return SPEED_5000; |
262 | |
263 | case PHY_INTERFACE_MODE_XGMII: |
264 | case PHY_INTERFACE_MODE_RXAUI: |
265 | case PHY_INTERFACE_MODE_XAUI: |
266 | case PHY_INTERFACE_MODE_10GBASER: |
267 | case PHY_INTERFACE_MODE_10GKR: |
268 | case PHY_INTERFACE_MODE_USXGMII: |
269 | return SPEED_10000; |
270 | |
271 | case PHY_INTERFACE_MODE_25GBASER: |
272 | return SPEED_25000; |
273 | |
274 | case PHY_INTERFACE_MODE_XLGMII: |
275 | return SPEED_40000; |
276 | |
277 | case PHY_INTERFACE_MODE_INTERNAL: |
278 | case PHY_INTERFACE_MODE_NA: |
279 | case PHY_INTERFACE_MODE_MAX: |
280 | /* No idea! Garbage in, unknown out */ |
281 | return SPEED_UNKNOWN; |
282 | } |
283 | |
284 | /* If we get here, someone forgot to add an interface mode above */ |
285 | WARN_ON_ONCE(1); |
286 | return SPEED_UNKNOWN; |
287 | } |
288 | |
289 | static struct { |
290 | unsigned long mask; |
291 | int speed; |
292 | unsigned int duplex; |
293 | unsigned int caps_bit; |
294 | } phylink_caps_params[] = { |
295 | { MAC_400000FD, SPEED_400000, DUPLEX_FULL, BIT(LINK_CAPA_400000FD) }, |
296 | { MAC_200000FD, SPEED_200000, DUPLEX_FULL, BIT(LINK_CAPA_200000FD) }, |
297 | { MAC_100000FD, SPEED_100000, DUPLEX_FULL, BIT(LINK_CAPA_100000FD) }, |
298 | { MAC_56000FD, SPEED_56000, DUPLEX_FULL, BIT(LINK_CAPA_56000FD) }, |
299 | { MAC_50000FD, SPEED_50000, DUPLEX_FULL, BIT(LINK_CAPA_50000FD) }, |
300 | { MAC_40000FD, SPEED_40000, DUPLEX_FULL, BIT(LINK_CAPA_40000FD) }, |
301 | { MAC_25000FD, SPEED_25000, DUPLEX_FULL, BIT(LINK_CAPA_25000FD) }, |
302 | { MAC_20000FD, SPEED_20000, DUPLEX_FULL, BIT(LINK_CAPA_20000FD) }, |
303 | { MAC_10000FD, SPEED_10000, DUPLEX_FULL, BIT(LINK_CAPA_10000FD) }, |
304 | { MAC_5000FD, SPEED_5000, DUPLEX_FULL, BIT(LINK_CAPA_5000FD) }, |
305 | { MAC_2500FD, SPEED_2500, DUPLEX_FULL, BIT(LINK_CAPA_2500FD) }, |
306 | { MAC_1000FD, SPEED_1000, DUPLEX_FULL, BIT(LINK_CAPA_1000FD) }, |
307 | { MAC_1000HD, SPEED_1000, DUPLEX_HALF, BIT(LINK_CAPA_1000HD) }, |
308 | { MAC_100FD, SPEED_100, DUPLEX_FULL, BIT(LINK_CAPA_100FD) }, |
309 | { MAC_100HD, SPEED_100, DUPLEX_HALF, BIT(LINK_CAPA_100HD) }, |
310 | { MAC_10FD, SPEED_10, DUPLEX_FULL, BIT(LINK_CAPA_10FD) }, |
311 | { MAC_10HD, SPEED_10, DUPLEX_HALF, BIT(LINK_CAPA_10HD) }, |
312 | }; |
313 | |
314 | /** |
315 | * phylink_caps_to_link_caps() - Convert a set of MAC capabilities LINK caps |
316 | * @caps: A set of MAC capabilities |
317 | * |
318 | * Returns: The corresponding set of LINK_CAPA as defined in phy-caps.h |
319 | */ |
320 | static unsigned long phylink_caps_to_link_caps(unsigned long caps) |
321 | { |
322 | unsigned long link_caps = 0; |
323 | int i; |
324 | |
325 | for (i = 0; i < ARRAY_SIZE(phylink_caps_params); i++) |
326 | if (caps & phylink_caps_params[i].mask) |
327 | link_caps |= phylink_caps_params[i].caps_bit; |
328 | |
329 | return link_caps; |
330 | } |
331 | |
332 | static unsigned long phylink_link_caps_to_mac_caps(unsigned long link_caps) |
333 | { |
334 | unsigned long caps = 0; |
335 | int i; |
336 | |
337 | for (i = 0; i < ARRAY_SIZE(phylink_caps_params); i++) |
338 | if (link_caps & phylink_caps_params[i].caps_bit) |
339 | caps |= phylink_caps_params[i].mask; |
340 | |
341 | return caps; |
342 | } |
343 | |
344 | /** |
345 | * phylink_caps_to_linkmodes() - Convert capabilities to ethtool link modes |
346 | * @linkmodes: ethtool linkmode mask (must be already initialised) |
347 | * @caps: bitmask of MAC capabilities |
348 | * |
349 | * Set all possible pause, speed and duplex linkmodes in @linkmodes that are |
350 | * supported by the @caps. @linkmodes must have been initialised previously. |
351 | */ |
352 | static void phylink_caps_to_linkmodes(unsigned long *linkmodes, |
353 | unsigned long caps) |
354 | { |
355 | unsigned long link_caps = phylink_caps_to_link_caps(caps); |
356 | |
357 | if (caps & MAC_SYM_PAUSE) |
358 | __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes); |
359 | |
360 | if (caps & MAC_ASYM_PAUSE) |
361 | __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes); |
362 | |
363 | phy_caps_linkmodes(caps: link_caps, linkmodes); |
364 | } |
365 | |
366 | /** |
367 | * phylink_limit_mac_speed - limit the phylink_config to a maximum speed |
368 | * @config: pointer to a &struct phylink_config |
369 | * @max_speed: maximum speed |
370 | * |
371 | * Mask off MAC capabilities for speeds higher than the @max_speed parameter. |
372 | * Any further motifications of config.mac_capabilities will override this. |
373 | */ |
374 | void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed) |
375 | { |
376 | int i; |
377 | |
378 | for (i = 0; i < ARRAY_SIZE(phylink_caps_params) && |
379 | phylink_caps_params[i].speed > max_speed; i++) |
380 | config->mac_capabilities &= ~phylink_caps_params[i].mask; |
381 | } |
382 | EXPORT_SYMBOL_GPL(phylink_limit_mac_speed); |
383 | |
384 | /** |
385 | * phylink_cap_from_speed_duplex - Get mac capability from speed/duplex |
386 | * @speed: the speed to search for |
387 | * @duplex: the duplex to search for |
388 | * |
389 | * Find the mac capability for a given speed and duplex. |
390 | * |
391 | * Return: A mask with the mac capability patching @speed and @duplex, or 0 if |
392 | * there were no matches. |
393 | */ |
394 | static unsigned long phylink_cap_from_speed_duplex(int speed, |
395 | unsigned int duplex) |
396 | { |
397 | int i; |
398 | |
399 | for (i = 0; i < ARRAY_SIZE(phylink_caps_params); i++) { |
400 | if (speed == phylink_caps_params[i].speed && |
401 | duplex == phylink_caps_params[i].duplex) |
402 | return phylink_caps_params[i].mask; |
403 | } |
404 | |
405 | return 0; |
406 | } |
407 | |
408 | /** |
409 | * phylink_get_capabilities() - get capabilities for a given MAC |
410 | * @interface: phy interface mode defined by &typedef phy_interface_t |
411 | * @mac_capabilities: bitmask of MAC capabilities |
412 | * @rate_matching: type of rate matching being performed |
413 | * |
414 | * Get the MAC capabilities that are supported by the @interface mode and |
415 | * @mac_capabilities. |
416 | */ |
417 | static unsigned long phylink_get_capabilities(phy_interface_t interface, |
418 | unsigned long mac_capabilities, |
419 | int rate_matching) |
420 | { |
421 | unsigned long link_caps = phy_caps_from_interface(interface); |
422 | int max_speed = phylink_interface_max_speed(interface); |
423 | unsigned long caps = MAC_SYM_PAUSE | MAC_ASYM_PAUSE; |
424 | unsigned long matched_caps = 0; |
425 | |
426 | caps |= phylink_link_caps_to_mac_caps(link_caps); |
427 | |
428 | switch (rate_matching) { |
429 | case RATE_MATCH_OPEN_LOOP: |
430 | /* TODO */ |
431 | fallthrough; |
432 | case RATE_MATCH_NONE: |
433 | matched_caps = 0; |
434 | break; |
435 | case RATE_MATCH_PAUSE: { |
436 | /* The MAC must support asymmetric pause towards the local |
437 | * device for this. We could allow just symmetric pause, but |
438 | * then we might have to renegotiate if the link partner |
439 | * doesn't support pause. This is because there's no way to |
440 | * accept pause frames without transmitting them if we only |
441 | * support symmetric pause. |
442 | */ |
443 | if (!(mac_capabilities & MAC_SYM_PAUSE) || |
444 | !(mac_capabilities & MAC_ASYM_PAUSE)) |
445 | break; |
446 | |
447 | /* We can't adapt if the MAC doesn't support the interface's |
448 | * max speed at full duplex. |
449 | */ |
450 | if (mac_capabilities & |
451 | phylink_cap_from_speed_duplex(speed: max_speed, DUPLEX_FULL)) |
452 | matched_caps = GENMASK(__fls(caps), __fls(MAC_10HD)); |
453 | break; |
454 | } |
455 | case RATE_MATCH_CRS: |
456 | /* The MAC must support half duplex at the interface's max |
457 | * speed. |
458 | */ |
459 | if (mac_capabilities & |
460 | phylink_cap_from_speed_duplex(speed: max_speed, DUPLEX_HALF)) { |
461 | matched_caps = GENMASK(__fls(caps), __fls(MAC_10HD)); |
462 | matched_caps &= mac_capabilities; |
463 | } |
464 | break; |
465 | } |
466 | |
467 | return (caps & mac_capabilities) | matched_caps; |
468 | } |
469 | |
470 | /** |
471 | * phylink_validate_mask_caps() - Restrict link modes based on caps |
472 | * @supported: ethtool bitmask for supported link modes. |
473 | * @state: pointer to a &struct phylink_link_state. |
474 | * @mac_capabilities: bitmask of MAC capabilities |
475 | * |
476 | * Calculate the supported link modes based on @mac_capabilities, and restrict |
477 | * @supported and @state based on that. Use this function if your capabiliies |
478 | * aren't constant, such as if they vary depending on the interface. |
479 | */ |
480 | static void phylink_validate_mask_caps(unsigned long *supported, |
481 | struct phylink_link_state *state, |
482 | unsigned long mac_capabilities) |
483 | { |
484 | __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; |
485 | unsigned long caps; |
486 | |
487 | phylink_set_port_modes(mask); |
488 | phylink_set(mask, Autoneg); |
489 | caps = phylink_get_capabilities(interface: state->interface, mac_capabilities, |
490 | rate_matching: state->rate_matching); |
491 | phylink_caps_to_linkmodes(linkmodes: mask, caps); |
492 | |
493 | linkmode_and(dst: supported, a: supported, b: mask); |
494 | linkmode_and(dst: state->advertising, a: state->advertising, b: mask); |
495 | } |
496 | |
497 | static int phylink_validate_mac_and_pcs(struct phylink *pl, |
498 | unsigned long *supported, |
499 | struct phylink_link_state *state) |
500 | { |
501 | struct phylink_pcs *pcs = NULL; |
502 | unsigned long capabilities; |
503 | int ret; |
504 | |
505 | /* Get the PCS for this interface mode */ |
506 | if (pl->mac_ops->mac_select_pcs) { |
507 | pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); |
508 | if (IS_ERR(ptr: pcs)) |
509 | return PTR_ERR(ptr: pcs); |
510 | } |
511 | |
512 | if (pcs) { |
513 | /* The PCS, if present, must be setup before phylink_create() |
514 | * has been called. If the ops is not initialised, print an |
515 | * error and backtrace rather than oopsing the kernel. |
516 | */ |
517 | if (!pcs->ops) { |
518 | phylink_err(pl, "interface %s: uninitialised PCS\n", |
519 | phy_modes(state->interface)); |
520 | dump_stack(); |
521 | return -EINVAL; |
522 | } |
523 | |
524 | /* Ensure that this PCS supports the interface which the MAC |
525 | * returned it for. It is an error for the MAC to return a PCS |
526 | * that does not support the interface mode. |
527 | */ |
528 | if (!phy_interface_empty(intf: pcs->supported_interfaces) && |
529 | !test_bit(state->interface, pcs->supported_interfaces)) { |
530 | phylink_err(pl, "MAC returned PCS which does not support %s\n", |
531 | phy_modes(state->interface)); |
532 | return -EINVAL; |
533 | } |
534 | |
535 | /* Validate the link parameters with the PCS */ |
536 | if (pcs->ops->pcs_validate) { |
537 | ret = pcs->ops->pcs_validate(pcs, supported, state); |
538 | if (ret < 0 || phylink_is_empty_linkmode(linkmode: supported)) |
539 | return -EINVAL; |
540 | |
541 | /* Ensure the advertising mask is a subset of the |
542 | * supported mask. |
543 | */ |
544 | linkmode_and(dst: state->advertising, a: state->advertising, |
545 | b: supported); |
546 | } |
547 | } |
548 | |
549 | /* Then validate the link parameters with the MAC */ |
550 | if (pl->mac_ops->mac_get_caps) |
551 | capabilities = pl->mac_ops->mac_get_caps(pl->config, |
552 | state->interface); |
553 | else |
554 | capabilities = pl->config->mac_capabilities; |
555 | |
556 | phylink_validate_mask_caps(supported, state, mac_capabilities: capabilities); |
557 | |
558 | return phylink_is_empty_linkmode(linkmode: supported) ? -EINVAL : 0; |
559 | } |
560 | |
561 | static void phylink_validate_one(struct phylink *pl, struct phy_device *phy, |
562 | const unsigned long *supported, |
563 | const struct phylink_link_state *state, |
564 | phy_interface_t interface, |
565 | unsigned long *accum_supported, |
566 | unsigned long *accum_advertising) |
567 | { |
568 | __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp_supported); |
569 | struct phylink_link_state tmp_state; |
570 | |
571 | linkmode_copy(dst: tmp_supported, src: supported); |
572 | |
573 | tmp_state = *state; |
574 | tmp_state.interface = interface; |
575 | |
576 | if (phy) |
577 | tmp_state.rate_matching = phy_get_rate_matching(phydev: phy, iface: interface); |
578 | |
579 | if (!phylink_validate_mac_and_pcs(pl, supported: tmp_supported, state: &tmp_state)) { |
580 | phylink_dbg(pl, " interface %u (%s) rate match %s supports %*pbl\n", |
581 | interface, phy_modes(interface), |
582 | phy_rate_matching_to_str(tmp_state.rate_matching), |
583 | __ETHTOOL_LINK_MODE_MASK_NBITS, tmp_supported); |
584 | |
585 | linkmode_or(dst: accum_supported, a: accum_supported, b: tmp_supported); |
586 | linkmode_or(dst: accum_advertising, a: accum_advertising, |
587 | b: tmp_state.advertising); |
588 | } |
589 | } |
590 | |
591 | static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy, |
592 | unsigned long *supported, |
593 | struct phylink_link_state *state, |
594 | const unsigned long *interfaces) |
595 | { |
596 | __ETHTOOL_DECLARE_LINK_MODE_MASK(all_adv) = { 0, }; |
597 | __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, }; |
598 | int interface; |
599 | |
600 | for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX) |
601 | phylink_validate_one(pl, phy, supported, state, interface, |
602 | accum_supported: all_s, accum_advertising: all_adv); |
603 | |
604 | linkmode_copy(dst: supported, src: all_s); |
605 | linkmode_copy(dst: state->advertising, src: all_adv); |
606 | |
607 | return phylink_is_empty_linkmode(linkmode: supported) ? -EINVAL : 0; |
608 | } |
609 | |
610 | static int phylink_validate(struct phylink *pl, unsigned long *supported, |
611 | struct phylink_link_state *state) |
612 | { |
613 | const unsigned long *interfaces = pl->config->supported_interfaces; |
614 | |
615 | if (state->interface == PHY_INTERFACE_MODE_NA) |
616 | return phylink_validate_mask(pl, NULL, supported, state, |
617 | interfaces); |
618 | |
619 | if (!test_bit(state->interface, interfaces)) |
620 | return -EINVAL; |
621 | |
622 | return phylink_validate_mac_and_pcs(pl, supported, state); |
623 | } |
624 | |
625 | static void phylink_fill_fixedlink_supported(unsigned long *supported) |
626 | { |
627 | linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, supported); |
628 | linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, supported); |
629 | linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, supported); |
630 | linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, supported); |
631 | linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, supported); |
632 | linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, supported); |
633 | linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported); |
634 | linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, supported); |
635 | linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, supported); |
636 | } |
637 | |
638 | static int phylink_parse_fixedlink(struct phylink *pl, |
639 | const struct fwnode_handle *fwnode) |
640 | { |
641 | __ETHTOOL_DECLARE_LINK_MODE_MASK(match) = { 0, }; |
642 | __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; |
643 | const struct link_capabilities *c; |
644 | struct fwnode_handle *fixed_node; |
645 | struct gpio_desc *desc; |
646 | u32 speed; |
647 | int ret; |
648 | |
649 | fixed_node = fwnode_get_named_child_node(fwnode, childname: "fixed-link"); |
650 | if (fixed_node) { |
651 | ret = fwnode_property_read_u32(fwnode: fixed_node, propname: "speed", val: &speed); |
652 | |
653 | pl->link_config.speed = speed; |
654 | pl->link_config.duplex = DUPLEX_HALF; |
655 | |
656 | if (fwnode_property_read_bool(fwnode: fixed_node, propname: "full-duplex")) |
657 | pl->link_config.duplex = DUPLEX_FULL; |
658 | |
659 | /* We treat the "pause" and "asym-pause" terminology as |
660 | * defining the link partner's ability. |
661 | */ |
662 | if (fwnode_property_read_bool(fwnode: fixed_node, propname: "pause")) |
663 | __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
664 | pl->link_config.lp_advertising); |
665 | if (fwnode_property_read_bool(fwnode: fixed_node, propname: "asym-pause")) |
666 | __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
667 | pl->link_config.lp_advertising); |
668 | |
669 | if (ret == 0) { |
670 | desc = fwnode_gpiod_get_index(fwnode: fixed_node, con_id: "link", index: 0, |
671 | flags: GPIOD_IN, label: "?"); |
672 | |
673 | if (!IS_ERR(ptr: desc)) |
674 | pl->link_gpio = desc; |
675 | else if (desc == ERR_PTR(error: -EPROBE_DEFER)) |
676 | ret = -EPROBE_DEFER; |
677 | } |
678 | fwnode_handle_put(fwnode: fixed_node); |
679 | |
680 | if (ret) |
681 | return ret; |
682 | } else { |
683 | u32 prop[5]; |
684 | |
685 | ret = fwnode_property_read_u32_array(fwnode, propname: "fixed-link", |
686 | NULL, nval: 0); |
687 | if (ret != ARRAY_SIZE(prop)) { |
688 | phylink_err(pl, "broken fixed-link?\n"); |
689 | return -EINVAL; |
690 | } |
691 | |
692 | ret = fwnode_property_read_u32_array(fwnode, propname: "fixed-link", |
693 | val: prop, ARRAY_SIZE(prop)); |
694 | if (!ret) { |
695 | pl->link_config.duplex = prop[1] ? |
696 | DUPLEX_FULL : DUPLEX_HALF; |
697 | pl->link_config.speed = prop[2]; |
698 | if (prop[3]) |
699 | __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
700 | pl->link_config.lp_advertising); |
701 | if (prop[4]) |
702 | __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
703 | pl->link_config.lp_advertising); |
704 | } |
705 | } |
706 | |
707 | if (pl->link_config.speed > SPEED_1000 && |
708 | pl->link_config.duplex != DUPLEX_FULL) |
709 | phylink_warn(pl, "fixed link specifies half duplex for %dMbps link?\n", |
710 | pl->link_config.speed); |
711 | |
712 | linkmode_zero(dst: pl->supported); |
713 | phylink_fill_fixedlink_supported(supported: pl->supported); |
714 | |
715 | linkmode_copy(dst: pl->link_config.advertising, src: pl->supported); |
716 | phylink_validate(pl, supported: pl->supported, state: &pl->link_config); |
717 | |
718 | c = phy_caps_lookup(speed: pl->link_config.speed, duplex: pl->link_config.duplex, |
719 | supported: pl->supported, exact: true); |
720 | if (c) |
721 | linkmode_and(dst: match, a: pl->supported, b: c->linkmodes); |
722 | |
723 | linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, mask); |
724 | linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask); |
725 | linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask); |
726 | linkmode_and(dst: pl->supported, a: pl->supported, b: mask); |
727 | |
728 | phylink_set(pl->supported, MII); |
729 | |
730 | if (c) { |
731 | linkmode_or(dst: pl->supported, a: pl->supported, b: match); |
732 | linkmode_or(dst: pl->link_config.lp_advertising, |
733 | a: pl->link_config.lp_advertising, b: match); |
734 | } else { |
735 | phylink_warn(pl, "fixed link %s duplex %dMbps not recognised\n", |
736 | pl->link_config.duplex == DUPLEX_FULL ? "full": "half", |
737 | pl->link_config.speed); |
738 | } |
739 | |
740 | linkmode_and(dst: pl->link_config.advertising, a: pl->link_config.advertising, |
741 | b: pl->supported); |
742 | |
743 | pl->link_config.link = 1; |
744 | pl->link_config.an_complete = 1; |
745 | |
746 | return 0; |
747 | } |
748 | |
749 | static int phylink_parse_mode(struct phylink *pl, |
750 | const struct fwnode_handle *fwnode) |
751 | { |
752 | struct fwnode_handle *dn; |
753 | const char *managed; |
754 | unsigned long caps; |
755 | |
756 | if (pl->config->default_an_inband) |
757 | pl->cfg_link_an_mode = MLO_AN_INBAND; |
758 | |
759 | dn = fwnode_get_named_child_node(fwnode, childname: "fixed-link"); |
760 | if (dn || fwnode_property_present(fwnode, propname: "fixed-link")) |
761 | pl->cfg_link_an_mode = MLO_AN_FIXED; |
762 | fwnode_handle_put(fwnode: dn); |
763 | |
764 | if ((fwnode_property_read_string(fwnode, propname: "managed", val: &managed) == 0 && |
765 | strcmp(managed, "in-band-status") == 0)) { |
766 | if (pl->cfg_link_an_mode == MLO_AN_FIXED) { |
767 | phylink_err(pl, |
768 | "can't use both fixed-link and in-band-status\n"); |
769 | return -EINVAL; |
770 | } |
771 | |
772 | pl->cfg_link_an_mode = MLO_AN_INBAND; |
773 | } |
774 | |
775 | if (pl->cfg_link_an_mode == MLO_AN_INBAND) { |
776 | linkmode_zero(dst: pl->supported); |
777 | phylink_set(pl->supported, MII); |
778 | phylink_set(pl->supported, Autoneg); |
779 | phylink_set(pl->supported, Asym_Pause); |
780 | phylink_set(pl->supported, Pause); |
781 | |
782 | switch (pl->link_config.interface) { |
783 | case PHY_INTERFACE_MODE_SGMII: |
784 | case PHY_INTERFACE_MODE_PSGMII: |
785 | case PHY_INTERFACE_MODE_QSGMII: |
786 | case PHY_INTERFACE_MODE_QUSGMII: |
787 | case PHY_INTERFACE_MODE_RGMII: |
788 | case PHY_INTERFACE_MODE_RGMII_ID: |
789 | case PHY_INTERFACE_MODE_RGMII_RXID: |
790 | case PHY_INTERFACE_MODE_RGMII_TXID: |
791 | case PHY_INTERFACE_MODE_RTBI: |
792 | case PHY_INTERFACE_MODE_1000BASEX: |
793 | case PHY_INTERFACE_MODE_2500BASEX: |
794 | case PHY_INTERFACE_MODE_5GBASER: |
795 | case PHY_INTERFACE_MODE_25GBASER: |
796 | case PHY_INTERFACE_MODE_USXGMII: |
797 | case PHY_INTERFACE_MODE_10G_QXGMII: |
798 | case PHY_INTERFACE_MODE_10GKR: |
799 | case PHY_INTERFACE_MODE_10GBASER: |
800 | case PHY_INTERFACE_MODE_XLGMII: |
801 | caps = ~(MAC_SYM_PAUSE | MAC_ASYM_PAUSE); |
802 | caps = phylink_get_capabilities(interface: pl->link_config.interface, mac_capabilities: caps, |
803 | RATE_MATCH_NONE); |
804 | phylink_caps_to_linkmodes(linkmodes: pl->supported, caps); |
805 | break; |
806 | |
807 | default: |
808 | phylink_err(pl, |
809 | "incorrect link mode %s for in-band status\n", |
810 | phy_modes(pl->link_config.interface)); |
811 | return -EINVAL; |
812 | } |
813 | |
814 | linkmode_copy(dst: pl->link_config.advertising, src: pl->supported); |
815 | |
816 | if (phylink_validate(pl, supported: pl->supported, state: &pl->link_config)) { |
817 | phylink_err(pl, |
818 | "failed to validate link configuration for in-band status\n"); |
819 | return -EINVAL; |
820 | } |
821 | } |
822 | |
823 | return 0; |
824 | } |
825 | |
826 | static void phylink_apply_manual_flow(struct phylink *pl, |
827 | struct phylink_link_state *state) |
828 | { |
829 | /* If autoneg is disabled, pause AN is also disabled */ |
830 | if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, |
831 | state->advertising)) |
832 | state->pause &= ~MLO_PAUSE_AN; |
833 | |
834 | /* Manual configuration of pause modes */ |
835 | if (!(pl->link_config.pause & MLO_PAUSE_AN)) |
836 | state->pause = pl->link_config.pause; |
837 | } |
838 | |
839 | static void phylink_resolve_an_pause(struct phylink_link_state *state) |
840 | { |
841 | bool tx_pause, rx_pause; |
842 | |
843 | if (state->duplex == DUPLEX_FULL) { |
844 | linkmode_resolve_pause(local_adv: state->advertising, |
845 | partner_adv: state->lp_advertising, |
846 | tx_pause: &tx_pause, rx_pause: &rx_pause); |
847 | if (tx_pause) |
848 | state->pause |= MLO_PAUSE_TX; |
849 | if (rx_pause) |
850 | state->pause |= MLO_PAUSE_RX; |
851 | } |
852 | } |
853 | |
854 | static unsigned int phylink_pcs_inband_caps(struct phylink_pcs *pcs, |
855 | phy_interface_t interface) |
856 | { |
857 | if (pcs && pcs->ops->pcs_inband_caps) |
858 | return pcs->ops->pcs_inband_caps(pcs, interface); |
859 | |
860 | return 0; |
861 | } |
862 | |
863 | static void phylink_pcs_pre_config(struct phylink_pcs *pcs, |
864 | phy_interface_t interface) |
865 | { |
866 | if (pcs && pcs->ops->pcs_pre_config) |
867 | pcs->ops->pcs_pre_config(pcs, interface); |
868 | } |
869 | |
870 | static int phylink_pcs_post_config(struct phylink_pcs *pcs, |
871 | phy_interface_t interface) |
872 | { |
873 | int err = 0; |
874 | |
875 | if (pcs && pcs->ops->pcs_post_config) |
876 | err = pcs->ops->pcs_post_config(pcs, interface); |
877 | |
878 | return err; |
879 | } |
880 | |
881 | static void phylink_pcs_disable(struct phylink_pcs *pcs) |
882 | { |
883 | if (pcs && pcs->ops->pcs_disable) |
884 | pcs->ops->pcs_disable(pcs); |
885 | } |
886 | |
887 | static int phylink_pcs_enable(struct phylink_pcs *pcs) |
888 | { |
889 | int err = 0; |
890 | |
891 | if (pcs && pcs->ops->pcs_enable) |
892 | err = pcs->ops->pcs_enable(pcs); |
893 | |
894 | return err; |
895 | } |
896 | |
897 | static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, |
898 | const struct phylink_link_state *state, |
899 | bool permit_pause_to_mac) |
900 | { |
901 | if (!pcs) |
902 | return 0; |
903 | |
904 | return pcs->ops->pcs_config(pcs, neg_mode, state->interface, |
905 | state->advertising, permit_pause_to_mac); |
906 | } |
907 | |
908 | static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, |
909 | phy_interface_t interface, int speed, |
910 | int duplex) |
911 | { |
912 | if (pcs && pcs->ops->pcs_link_up) |
913 | pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); |
914 | } |
915 | |
916 | static void phylink_pcs_disable_eee(struct phylink_pcs *pcs) |
917 | { |
918 | if (pcs && pcs->ops->pcs_disable_eee) |
919 | pcs->ops->pcs_disable_eee(pcs); |
920 | } |
921 | |
922 | static void phylink_pcs_enable_eee(struct phylink_pcs *pcs) |
923 | { |
924 | if (pcs && pcs->ops->pcs_enable_eee) |
925 | pcs->ops->pcs_enable_eee(pcs); |
926 | } |
927 | |
928 | /* Query inband for a specific interface mode, asking the MAC for the |
929 | * PCS which will be used to handle the interface mode. |
930 | */ |
931 | static unsigned int phylink_inband_caps(struct phylink *pl, |
932 | phy_interface_t interface) |
933 | { |
934 | struct phylink_pcs *pcs; |
935 | |
936 | if (!pl->mac_ops->mac_select_pcs) |
937 | return 0; |
938 | |
939 | pcs = pl->mac_ops->mac_select_pcs(pl->config, interface); |
940 | if (!pcs) |
941 | return 0; |
942 | |
943 | return phylink_pcs_inband_caps(pcs, interface); |
944 | } |
945 | |
946 | static void phylink_pcs_poll_stop(struct phylink *pl) |
947 | { |
948 | if (pl->cfg_link_an_mode == MLO_AN_INBAND) |
949 | timer_delete(timer: &pl->link_poll); |
950 | } |
951 | |
952 | static void phylink_pcs_poll_start(struct phylink *pl) |
953 | { |
954 | if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) |
955 | mod_timer(timer: &pl->link_poll, expires: jiffies + HZ); |
956 | } |
957 | |
958 | int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs) |
959 | { |
960 | int ret = 0; |
961 | |
962 | /* Signal to PCS driver that MAC requires RX clock for init */ |
963 | if (pl->config->mac_requires_rxc) |
964 | pcs->rxc_always_on = true; |
965 | |
966 | if (pcs->ops->pcs_pre_init) |
967 | ret = pcs->ops->pcs_pre_init(pcs); |
968 | |
969 | return ret; |
970 | } |
971 | EXPORT_SYMBOL_GPL(phylink_pcs_pre_init); |
972 | |
973 | static void phylink_mac_config(struct phylink *pl, |
974 | const struct phylink_link_state *state) |
975 | { |
976 | struct phylink_link_state st = *state; |
977 | |
978 | /* Stop drivers incorrectly using these */ |
979 | linkmode_zero(dst: st.lp_advertising); |
980 | st.speed = SPEED_UNKNOWN; |
981 | st.duplex = DUPLEX_UNKNOWN; |
982 | st.an_complete = false; |
983 | st.link = false; |
984 | |
985 | phylink_dbg(pl, |
986 | "%s: mode=%s/%s/%s adv=%*pb pause=%02x\n", |
987 | __func__, phylink_an_mode_str(pl->act_link_an_mode), |
988 | phy_modes(st.interface), |
989 | phy_rate_matching_to_str(st.rate_matching), |
990 | __ETHTOOL_LINK_MODE_MASK_NBITS, st.advertising, |
991 | st.pause); |
992 | |
993 | pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st); |
994 | } |
995 | |
996 | static void phylink_pcs_an_restart(struct phylink *pl) |
997 | { |
998 | if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, |
999 | pl->link_config.advertising) && |
1000 | phy_interface_mode_is_8023z(mode: pl->link_config.interface) && |
1001 | phylink_autoneg_inband(mode: pl->act_link_an_mode)) |
1002 | pl->pcs->ops->pcs_an_restart(pl->pcs); |
1003 | } |
1004 | |
1005 | /** |
1006 | * phylink_pcs_neg_mode() - helper to determine PCS inband mode |
1007 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
1008 | * @pcs: a pointer to &struct phylink_pcs |
1009 | * @interface: interface mode to be used |
1010 | * @advertising: adertisement ethtool link mode mask |
1011 | * |
1012 | * Determines the negotiation mode to be used by the PCS, and returns |
1013 | * one of: |
1014 | * |
1015 | * - %PHYLINK_PCS_NEG_NONE: interface mode does not support inband |
1016 | * - %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY) |
1017 | * will be used. |
1018 | * - %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg |
1019 | * disabled |
1020 | * - %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled |
1021 | * |
1022 | * Note: this is for cases where the PCS itself is involved in negotiation |
1023 | * (e.g. Clause 37, SGMII and similar) not Clause 73. |
1024 | */ |
1025 | static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, |
1026 | phy_interface_t interface, |
1027 | const unsigned long *advertising) |
1028 | { |
1029 | unsigned int pcs_ib_caps = 0; |
1030 | unsigned int phy_ib_caps = 0; |
1031 | unsigned int neg_mode, mode; |
1032 | enum { |
1033 | INBAND_CISCO_SGMII, |
1034 | INBAND_BASEX, |
1035 | } type; |
1036 | |
1037 | mode = pl->req_link_an_mode; |
1038 | |
1039 | pl->phy_ib_mode = 0; |
1040 | |
1041 | switch (interface) { |
1042 | case PHY_INTERFACE_MODE_SGMII: |
1043 | case PHY_INTERFACE_MODE_QSGMII: |
1044 | case PHY_INTERFACE_MODE_QUSGMII: |
1045 | case PHY_INTERFACE_MODE_USXGMII: |
1046 | case PHY_INTERFACE_MODE_10G_QXGMII: |
1047 | /* These protocols are designed for use with a PHY which |
1048 | * communicates its negotiation result back to the MAC via |
1049 | * inband communication. Note: there exist PHYs that run |
1050 | * with SGMII but do not send the inband data. |
1051 | */ |
1052 | type = INBAND_CISCO_SGMII; |
1053 | break; |
1054 | |
1055 | case PHY_INTERFACE_MODE_1000BASEX: |
1056 | case PHY_INTERFACE_MODE_2500BASEX: |
1057 | /* 1000base-X is designed for use media-side for Fibre |
1058 | * connections, and thus the Autoneg bit needs to be |
1059 | * taken into account. We also do this for 2500base-X |
1060 | * as well, but drivers may not support this, so may |
1061 | * need to override this. |
1062 | */ |
1063 | type = INBAND_BASEX; |
1064 | break; |
1065 | |
1066 | default: |
1067 | pl->pcs_neg_mode = PHYLINK_PCS_NEG_NONE; |
1068 | pl->act_link_an_mode = mode; |
1069 | return; |
1070 | } |
1071 | |
1072 | if (pcs) |
1073 | pcs_ib_caps = phylink_pcs_inband_caps(pcs, interface); |
1074 | |
1075 | if (pl->phydev) |
1076 | phy_ib_caps = phy_inband_caps(phydev: pl->phydev, interface); |
1077 | |
1078 | phylink_dbg(pl, "interface %s inband modes: pcs=%02x phy=%02x\n", |
1079 | phy_modes(interface), pcs_ib_caps, phy_ib_caps); |
1080 | |
1081 | if (!phylink_autoneg_inband(mode)) { |
1082 | bool pcs_ib_only = false; |
1083 | bool phy_ib_only = false; |
1084 | |
1085 | if (pcs_ib_caps && pcs_ib_caps != LINK_INBAND_DISABLE) { |
1086 | /* PCS supports reporting in-band capabilities, and |
1087 | * supports more than disable mode. |
1088 | */ |
1089 | if (pcs_ib_caps & LINK_INBAND_DISABLE) |
1090 | neg_mode = PHYLINK_PCS_NEG_OUTBAND; |
1091 | else if (pcs_ib_caps & LINK_INBAND_ENABLE) |
1092 | pcs_ib_only = true; |
1093 | } |
1094 | |
1095 | if (phy_ib_caps && phy_ib_caps != LINK_INBAND_DISABLE) { |
1096 | /* PHY supports in-band capabilities, and supports |
1097 | * more than disable mode. |
1098 | */ |
1099 | if (phy_ib_caps & LINK_INBAND_DISABLE) |
1100 | pl->phy_ib_mode = LINK_INBAND_DISABLE; |
1101 | else if (phy_ib_caps & LINK_INBAND_BYPASS) |
1102 | pl->phy_ib_mode = LINK_INBAND_BYPASS; |
1103 | else if (phy_ib_caps & LINK_INBAND_ENABLE) |
1104 | phy_ib_only = true; |
1105 | } |
1106 | |
1107 | /* If either the PCS or PHY requires inband to be enabled, |
1108 | * this is an invalid configuration. Provide a diagnostic |
1109 | * message for this case, but don't try to force the issue. |
1110 | */ |
1111 | if (pcs_ib_only || phy_ib_only) |
1112 | phylink_warn(pl, |
1113 | "firmware wants %s mode, but %s%s%s requires inband\n", |
1114 | phylink_an_mode_str(mode), |
1115 | pcs_ib_only ? "PCS": "", |
1116 | pcs_ib_only && phy_ib_only ? " and ": "", |
1117 | phy_ib_only ? "PHY": ""); |
1118 | |
1119 | neg_mode = PHYLINK_PCS_NEG_OUTBAND; |
1120 | } else if (type == INBAND_CISCO_SGMII || pl->phydev) { |
1121 | /* For SGMII modes which are designed to be used with PHYs, or |
1122 | * Base-X with a PHY, we try to use in-band mode where-ever |
1123 | * possible. However, there are some PHYs e.g. BCM84881 which |
1124 | * do not support in-band. |
1125 | */ |
1126 | const unsigned int inband_ok = LINK_INBAND_ENABLE | |
1127 | LINK_INBAND_BYPASS; |
1128 | const unsigned int outband_ok = LINK_INBAND_DISABLE | |
1129 | LINK_INBAND_BYPASS; |
1130 | /* PCS PHY |
1131 | * D E D E |
1132 | * 0 0 0 0 no information inband enabled |
1133 | * 1 0 0 0 pcs doesn't support outband |
1134 | * 0 1 0 0 pcs required inband enabled |
1135 | * 1 1 0 0 pcs optional inband enabled |
1136 | * 0 0 1 0 phy doesn't support outband |
1137 | * 1 0 1 0 pcs+phy doesn't support outband |
1138 | * 0 1 1 0 pcs required, phy doesn't support, invalid |
1139 | * 1 1 1 0 pcs optional, phy doesn't support, outband |
1140 | * 0 0 0 1 phy required inband enabled |
1141 | * 1 0 0 1 pcs doesn't support, phy required, invalid |
1142 | * 0 1 0 1 pcs+phy required inband enabled |
1143 | * 1 1 0 1 pcs optional, phy required inband enabled |
1144 | * 0 0 1 1 phy optional inband enabled |
1145 | * 1 0 1 1 pcs doesn't support, phy optional, outband |
1146 | * 0 1 1 1 pcs required, phy optional inband enabled |
1147 | * 1 1 1 1 pcs+phy optional inband enabled |
1148 | */ |
1149 | if ((!pcs_ib_caps || pcs_ib_caps & inband_ok) && |
1150 | (!phy_ib_caps || phy_ib_caps & inband_ok)) { |
1151 | /* In-band supported or unknown at both ends. Enable |
1152 | * in-band mode with or without bypass at the PHY. |
1153 | */ |
1154 | if (phy_ib_caps & LINK_INBAND_ENABLE) |
1155 | pl->phy_ib_mode = LINK_INBAND_ENABLE; |
1156 | else if (phy_ib_caps & LINK_INBAND_BYPASS) |
1157 | pl->phy_ib_mode = LINK_INBAND_BYPASS; |
1158 | |
1159 | neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; |
1160 | } else if ((!pcs_ib_caps || pcs_ib_caps & outband_ok) && |
1161 | (!phy_ib_caps || phy_ib_caps & outband_ok)) { |
1162 | /* Either in-band not supported at at least one end. |
1163 | * In-band bypass at the other end is possible. |
1164 | */ |
1165 | if (phy_ib_caps & LINK_INBAND_DISABLE) |
1166 | pl->phy_ib_mode = LINK_INBAND_DISABLE; |
1167 | else if (phy_ib_caps & LINK_INBAND_BYPASS) |
1168 | pl->phy_ib_mode = LINK_INBAND_BYPASS; |
1169 | |
1170 | neg_mode = PHYLINK_PCS_NEG_OUTBAND; |
1171 | if (pl->phydev) |
1172 | mode = MLO_AN_PHY; |
1173 | } else { |
1174 | /* invalid */ |
1175 | phylink_warn(pl, "%s: incompatible in-band capabilities, trying in-band", |
1176 | phy_modes(interface)); |
1177 | neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; |
1178 | } |
1179 | } else { |
1180 | /* For Base-X without a PHY */ |
1181 | if (pcs_ib_caps == LINK_INBAND_DISABLE) |
1182 | /* If the PCS doesn't support inband, then inband must |
1183 | * be disabled. |
1184 | */ |
1185 | neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED; |
1186 | else if (pcs_ib_caps == LINK_INBAND_ENABLE) |
1187 | /* If the PCS requires inband, then inband must always |
1188 | * be enabled. |
1189 | */ |
1190 | neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; |
1191 | else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, |
1192 | advertising)) |
1193 | neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; |
1194 | else |
1195 | neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED; |
1196 | } |
1197 | |
1198 | pl->pcs_neg_mode = neg_mode; |
1199 | pl->act_link_an_mode = mode; |
1200 | } |
1201 | |
1202 | static void phylink_major_config(struct phylink *pl, bool restart, |
1203 | const struct phylink_link_state *state) |
1204 | { |
1205 | struct phylink_pcs *pcs = NULL; |
1206 | bool pcs_changed = false; |
1207 | unsigned int rate_kbd; |
1208 | int err; |
1209 | |
1210 | phylink_dbg(pl, "major config, requested %s/%s\n", |
1211 | phylink_an_mode_str(pl->req_link_an_mode), |
1212 | phy_modes(state->interface)); |
1213 | |
1214 | pl->major_config_failed = false; |
1215 | |
1216 | if (pl->mac_ops->mac_select_pcs) { |
1217 | pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); |
1218 | if (IS_ERR(ptr: pcs)) { |
1219 | phylink_err(pl, |
1220 | "mac_select_pcs unexpectedly failed: %pe\n", |
1221 | pcs); |
1222 | |
1223 | pl->major_config_failed = true; |
1224 | return; |
1225 | } |
1226 | |
1227 | pcs_changed = pl->pcs != pcs; |
1228 | } |
1229 | |
1230 | phylink_pcs_neg_mode(pl, pcs, interface: state->interface, advertising: state->advertising); |
1231 | |
1232 | phylink_dbg(pl, "major config, active %s/%s/%s\n", |
1233 | phylink_an_mode_str(pl->act_link_an_mode), |
1234 | phylink_pcs_mode_str(pl->pcs_neg_mode), |
1235 | phy_modes(state->interface)); |
1236 | |
1237 | phylink_pcs_poll_stop(pl); |
1238 | |
1239 | if (pl->mac_ops->mac_prepare) { |
1240 | err = pl->mac_ops->mac_prepare(pl->config, pl->act_link_an_mode, |
1241 | state->interface); |
1242 | if (err < 0) { |
1243 | phylink_err(pl, "mac_prepare failed: %pe\n", |
1244 | ERR_PTR(err)); |
1245 | pl->major_config_failed = true; |
1246 | return; |
1247 | } |
1248 | } |
1249 | |
1250 | /* If we have a new PCS, switch to the new PCS after preparing the MAC |
1251 | * for the change. |
1252 | */ |
1253 | if (pcs_changed) { |
1254 | phylink_pcs_disable(pcs: pl->pcs); |
1255 | |
1256 | if (pl->pcs) |
1257 | pl->pcs->phylink = NULL; |
1258 | |
1259 | pcs->phylink = pl; |
1260 | |
1261 | pl->pcs = pcs; |
1262 | } |
1263 | |
1264 | if (pl->pcs) |
1265 | phylink_pcs_pre_config(pcs: pl->pcs, interface: state->interface); |
1266 | |
1267 | phylink_mac_config(pl, state); |
1268 | |
1269 | if (pl->pcs) { |
1270 | err = phylink_pcs_post_config(pcs: pl->pcs, interface: state->interface); |
1271 | if (err < 0) { |
1272 | phylink_err(pl, "pcs_post_config failed: %pe\n", |
1273 | ERR_PTR(err)); |
1274 | |
1275 | pl->major_config_failed = true; |
1276 | } |
1277 | } |
1278 | |
1279 | if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) |
1280 | phylink_pcs_enable(pcs: pl->pcs); |
1281 | |
1282 | err = phylink_pcs_config(pcs: pl->pcs, neg_mode: pl->pcs_neg_mode, state, |
1283 | permit_pause_to_mac: !!(pl->link_config.pause & MLO_PAUSE_AN)); |
1284 | if (err < 0) { |
1285 | phylink_err(pl, "pcs_config failed: %pe\n", ERR_PTR(err)); |
1286 | pl->major_config_failed = true; |
1287 | } else if (err > 0) { |
1288 | restart = true; |
1289 | } |
1290 | |
1291 | if (restart) |
1292 | phylink_pcs_an_restart(pl); |
1293 | |
1294 | if (pl->mac_ops->mac_finish) { |
1295 | err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode, |
1296 | state->interface); |
1297 | if (err < 0) { |
1298 | phylink_err(pl, "mac_finish failed: %pe\n", |
1299 | ERR_PTR(err)); |
1300 | |
1301 | pl->major_config_failed = true; |
1302 | } |
1303 | } |
1304 | |
1305 | if (pl->phydev && pl->phy_ib_mode) { |
1306 | err = phy_config_inband(phydev: pl->phydev, modes: pl->phy_ib_mode); |
1307 | if (err < 0) { |
1308 | phylink_err(pl, "phy_config_inband: %pe\n", |
1309 | ERR_PTR(err)); |
1310 | |
1311 | pl->major_config_failed = true; |
1312 | } |
1313 | } |
1314 | |
1315 | if (pl->sfp_bus) { |
1316 | rate_kbd = phylink_interface_signal_rate(interface: state->interface); |
1317 | if (rate_kbd) |
1318 | sfp_upstream_set_signal_rate(bus: pl->sfp_bus, rate_kbd); |
1319 | } |
1320 | |
1321 | phylink_pcs_poll_start(pl); |
1322 | } |
1323 | |
1324 | /* |
1325 | * Reconfigure for a change of inband advertisement. |
1326 | * If we have a separate PCS, we only need to call its pcs_config() method, |
1327 | * and then restart AN if it indicates something changed. Otherwise, we do |
1328 | * the full MAC reconfiguration. |
1329 | */ |
1330 | static int phylink_change_inband_advert(struct phylink *pl) |
1331 | { |
1332 | int ret; |
1333 | |
1334 | if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) |
1335 | return 0; |
1336 | |
1337 | phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__, |
1338 | phylink_an_mode_str(pl->req_link_an_mode), |
1339 | phy_modes(pl->link_config.interface), |
1340 | __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, |
1341 | pl->link_config.pause); |
1342 | |
1343 | /* Recompute the PCS neg mode */ |
1344 | phylink_pcs_neg_mode(pl, pcs: pl->pcs, interface: pl->link_config.interface, |
1345 | advertising: pl->link_config.advertising); |
1346 | |
1347 | /* Modern PCS-based method; update the advert at the PCS, and |
1348 | * restart negotiation if the pcs_config() helper indicates that |
1349 | * the programmed advertisement has changed. |
1350 | */ |
1351 | ret = phylink_pcs_config(pcs: pl->pcs, neg_mode: pl->pcs_neg_mode, state: &pl->link_config, |
1352 | permit_pause_to_mac: !!(pl->link_config.pause & MLO_PAUSE_AN)); |
1353 | if (ret < 0) |
1354 | return ret; |
1355 | |
1356 | if (ret > 0) |
1357 | phylink_pcs_an_restart(pl); |
1358 | |
1359 | return 0; |
1360 | } |
1361 | |
1362 | static void phylink_mac_pcs_get_state(struct phylink *pl, |
1363 | struct phylink_link_state *state) |
1364 | { |
1365 | struct phylink_pcs *pcs; |
1366 | bool autoneg; |
1367 | |
1368 | linkmode_copy(dst: state->advertising, src: pl->link_config.advertising); |
1369 | linkmode_zero(dst: state->lp_advertising); |
1370 | state->interface = pl->link_config.interface; |
1371 | state->rate_matching = pl->link_config.rate_matching; |
1372 | state->an_complete = 0; |
1373 | state->link = 1; |
1374 | |
1375 | autoneg = pl->pcs_neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED; |
1376 | if (autoneg) { |
1377 | state->speed = SPEED_UNKNOWN; |
1378 | state->duplex = DUPLEX_UNKNOWN; |
1379 | state->pause = MLO_PAUSE_NONE; |
1380 | } else { |
1381 | state->speed = pl->link_config.speed; |
1382 | state->duplex = pl->link_config.duplex; |
1383 | state->pause = pl->link_config.pause; |
1384 | } |
1385 | |
1386 | pcs = pl->pcs; |
1387 | if (pcs) |
1388 | pcs->ops->pcs_get_state(pcs, pl->pcs_neg_mode, state); |
1389 | else |
1390 | state->link = 0; |
1391 | } |
1392 | |
1393 | /* The fixed state is... fixed except for the link state, |
1394 | * which may be determined by a GPIO or a callback. |
1395 | */ |
1396 | static void phylink_get_fixed_state(struct phylink *pl, |
1397 | struct phylink_link_state *state) |
1398 | { |
1399 | *state = pl->link_config; |
1400 | if (pl->config->get_fixed_state) |
1401 | pl->config->get_fixed_state(pl->config, state); |
1402 | else if (pl->link_gpio) |
1403 | state->link = !!gpiod_get_value_cansleep(desc: pl->link_gpio); |
1404 | |
1405 | state->pause = MLO_PAUSE_NONE; |
1406 | phylink_resolve_an_pause(state); |
1407 | } |
1408 | |
1409 | static void phylink_mac_initial_config(struct phylink *pl, bool force_restart) |
1410 | { |
1411 | struct phylink_link_state link_state; |
1412 | |
1413 | switch (pl->req_link_an_mode) { |
1414 | case MLO_AN_PHY: |
1415 | link_state = pl->phy_state; |
1416 | break; |
1417 | |
1418 | case MLO_AN_FIXED: |
1419 | phylink_get_fixed_state(pl, state: &link_state); |
1420 | break; |
1421 | |
1422 | case MLO_AN_INBAND: |
1423 | link_state = pl->link_config; |
1424 | if (link_state.interface == PHY_INTERFACE_MODE_SGMII) |
1425 | link_state.pause = MLO_PAUSE_NONE; |
1426 | break; |
1427 | |
1428 | default: /* can't happen */ |
1429 | return; |
1430 | } |
1431 | |
1432 | link_state.link = false; |
1433 | |
1434 | phylink_apply_manual_flow(pl, state: &link_state); |
1435 | phylink_major_config(pl, restart: force_restart, state: &link_state); |
1436 | } |
1437 | |
1438 | static const char *phylink_pause_to_str(int pause) |
1439 | { |
1440 | switch (pause & MLO_PAUSE_TXRX_MASK) { |
1441 | case MLO_PAUSE_TX | MLO_PAUSE_RX: |
1442 | return "rx/tx"; |
1443 | case MLO_PAUSE_TX: |
1444 | return "tx"; |
1445 | case MLO_PAUSE_RX: |
1446 | return "rx"; |
1447 | default: |
1448 | return "off"; |
1449 | } |
1450 | } |
1451 | |
1452 | static void phylink_deactivate_lpi(struct phylink *pl) |
1453 | { |
1454 | if (pl->mac_enable_tx_lpi) { |
1455 | pl->mac_enable_tx_lpi = false; |
1456 | |
1457 | phylink_dbg(pl, "disabling LPI\n"); |
1458 | |
1459 | pl->mac_ops->mac_disable_tx_lpi(pl->config); |
1460 | |
1461 | phylink_pcs_disable_eee(pcs: pl->pcs); |
1462 | } |
1463 | } |
1464 | |
1465 | static void phylink_activate_lpi(struct phylink *pl) |
1466 | { |
1467 | int err; |
1468 | |
1469 | if (!test_bit(pl->cur_interface, pl->config->lpi_interfaces)) { |
1470 | phylink_dbg(pl, "MAC does not support LPI with %s\n", |
1471 | phy_modes(pl->cur_interface)); |
1472 | return; |
1473 | } |
1474 | |
1475 | phylink_dbg(pl, "LPI timer %uus, tx clock stop %u\n", |
1476 | pl->mac_tx_lpi_timer, pl->mac_tx_clk_stop); |
1477 | |
1478 | phylink_pcs_enable_eee(pcs: pl->pcs); |
1479 | |
1480 | err = pl->mac_ops->mac_enable_tx_lpi(pl->config, pl->mac_tx_lpi_timer, |
1481 | pl->mac_tx_clk_stop); |
1482 | if (err) { |
1483 | phylink_pcs_disable_eee(pcs: pl->pcs); |
1484 | phylink_err(pl, "%ps() failed: %pe\n", |
1485 | pl->mac_ops->mac_enable_tx_lpi, ERR_PTR(err)); |
1486 | return; |
1487 | } |
1488 | |
1489 | pl->mac_enable_tx_lpi = true; |
1490 | } |
1491 | |
1492 | static void phylink_link_up(struct phylink *pl, |
1493 | struct phylink_link_state link_state) |
1494 | { |
1495 | struct net_device *ndev = pl->netdev; |
1496 | int speed, duplex; |
1497 | bool rx_pause; |
1498 | |
1499 | speed = link_state.speed; |
1500 | duplex = link_state.duplex; |
1501 | rx_pause = !!(link_state.pause & MLO_PAUSE_RX); |
1502 | |
1503 | switch (link_state.rate_matching) { |
1504 | case RATE_MATCH_PAUSE: |
1505 | /* The PHY is doing rate matchion from the media rate (in |
1506 | * the link_state) to the interface speed, and will send |
1507 | * pause frames to the MAC to limit its transmission speed. |
1508 | */ |
1509 | speed = phylink_interface_max_speed(interface: link_state.interface); |
1510 | duplex = DUPLEX_FULL; |
1511 | rx_pause = true; |
1512 | break; |
1513 | |
1514 | case RATE_MATCH_CRS: |
1515 | /* The PHY is doing rate matchion from the media rate (in |
1516 | * the link_state) to the interface speed, and will cause |
1517 | * collisions to the MAC to limit its transmission speed. |
1518 | */ |
1519 | speed = phylink_interface_max_speed(interface: link_state.interface); |
1520 | duplex = DUPLEX_HALF; |
1521 | break; |
1522 | } |
1523 | |
1524 | pl->cur_interface = link_state.interface; |
1525 | |
1526 | phylink_pcs_link_up(pcs: pl->pcs, neg_mode: pl->pcs_neg_mode, interface: pl->cur_interface, speed, |
1527 | duplex); |
1528 | |
1529 | pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode, |
1530 | pl->cur_interface, speed, duplex, |
1531 | !!(link_state.pause & MLO_PAUSE_TX), rx_pause); |
1532 | |
1533 | if (pl->mac_supports_eee && pl->phy_enable_tx_lpi) |
1534 | phylink_activate_lpi(pl); |
1535 | |
1536 | if (ndev) |
1537 | netif_carrier_on(dev: ndev); |
1538 | |
1539 | phylink_info(pl, |
1540 | "Link is Up - %s/%s - flow control %s\n", |
1541 | phy_speed_to_str(link_state.speed), |
1542 | phy_duplex_to_str(link_state.duplex), |
1543 | phylink_pause_to_str(link_state.pause)); |
1544 | } |
1545 | |
1546 | static void phylink_link_down(struct phylink *pl) |
1547 | { |
1548 | struct net_device *ndev = pl->netdev; |
1549 | |
1550 | if (ndev) |
1551 | netif_carrier_off(dev: ndev); |
1552 | |
1553 | phylink_deactivate_lpi(pl); |
1554 | |
1555 | pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode, |
1556 | pl->cur_interface); |
1557 | phylink_info(pl, "Link is Down\n"); |
1558 | } |
1559 | |
1560 | static bool phylink_link_is_up(struct phylink *pl) |
1561 | { |
1562 | return pl->netdev ? netif_carrier_ok(dev: pl->netdev) : pl->old_link_state; |
1563 | } |
1564 | |
1565 | static void phylink_resolve(struct work_struct *w) |
1566 | { |
1567 | struct phylink *pl = container_of(w, struct phylink, resolve); |
1568 | struct phylink_link_state link_state; |
1569 | bool mac_config = false; |
1570 | bool retrigger = false; |
1571 | bool cur_link_state; |
1572 | |
1573 | mutex_lock(&pl->state_mutex); |
1574 | cur_link_state = phylink_link_is_up(pl); |
1575 | |
1576 | if (pl->phylink_disable_state) { |
1577 | pl->link_failed = false; |
1578 | link_state.link = false; |
1579 | } else if (pl->link_failed) { |
1580 | link_state.link = false; |
1581 | retrigger = true; |
1582 | } else if (pl->act_link_an_mode == MLO_AN_FIXED) { |
1583 | phylink_get_fixed_state(pl, state: &link_state); |
1584 | mac_config = link_state.link; |
1585 | } else if (pl->act_link_an_mode == MLO_AN_PHY) { |
1586 | link_state = pl->phy_state; |
1587 | mac_config = link_state.link; |
1588 | } else { |
1589 | phylink_mac_pcs_get_state(pl, state: &link_state); |
1590 | |
1591 | /* The PCS may have a latching link-fail indicator. If the link |
1592 | * was up, bring the link down and re-trigger the resolve. |
1593 | * Otherwise, re-read the PCS state to get the current status |
1594 | * of the link. |
1595 | */ |
1596 | if (!link_state.link) { |
1597 | if (cur_link_state) |
1598 | retrigger = true; |
1599 | else |
1600 | phylink_mac_pcs_get_state(pl, state: &link_state); |
1601 | } |
1602 | |
1603 | /* If we have a phy, the "up" state is the union of both the |
1604 | * PHY and the MAC |
1605 | */ |
1606 | if (pl->phydev) |
1607 | link_state.link &= pl->phy_state.link; |
1608 | |
1609 | /* Only update if the PHY link is up */ |
1610 | if (pl->phydev && pl->phy_state.link) { |
1611 | /* If the interface has changed, force a link down |
1612 | * event if the link isn't already down, and re-resolve. |
1613 | */ |
1614 | if (link_state.interface != pl->phy_state.interface) { |
1615 | retrigger = true; |
1616 | link_state.link = false; |
1617 | } |
1618 | |
1619 | link_state.interface = pl->phy_state.interface; |
1620 | |
1621 | /* If we are doing rate matching, then the link |
1622 | * speed/duplex comes from the PHY |
1623 | */ |
1624 | if (pl->phy_state.rate_matching) { |
1625 | link_state.rate_matching = |
1626 | pl->phy_state.rate_matching; |
1627 | link_state.speed = pl->phy_state.speed; |
1628 | link_state.duplex = pl->phy_state.duplex; |
1629 | } |
1630 | |
1631 | /* If we have a PHY, we need to update with the PHY |
1632 | * flow control bits. |
1633 | */ |
1634 | link_state.pause = pl->phy_state.pause; |
1635 | mac_config = true; |
1636 | } |
1637 | } |
1638 | |
1639 | if (pl->act_link_an_mode != MLO_AN_FIXED) |
1640 | phylink_apply_manual_flow(pl, state: &link_state); |
1641 | |
1642 | if (mac_config) { |
1643 | if (link_state.interface != pl->link_config.interface) { |
1644 | /* The interface has changed, force the link down and |
1645 | * then reconfigure. |
1646 | */ |
1647 | if (cur_link_state) { |
1648 | phylink_link_down(pl); |
1649 | cur_link_state = false; |
1650 | } |
1651 | phylink_major_config(pl, restart: false, state: &link_state); |
1652 | pl->link_config.interface = link_state.interface; |
1653 | } |
1654 | } |
1655 | |
1656 | /* If configuration of the interface failed, force the link down |
1657 | * until we get a successful configuration. |
1658 | */ |
1659 | if (pl->major_config_failed) |
1660 | link_state.link = false; |
1661 | |
1662 | if (link_state.link != cur_link_state) { |
1663 | pl->old_link_state = link_state.link; |
1664 | if (!link_state.link) |
1665 | phylink_link_down(pl); |
1666 | else |
1667 | phylink_link_up(pl, link_state); |
1668 | } |
1669 | if (!link_state.link && retrigger) { |
1670 | pl->link_failed = false; |
1671 | queue_work(wq: system_power_efficient_wq, work: &pl->resolve); |
1672 | } |
1673 | mutex_unlock(lock: &pl->state_mutex); |
1674 | } |
1675 | |
1676 | static void phylink_run_resolve(struct phylink *pl) |
1677 | { |
1678 | if (!pl->phylink_disable_state) |
1679 | queue_work(wq: system_power_efficient_wq, work: &pl->resolve); |
1680 | } |
1681 | |
1682 | static void phylink_run_resolve_and_disable(struct phylink *pl, int bit) |
1683 | { |
1684 | unsigned long state = pl->phylink_disable_state; |
1685 | |
1686 | set_bit(nr: bit, addr: &pl->phylink_disable_state); |
1687 | if (state == 0) { |
1688 | queue_work(wq: system_power_efficient_wq, work: &pl->resolve); |
1689 | flush_work(work: &pl->resolve); |
1690 | } |
1691 | } |
1692 | |
1693 | static void phylink_enable_and_run_resolve(struct phylink *pl, int bit) |
1694 | { |
1695 | clear_bit(nr: bit, addr: &pl->phylink_disable_state); |
1696 | phylink_run_resolve(pl); |
1697 | } |
1698 | |
1699 | static void phylink_fixed_poll(struct timer_list *t) |
1700 | { |
1701 | struct phylink *pl = container_of(t, struct phylink, link_poll); |
1702 | |
1703 | mod_timer(timer: t, expires: jiffies + HZ); |
1704 | |
1705 | phylink_run_resolve(pl); |
1706 | } |
1707 | |
1708 | static const struct sfp_upstream_ops sfp_phylink_ops; |
1709 | |
1710 | static int phylink_register_sfp(struct phylink *pl, |
1711 | const struct fwnode_handle *fwnode) |
1712 | { |
1713 | struct sfp_bus *bus; |
1714 | int ret; |
1715 | |
1716 | if (!fwnode) |
1717 | return 0; |
1718 | |
1719 | bus = sfp_bus_find_fwnode(fwnode); |
1720 | if (IS_ERR(ptr: bus)) { |
1721 | phylink_err(pl, "unable to attach SFP bus: %pe\n", bus); |
1722 | return PTR_ERR(ptr: bus); |
1723 | } |
1724 | |
1725 | pl->sfp_bus = bus; |
1726 | |
1727 | ret = sfp_bus_add_upstream(bus, upstream: pl, ops: &sfp_phylink_ops); |
1728 | sfp_bus_put(bus); |
1729 | |
1730 | return ret; |
1731 | } |
1732 | |
1733 | /** |
1734 | * phylink_set_fixed_link() - set the fixed link |
1735 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
1736 | * @state: a pointer to a struct phylink_link_state. |
1737 | * |
1738 | * This function is used when the link parameters are known and do not change, |
1739 | * making it suitable for certain types of network connections. |
1740 | * |
1741 | * Returns: zero on success or negative error code. |
1742 | */ |
1743 | int phylink_set_fixed_link(struct phylink *pl, |
1744 | const struct phylink_link_state *state) |
1745 | { |
1746 | const struct link_capabilities *c; |
1747 | unsigned long *adv; |
1748 | |
1749 | if (pl->cfg_link_an_mode != MLO_AN_PHY || !state || |
1750 | !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) |
1751 | return -EINVAL; |
1752 | |
1753 | c = phy_caps_lookup(speed: state->speed, duplex: state->duplex, |
1754 | supported: pl->supported, exact: true); |
1755 | if (!c) |
1756 | return -EINVAL; |
1757 | |
1758 | adv = pl->link_config.advertising; |
1759 | linkmode_and(dst: adv, a: pl->supported, b: c->linkmodes); |
1760 | linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, adv); |
1761 | |
1762 | pl->link_config.speed = state->speed; |
1763 | pl->link_config.duplex = state->duplex; |
1764 | pl->link_config.link = 1; |
1765 | pl->link_config.an_complete = 1; |
1766 | |
1767 | pl->cfg_link_an_mode = MLO_AN_FIXED; |
1768 | pl->req_link_an_mode = pl->cfg_link_an_mode; |
1769 | |
1770 | return 0; |
1771 | } |
1772 | EXPORT_SYMBOL_GPL(phylink_set_fixed_link); |
1773 | |
1774 | /** |
1775 | * phylink_create() - create a phylink instance |
1776 | * @config: a pointer to the target &struct phylink_config |
1777 | * @fwnode: a pointer to a &struct fwnode_handle describing the network |
1778 | * interface |
1779 | * @iface: the desired link mode defined by &typedef phy_interface_t |
1780 | * @mac_ops: a pointer to a &struct phylink_mac_ops for the MAC. |
1781 | * |
1782 | * Create a new phylink instance, and parse the link parameters found in @np. |
1783 | * This will parse in-band modes, fixed-link or SFP configuration. |
1784 | * |
1785 | * Note: the rtnl lock must not be held when calling this function. |
1786 | * |
1787 | * Returns a pointer to a &struct phylink, or an error-pointer value. Users |
1788 | * must use IS_ERR() to check for errors from this function. |
1789 | */ |
1790 | struct phylink *phylink_create(struct phylink_config *config, |
1791 | const struct fwnode_handle *fwnode, |
1792 | phy_interface_t iface, |
1793 | const struct phylink_mac_ops *mac_ops) |
1794 | { |
1795 | struct phylink *pl; |
1796 | int ret; |
1797 | |
1798 | /* Validate the supplied configuration */ |
1799 | if (phy_interface_empty(intf: config->supported_interfaces)) { |
1800 | dev_err(config->dev, |
1801 | "phylink: error: empty supported_interfaces\n"); |
1802 | return ERR_PTR(error: -EINVAL); |
1803 | } |
1804 | |
1805 | pl = kzalloc(sizeof(*pl), GFP_KERNEL); |
1806 | if (!pl) |
1807 | return ERR_PTR(error: -ENOMEM); |
1808 | |
1809 | mutex_init(&pl->state_mutex); |
1810 | INIT_WORK(&pl->resolve, phylink_resolve); |
1811 | |
1812 | pl->config = config; |
1813 | if (config->type == PHYLINK_NETDEV) { |
1814 | pl->netdev = to_net_dev(config->dev); |
1815 | netif_carrier_off(dev: pl->netdev); |
1816 | } else if (config->type == PHYLINK_DEV) { |
1817 | pl->dev = config->dev; |
1818 | } else { |
1819 | kfree(objp: pl); |
1820 | return ERR_PTR(error: -EINVAL); |
1821 | } |
1822 | |
1823 | pl->mac_supports_eee_ops = phylink_mac_implements_lpi(ops: mac_ops); |
1824 | pl->mac_supports_eee = pl->mac_supports_eee_ops && |
1825 | pl->config->lpi_capabilities && |
1826 | !phy_interface_empty(intf: pl->config->lpi_interfaces); |
1827 | |
1828 | /* Set the default EEE configuration */ |
1829 | pl->eee_cfg.eee_enabled = pl->config->eee_enabled_default; |
1830 | pl->eee_cfg.tx_lpi_enabled = pl->eee_cfg.eee_enabled; |
1831 | pl->eee_cfg.tx_lpi_timer = pl->config->lpi_timer_default; |
1832 | |
1833 | pl->phy_state.interface = iface; |
1834 | pl->link_interface = iface; |
1835 | if (iface == PHY_INTERFACE_MODE_MOCA) |
1836 | pl->link_port = PORT_BNC; |
1837 | else |
1838 | pl->link_port = PORT_MII; |
1839 | pl->link_config.interface = iface; |
1840 | pl->link_config.pause = MLO_PAUSE_AN; |
1841 | pl->link_config.speed = SPEED_UNKNOWN; |
1842 | pl->link_config.duplex = DUPLEX_UNKNOWN; |
1843 | pl->pcs_state = PCS_STATE_DOWN; |
1844 | pl->mac_ops = mac_ops; |
1845 | __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); |
1846 | timer_setup(&pl->link_poll, phylink_fixed_poll, 0); |
1847 | |
1848 | linkmode_fill(dst: pl->supported); |
1849 | linkmode_copy(dst: pl->link_config.advertising, src: pl->supported); |
1850 | phylink_validate(pl, supported: pl->supported, state: &pl->link_config); |
1851 | |
1852 | ret = phylink_parse_mode(pl, fwnode); |
1853 | if (ret < 0) { |
1854 | kfree(objp: pl); |
1855 | return ERR_PTR(error: ret); |
1856 | } |
1857 | |
1858 | if (pl->cfg_link_an_mode == MLO_AN_FIXED) { |
1859 | ret = phylink_parse_fixedlink(pl, fwnode); |
1860 | if (ret < 0) { |
1861 | kfree(objp: pl); |
1862 | return ERR_PTR(error: ret); |
1863 | } |
1864 | } |
1865 | |
1866 | pl->req_link_an_mode = pl->cfg_link_an_mode; |
1867 | |
1868 | ret = phylink_register_sfp(pl, fwnode); |
1869 | if (ret < 0) { |
1870 | kfree(objp: pl); |
1871 | return ERR_PTR(error: ret); |
1872 | } |
1873 | |
1874 | return pl; |
1875 | } |
1876 | EXPORT_SYMBOL_GPL(phylink_create); |
1877 | |
1878 | /** |
1879 | * phylink_destroy() - cleanup and destroy the phylink instance |
1880 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
1881 | * |
1882 | * Destroy a phylink instance. Any PHY that has been attached must have been |
1883 | * cleaned up via phylink_disconnect_phy() prior to calling this function. |
1884 | * |
1885 | * Note: the rtnl lock must not be held when calling this function. |
1886 | */ |
1887 | void phylink_destroy(struct phylink *pl) |
1888 | { |
1889 | sfp_bus_del_upstream(bus: pl->sfp_bus); |
1890 | if (pl->link_gpio) |
1891 | gpiod_put(desc: pl->link_gpio); |
1892 | |
1893 | cancel_work_sync(work: &pl->resolve); |
1894 | kfree(objp: pl); |
1895 | } |
1896 | EXPORT_SYMBOL_GPL(phylink_destroy); |
1897 | |
1898 | /** |
1899 | * phylink_expects_phy() - Determine if phylink expects a phy to be attached |
1900 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
1901 | * |
1902 | * When using fixed-link mode, or in-band mode with 1000base-X or 2500base-X, |
1903 | * no PHY is needed. |
1904 | * |
1905 | * Returns true if phylink will be expecting a PHY. |
1906 | */ |
1907 | bool phylink_expects_phy(struct phylink *pl) |
1908 | { |
1909 | if (pl->cfg_link_an_mode == MLO_AN_FIXED || |
1910 | (pl->cfg_link_an_mode == MLO_AN_INBAND && |
1911 | phy_interface_mode_is_8023z(mode: pl->link_interface))) |
1912 | return false; |
1913 | return true; |
1914 | } |
1915 | EXPORT_SYMBOL_GPL(phylink_expects_phy); |
1916 | |
1917 | static void phylink_phy_change(struct phy_device *phydev, bool up) |
1918 | { |
1919 | struct phylink *pl = phydev->phylink; |
1920 | bool tx_pause, rx_pause; |
1921 | |
1922 | phy_get_pause(phydev, tx_pause: &tx_pause, rx_pause: &rx_pause); |
1923 | |
1924 | mutex_lock(&pl->state_mutex); |
1925 | pl->phy_state.speed = phydev->speed; |
1926 | pl->phy_state.duplex = phydev->duplex; |
1927 | pl->phy_state.rate_matching = phydev->rate_matching; |
1928 | pl->phy_state.pause = MLO_PAUSE_NONE; |
1929 | if (tx_pause) |
1930 | pl->phy_state.pause |= MLO_PAUSE_TX; |
1931 | if (rx_pause) |
1932 | pl->phy_state.pause |= MLO_PAUSE_RX; |
1933 | pl->phy_state.interface = phydev->interface; |
1934 | pl->phy_state.link = up; |
1935 | if (!up) |
1936 | pl->link_failed = true; |
1937 | |
1938 | /* Get the LPI state from phylib */ |
1939 | pl->phy_enable_tx_lpi = phydev->enable_tx_lpi; |
1940 | pl->mac_tx_lpi_timer = phydev->eee_cfg.tx_lpi_timer; |
1941 | mutex_unlock(lock: &pl->state_mutex); |
1942 | |
1943 | phylink_run_resolve(pl); |
1944 | |
1945 | phylink_dbg(pl, "phy link %s %s/%s/%s/%s/%s/%slpi\n", |
1946 | up ? "up": "down", |
1947 | phy_modes(phydev->interface), |
1948 | phy_speed_to_str(phydev->speed), |
1949 | phy_duplex_to_str(phydev->duplex), |
1950 | phy_rate_matching_to_str(phydev->rate_matching), |
1951 | phylink_pause_to_str(pl->phy_state.pause), |
1952 | phydev->enable_tx_lpi ? "": "no"); |
1953 | } |
1954 | |
1955 | static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy, |
1956 | unsigned long *supported, |
1957 | struct phylink_link_state *state) |
1958 | { |
1959 | DECLARE_PHY_INTERFACE_MASK(interfaces); |
1960 | |
1961 | /* If the PHY provides a bitmap of the interfaces it will be using |
1962 | * depending on the negotiated media speeds, use this to validate |
1963 | * which ethtool link modes can be used. |
1964 | */ |
1965 | if (!phy_interface_empty(intf: phy->possible_interfaces)) { |
1966 | /* We only care about the union of the PHY's interfaces and |
1967 | * those which the host supports. |
1968 | */ |
1969 | phy_interface_and(dst: interfaces, a: phy->possible_interfaces, |
1970 | b: pl->config->supported_interfaces); |
1971 | |
1972 | if (phy_interface_empty(intf: interfaces)) { |
1973 | phylink_err(pl, "PHY has no common interfaces\n"); |
1974 | return -EINVAL; |
1975 | } |
1976 | |
1977 | if (phy_on_sfp(phydev: phy)) { |
1978 | /* If the PHY is on a SFP, limit the interfaces to |
1979 | * those that can be used with a SFP module. |
1980 | */ |
1981 | phy_interface_and(dst: interfaces, a: interfaces, |
1982 | b: phylink_sfp_interfaces); |
1983 | |
1984 | if (phy_interface_empty(intf: interfaces)) { |
1985 | phylink_err(pl, "SFP PHY's possible interfaces becomes empty\n"); |
1986 | return -EINVAL; |
1987 | } |
1988 | } |
1989 | |
1990 | phylink_dbg(pl, "PHY %s uses interfaces %*pbl, validating %*pbl\n", |
1991 | phydev_name(phy), |
1992 | (int)PHY_INTERFACE_MODE_MAX, |
1993 | phy->possible_interfaces, |
1994 | (int)PHY_INTERFACE_MODE_MAX, interfaces); |
1995 | |
1996 | return phylink_validate_mask(pl, phy, supported, state, |
1997 | interfaces); |
1998 | } |
1999 | |
2000 | phylink_dbg(pl, "PHY %s doesn't supply possible interfaces\n", |
2001 | phydev_name(phy)); |
2002 | |
2003 | /* Check whether we would use rate matching for the proposed interface |
2004 | * mode. |
2005 | */ |
2006 | state->rate_matching = phy_get_rate_matching(phydev: phy, iface: state->interface); |
2007 | |
2008 | /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R, |
2009 | * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching. |
2010 | * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching |
2011 | * their Serdes is either unnecessary or not reasonable. |
2012 | * |
2013 | * For these which switch interface modes, we really need to know which |
2014 | * interface modes the PHY supports to properly work out which ethtool |
2015 | * linkmodes can be supported. For now, as a work-around, we validate |
2016 | * against all interface modes, which may lead to more ethtool link |
2017 | * modes being advertised than are actually supported. |
2018 | */ |
2019 | if (phy->is_c45 && state->rate_matching == RATE_MATCH_NONE && |
2020 | state->interface != PHY_INTERFACE_MODE_RXAUI && |
2021 | state->interface != PHY_INTERFACE_MODE_XAUI && |
2022 | state->interface != PHY_INTERFACE_MODE_USXGMII) |
2023 | state->interface = PHY_INTERFACE_MODE_NA; |
2024 | |
2025 | return phylink_validate(pl, supported, state); |
2026 | } |
2027 | |
2028 | static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, |
2029 | phy_interface_t interface) |
2030 | { |
2031 | struct phylink_link_state config; |
2032 | __ETHTOOL_DECLARE_LINK_MODE_MASK(supported); |
2033 | char *irq_str; |
2034 | int ret; |
2035 | |
2036 | /* |
2037 | * This is the new way of dealing with flow control for PHYs, |
2038 | * as described by Timur Tabi in commit 529ed1275263 ("net: phy: |
2039 | * phy drivers should not set SUPPORTED_[Asym_]Pause") except |
2040 | * using our validate call to the MAC, we rely upon the MAC |
2041 | * clearing the bits from both supported and advertising fields. |
2042 | */ |
2043 | phy_support_asym_pause(phydev: phy); |
2044 | |
2045 | memset(&config, 0, sizeof(config)); |
2046 | linkmode_copy(dst: supported, src: phy->supported); |
2047 | linkmode_copy(dst: config.advertising, src: phy->advertising); |
2048 | config.interface = interface; |
2049 | |
2050 | ret = phylink_validate_phy(pl, phy, supported, state: &config); |
2051 | if (ret) { |
2052 | phylink_warn(pl, "validation of %s with support %*pb and advertisement %*pb failed: %pe\n", |
2053 | phy_modes(config.interface), |
2054 | __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported, |
2055 | __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising, |
2056 | ERR_PTR(ret)); |
2057 | return ret; |
2058 | } |
2059 | |
2060 | phy->phylink = pl; |
2061 | phy->phy_link_change = phylink_phy_change; |
2062 | |
2063 | irq_str = phy_attached_info_irq(phydev: phy); |
2064 | phylink_info(pl, |
2065 | "PHY [%s] driver [%s] (irq=%s)\n", |
2066 | dev_name(&phy->mdio.dev), phy->drv->name, irq_str); |
2067 | kfree(objp: irq_str); |
2068 | |
2069 | mutex_lock(&phy->lock); |
2070 | mutex_lock(&pl->state_mutex); |
2071 | pl->phydev = phy; |
2072 | pl->phy_state.interface = interface; |
2073 | pl->phy_state.pause = MLO_PAUSE_NONE; |
2074 | pl->phy_state.speed = SPEED_UNKNOWN; |
2075 | pl->phy_state.duplex = DUPLEX_UNKNOWN; |
2076 | pl->phy_state.rate_matching = RATE_MATCH_NONE; |
2077 | linkmode_copy(dst: pl->supported, src: supported); |
2078 | linkmode_copy(dst: pl->link_config.advertising, src: config.advertising); |
2079 | |
2080 | /* Restrict the phy advertisement according to the MAC support. */ |
2081 | linkmode_copy(dst: phy->advertising, src: config.advertising); |
2082 | |
2083 | /* If the MAC supports phylink managed EEE, restrict the EEE |
2084 | * advertisement according to the MAC's LPI capabilities. |
2085 | */ |
2086 | if (pl->mac_supports_eee) { |
2087 | /* If EEE is enabled, then we need to call phy_support_eee() |
2088 | * to ensure that the advertising mask is appropriately set. |
2089 | * This also enables EEE at the PHY. |
2090 | */ |
2091 | if (pl->eee_cfg.eee_enabled) |
2092 | phy_support_eee(phydev: phy); |
2093 | |
2094 | phy->eee_cfg.tx_lpi_enabled = pl->eee_cfg.tx_lpi_enabled; |
2095 | phy->eee_cfg.tx_lpi_timer = pl->eee_cfg.tx_lpi_timer; |
2096 | |
2097 | /* Convert the MAC's LPI capabilities to linkmodes */ |
2098 | linkmode_zero(dst: pl->supported_lpi); |
2099 | phylink_caps_to_linkmodes(linkmodes: pl->supported_lpi, |
2100 | caps: pl->config->lpi_capabilities); |
2101 | |
2102 | /* Restrict the PHYs EEE support/advertisement to the modes |
2103 | * that the MAC supports. |
2104 | */ |
2105 | linkmode_and(dst: phy->advertising_eee, a: phy->advertising_eee, |
2106 | b: pl->supported_lpi); |
2107 | } else if (pl->mac_supports_eee_ops) { |
2108 | /* MAC supports phylink EEE, but wants EEE always disabled. */ |
2109 | phy_disable_eee(phydev: phy); |
2110 | } |
2111 | |
2112 | mutex_unlock(lock: &pl->state_mutex); |
2113 | mutex_unlock(lock: &phy->lock); |
2114 | |
2115 | phylink_dbg(pl, |
2116 | "phy: %s setting supported %*pb advertising %*pb\n", |
2117 | phy_modes(interface), |
2118 | __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, |
2119 | __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); |
2120 | |
2121 | if (phy_interrupt_is_valid(phydev: phy)) |
2122 | phy_request_interrupt(phydev: phy); |
2123 | |
2124 | if (pl->config->mac_managed_pm) |
2125 | phy->mac_managed_pm = true; |
2126 | |
2127 | /* Allow the MAC to stop its clock if the PHY has the capability */ |
2128 | pl->mac_tx_clk_stop = phy_eee_tx_clock_stop_capable(phydev: phy) > 0; |
2129 | |
2130 | if (pl->mac_supports_eee_ops) { |
2131 | /* Explicitly configure whether the PHY is allowed to stop it's |
2132 | * receive clock. |
2133 | */ |
2134 | ret = phy_eee_rx_clock_stop(phydev: phy, |
2135 | clk_stop_enable: pl->config->eee_rx_clk_stop_enable); |
2136 | if (ret == -EOPNOTSUPP) |
2137 | ret = 0; |
2138 | } |
2139 | |
2140 | return ret; |
2141 | } |
2142 | |
2143 | static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, |
2144 | phy_interface_t interface) |
2145 | { |
2146 | u32 flags = 0; |
2147 | |
2148 | if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || |
2149 | (pl->cfg_link_an_mode == MLO_AN_INBAND && |
2150 | phy_interface_mode_is_8023z(interface) && !pl->sfp_bus))) |
2151 | return -EINVAL; |
2152 | |
2153 | if (pl->phydev) |
2154 | return -EBUSY; |
2155 | |
2156 | if (pl->config->mac_requires_rxc) |
2157 | flags |= PHY_F_RXC_ALWAYS_ON; |
2158 | |
2159 | return phy_attach_direct(dev: pl->netdev, phydev: phy, flags, interface); |
2160 | } |
2161 | |
2162 | /** |
2163 | * phylink_connect_phy() - connect a PHY to the phylink instance |
2164 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2165 | * @phy: a pointer to a &struct phy_device. |
2166 | * |
2167 | * Connect @phy to the phylink instance specified by @pl by calling |
2168 | * phy_attach_direct(). Configure the @phy according to the MAC driver's |
2169 | * capabilities, start the PHYLIB state machine and enable any interrupts |
2170 | * that the PHY supports. |
2171 | * |
2172 | * This updates the phylink's ethtool supported and advertising link mode |
2173 | * masks. |
2174 | * |
2175 | * Returns 0 on success or a negative errno. |
2176 | */ |
2177 | int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) |
2178 | { |
2179 | int ret; |
2180 | |
2181 | /* Use PHY device/driver interface */ |
2182 | if (pl->link_interface == PHY_INTERFACE_MODE_NA) { |
2183 | pl->link_interface = phy->interface; |
2184 | pl->link_config.interface = pl->link_interface; |
2185 | } |
2186 | |
2187 | ret = phylink_attach_phy(pl, phy, interface: pl->link_interface); |
2188 | if (ret < 0) |
2189 | return ret; |
2190 | |
2191 | ret = phylink_bringup_phy(pl, phy, interface: pl->link_config.interface); |
2192 | if (ret) |
2193 | phy_detach(phydev: phy); |
2194 | |
2195 | return ret; |
2196 | } |
2197 | EXPORT_SYMBOL_GPL(phylink_connect_phy); |
2198 | |
2199 | /** |
2200 | * phylink_of_phy_connect() - connect the PHY specified in the DT mode. |
2201 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2202 | * @dn: a pointer to a &struct device_node. |
2203 | * @flags: PHY-specific flags to communicate to the PHY device driver |
2204 | * |
2205 | * Connect the phy specified in the device node @dn to the phylink instance |
2206 | * specified by @pl. Actions specified in phylink_connect_phy() will be |
2207 | * performed. |
2208 | * |
2209 | * Returns 0 on success or a negative errno. |
2210 | */ |
2211 | int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn, |
2212 | u32 flags) |
2213 | { |
2214 | return phylink_fwnode_phy_connect(pl, of_fwnode_handle(dn), flags); |
2215 | } |
2216 | EXPORT_SYMBOL_GPL(phylink_of_phy_connect); |
2217 | |
2218 | /** |
2219 | * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode. |
2220 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2221 | * @fwnode: a pointer to a &struct fwnode_handle. |
2222 | * @flags: PHY-specific flags to communicate to the PHY device driver |
2223 | * |
2224 | * Connect the phy specified @fwnode to the phylink instance specified |
2225 | * by @pl. |
2226 | * |
2227 | * Returns 0 on success or a negative errno. |
2228 | */ |
2229 | int phylink_fwnode_phy_connect(struct phylink *pl, |
2230 | const struct fwnode_handle *fwnode, |
2231 | u32 flags) |
2232 | { |
2233 | struct fwnode_handle *phy_fwnode; |
2234 | struct phy_device *phy_dev; |
2235 | int ret; |
2236 | |
2237 | /* Fixed links and 802.3z are handled without needing a PHY */ |
2238 | if (pl->cfg_link_an_mode == MLO_AN_FIXED || |
2239 | (pl->cfg_link_an_mode == MLO_AN_INBAND && |
2240 | phy_interface_mode_is_8023z(mode: pl->link_interface))) |
2241 | return 0; |
2242 | |
2243 | phy_fwnode = fwnode_get_phy_node(fwnode); |
2244 | if (IS_ERR(ptr: phy_fwnode)) { |
2245 | if (pl->cfg_link_an_mode == MLO_AN_PHY) |
2246 | return -ENODEV; |
2247 | return 0; |
2248 | } |
2249 | |
2250 | phy_dev = fwnode_phy_find_device(phy_fwnode); |
2251 | /* We're done with the phy_node handle */ |
2252 | fwnode_handle_put(fwnode: phy_fwnode); |
2253 | if (!phy_dev) |
2254 | return -ENODEV; |
2255 | |
2256 | /* Use PHY device/driver interface */ |
2257 | if (pl->link_interface == PHY_INTERFACE_MODE_NA) { |
2258 | pl->link_interface = phy_dev->interface; |
2259 | pl->link_config.interface = pl->link_interface; |
2260 | } |
2261 | |
2262 | if (pl->config->mac_requires_rxc) |
2263 | flags |= PHY_F_RXC_ALWAYS_ON; |
2264 | |
2265 | ret = phy_attach_direct(dev: pl->netdev, phydev: phy_dev, flags, |
2266 | interface: pl->link_interface); |
2267 | phy_device_free(phydev: phy_dev); |
2268 | if (ret) |
2269 | return ret; |
2270 | |
2271 | ret = phylink_bringup_phy(pl, phy: phy_dev, interface: pl->link_config.interface); |
2272 | if (ret) |
2273 | phy_detach(phydev: phy_dev); |
2274 | |
2275 | return ret; |
2276 | } |
2277 | EXPORT_SYMBOL_GPL(phylink_fwnode_phy_connect); |
2278 | |
2279 | /** |
2280 | * phylink_disconnect_phy() - disconnect any PHY attached to the phylink |
2281 | * instance. |
2282 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2283 | * |
2284 | * Disconnect any current PHY from the phylink instance described by @pl. |
2285 | */ |
2286 | void phylink_disconnect_phy(struct phylink *pl) |
2287 | { |
2288 | struct phy_device *phy; |
2289 | |
2290 | ASSERT_RTNL(); |
2291 | |
2292 | phy = pl->phydev; |
2293 | if (phy) { |
2294 | mutex_lock(&phy->lock); |
2295 | mutex_lock(&pl->state_mutex); |
2296 | pl->phydev = NULL; |
2297 | pl->phy_enable_tx_lpi = false; |
2298 | pl->mac_tx_clk_stop = false; |
2299 | mutex_unlock(lock: &pl->state_mutex); |
2300 | mutex_unlock(lock: &phy->lock); |
2301 | flush_work(work: &pl->resolve); |
2302 | |
2303 | phy_disconnect(phydev: phy); |
2304 | } |
2305 | } |
2306 | EXPORT_SYMBOL_GPL(phylink_disconnect_phy); |
2307 | |
2308 | static void phylink_link_changed(struct phylink *pl, bool up, const char *what) |
2309 | { |
2310 | if (!up) |
2311 | pl->link_failed = true; |
2312 | phylink_run_resolve(pl); |
2313 | phylink_dbg(pl, "%s link %s\n", what, up ? "up": "down"); |
2314 | } |
2315 | |
2316 | /** |
2317 | * phylink_mac_change() - notify phylink of a change in MAC state |
2318 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2319 | * @up: indicates whether the link is currently up. |
2320 | * |
2321 | * The MAC driver should call this driver when the state of its link |
2322 | * changes (eg, link failure, new negotiation results, etc.) |
2323 | */ |
2324 | void phylink_mac_change(struct phylink *pl, bool up) |
2325 | { |
2326 | phylink_link_changed(pl, up, what: "mac"); |
2327 | } |
2328 | EXPORT_SYMBOL_GPL(phylink_mac_change); |
2329 | |
2330 | /** |
2331 | * phylink_pcs_change() - notify phylink of a change to PCS link state |
2332 | * @pcs: pointer to &struct phylink_pcs |
2333 | * @up: indicates whether the link is currently up. |
2334 | * |
2335 | * The PCS driver should call this when the state of its link changes |
2336 | * (e.g. link failure, new negotiation results, etc.) Note: it should |
2337 | * not determine "up" by reading the BMSR. If in doubt about the link |
2338 | * state at interrupt time, then pass true if pcs_get_state() returns |
2339 | * the latched link-down state, otherwise pass false. |
2340 | */ |
2341 | void phylink_pcs_change(struct phylink_pcs *pcs, bool up) |
2342 | { |
2343 | struct phylink *pl = pcs->phylink; |
2344 | |
2345 | if (pl) |
2346 | phylink_link_changed(pl, up, what: "pcs"); |
2347 | } |
2348 | EXPORT_SYMBOL_GPL(phylink_pcs_change); |
2349 | |
2350 | static irqreturn_t phylink_link_handler(int irq, void *data) |
2351 | { |
2352 | struct phylink *pl = data; |
2353 | |
2354 | phylink_run_resolve(pl); |
2355 | |
2356 | return IRQ_HANDLED; |
2357 | } |
2358 | |
2359 | /** |
2360 | * phylink_start() - start a phylink instance |
2361 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2362 | * |
2363 | * Start the phylink instance specified by @pl, configuring the MAC for the |
2364 | * desired link mode(s) and negotiation style. This should be called from the |
2365 | * network device driver's &struct net_device_ops ndo_open() method. |
2366 | */ |
2367 | void phylink_start(struct phylink *pl) |
2368 | { |
2369 | bool poll = false; |
2370 | |
2371 | ASSERT_RTNL(); |
2372 | |
2373 | phylink_info(pl, "configuring for %s/%s link mode\n", |
2374 | phylink_an_mode_str(pl->req_link_an_mode), |
2375 | phy_modes(pl->link_config.interface)); |
2376 | |
2377 | /* Always set the carrier off */ |
2378 | if (pl->netdev) |
2379 | netif_carrier_off(dev: pl->netdev); |
2380 | |
2381 | pl->pcs_state = PCS_STATE_STARTING; |
2382 | |
2383 | /* Apply the link configuration to the MAC when starting. This allows |
2384 | * a fixed-link to start with the correct parameters, and also |
2385 | * ensures that we set the appropriate advertisement for Serdes links. |
2386 | * |
2387 | * Restart autonegotiation if using 802.3z to ensure that the link |
2388 | * parameters are properly negotiated. This is necessary for DSA |
2389 | * switches using 802.3z negotiation to ensure they see our modes. |
2390 | */ |
2391 | phylink_mac_initial_config(pl, force_restart: true); |
2392 | |
2393 | pl->pcs_state = PCS_STATE_STARTED; |
2394 | |
2395 | phylink_enable_and_run_resolve(pl, bit: PHYLINK_DISABLE_STOPPED); |
2396 | |
2397 | if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { |
2398 | int irq = gpiod_to_irq(desc: pl->link_gpio); |
2399 | |
2400 | if (irq > 0) { |
2401 | if (!request_irq(irq, handler: phylink_link_handler, |
2402 | IRQF_TRIGGER_RISING | |
2403 | IRQF_TRIGGER_FALLING, |
2404 | name: "netdev link", dev: pl)) |
2405 | pl->link_irq = irq; |
2406 | else |
2407 | irq = 0; |
2408 | } |
2409 | if (irq <= 0) |
2410 | poll = true; |
2411 | } |
2412 | |
2413 | if (pl->cfg_link_an_mode == MLO_AN_FIXED) |
2414 | poll |= pl->config->poll_fixed_state; |
2415 | |
2416 | if (poll) |
2417 | mod_timer(timer: &pl->link_poll, expires: jiffies + HZ); |
2418 | if (pl->phydev) |
2419 | phy_start(phydev: pl->phydev); |
2420 | if (pl->sfp_bus) |
2421 | sfp_upstream_start(bus: pl->sfp_bus); |
2422 | } |
2423 | EXPORT_SYMBOL_GPL(phylink_start); |
2424 | |
2425 | /** |
2426 | * phylink_stop() - stop a phylink instance |
2427 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2428 | * |
2429 | * Stop the phylink instance specified by @pl. This should be called from the |
2430 | * network device driver's &struct net_device_ops ndo_stop() method. The |
2431 | * network device's carrier state should not be changed prior to calling this |
2432 | * function. |
2433 | * |
2434 | * This will synchronously bring down the link if the link is not already |
2435 | * down (in other words, it will trigger a mac_link_down() method call.) |
2436 | */ |
2437 | void phylink_stop(struct phylink *pl) |
2438 | { |
2439 | ASSERT_RTNL(); |
2440 | |
2441 | if (pl->sfp_bus) |
2442 | sfp_upstream_stop(bus: pl->sfp_bus); |
2443 | if (pl->phydev) |
2444 | phy_stop(phydev: pl->phydev); |
2445 | timer_delete_sync(timer: &pl->link_poll); |
2446 | if (pl->link_irq) { |
2447 | free_irq(pl->link_irq, pl); |
2448 | pl->link_irq = 0; |
2449 | } |
2450 | |
2451 | phylink_run_resolve_and_disable(pl, bit: PHYLINK_DISABLE_STOPPED); |
2452 | |
2453 | pl->pcs_state = PCS_STATE_DOWN; |
2454 | |
2455 | phylink_pcs_disable(pcs: pl->pcs); |
2456 | } |
2457 | EXPORT_SYMBOL_GPL(phylink_stop); |
2458 | |
2459 | /** |
2460 | * phylink_rx_clk_stop_block() - block PHY ability to stop receive clock in LPI |
2461 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2462 | * |
2463 | * Disable the PHY's ability to stop the receive clock while the receive path |
2464 | * is in EEE LPI state, until the number of calls to phylink_rx_clk_stop_block() |
2465 | * are balanced by calls to phylink_rx_clk_stop_unblock(). |
2466 | */ |
2467 | void phylink_rx_clk_stop_block(struct phylink *pl) |
2468 | { |
2469 | ASSERT_RTNL(); |
2470 | |
2471 | if (pl->mac_rx_clk_stop_blocked == U8_MAX) { |
2472 | phylink_warn(pl, "%s called too many times - ignoring\n", |
2473 | __func__); |
2474 | dump_stack(); |
2475 | return; |
2476 | } |
2477 | |
2478 | /* Disable PHY receive clock stop if this is the first time this |
2479 | * function has been called and clock-stop was previously enabled. |
2480 | */ |
2481 | if (pl->mac_rx_clk_stop_blocked++ == 0 && |
2482 | pl->mac_supports_eee_ops && pl->phydev && |
2483 | pl->config->eee_rx_clk_stop_enable) |
2484 | phy_eee_rx_clock_stop(phydev: pl->phydev, clk_stop_enable: false); |
2485 | } |
2486 | EXPORT_SYMBOL_GPL(phylink_rx_clk_stop_block); |
2487 | |
2488 | /** |
2489 | * phylink_rx_clk_stop_unblock() - unblock PHY ability to stop receive clock |
2490 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2491 | * |
2492 | * All calls to phylink_rx_clk_stop_block() must be balanced with a |
2493 | * corresponding call to phylink_rx_clk_stop_unblock() to restore the PHYs |
2494 | * ability to stop the receive clock when the receive path is in EEE LPI mode. |
2495 | */ |
2496 | void phylink_rx_clk_stop_unblock(struct phylink *pl) |
2497 | { |
2498 | ASSERT_RTNL(); |
2499 | |
2500 | if (pl->mac_rx_clk_stop_blocked == 0) { |
2501 | phylink_warn(pl, "%s called too many times - ignoring\n", |
2502 | __func__); |
2503 | dump_stack(); |
2504 | return; |
2505 | } |
2506 | |
2507 | /* Re-enable PHY receive clock stop if the number of unblocks matches |
2508 | * the number of calls to the block function above. |
2509 | */ |
2510 | if (--pl->mac_rx_clk_stop_blocked == 0 && |
2511 | pl->mac_supports_eee_ops && pl->phydev && |
2512 | pl->config->eee_rx_clk_stop_enable) |
2513 | phy_eee_rx_clock_stop(phydev: pl->phydev, clk_stop_enable: true); |
2514 | } |
2515 | EXPORT_SYMBOL_GPL(phylink_rx_clk_stop_unblock); |
2516 | |
2517 | /** |
2518 | * phylink_suspend() - handle a network device suspend event |
2519 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2520 | * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan |
2521 | * |
2522 | * Handle a network device suspend event. There are several cases: |
2523 | * |
2524 | * - If Wake-on-Lan is not active, we can bring down the link between |
2525 | * the MAC and PHY by calling phylink_stop(). |
2526 | * - If Wake-on-Lan is active, and being handled only by the PHY, we |
2527 | * can also bring down the link between the MAC and PHY. |
2528 | * - If Wake-on-Lan is active, but being handled by the MAC, the MAC |
2529 | * still needs to receive packets, so we can not bring the link down. |
2530 | */ |
2531 | void phylink_suspend(struct phylink *pl, bool mac_wol) |
2532 | { |
2533 | ASSERT_RTNL(); |
2534 | |
2535 | if (mac_wol && (!pl->netdev || pl->netdev->ethtool->wol_enabled)) { |
2536 | /* Wake-on-Lan enabled, MAC handling */ |
2537 | mutex_lock(&pl->state_mutex); |
2538 | |
2539 | /* Stop the resolver bringing the link up */ |
2540 | __set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state); |
2541 | |
2542 | pl->suspend_link_up = phylink_link_is_up(pl); |
2543 | if (pl->suspend_link_up) { |
2544 | /* Disable the carrier, to prevent transmit timeouts, |
2545 | * but one would hope all packets have been sent. This |
2546 | * also means phylink_resolve() will do nothing. |
2547 | */ |
2548 | if (pl->netdev) |
2549 | netif_carrier_off(dev: pl->netdev); |
2550 | pl->old_link_state = false; |
2551 | } |
2552 | |
2553 | /* We do not call mac_link_down() here as we want the |
2554 | * link to remain up to receive the WoL packets. |
2555 | */ |
2556 | mutex_unlock(lock: &pl->state_mutex); |
2557 | } else { |
2558 | phylink_stop(pl); |
2559 | } |
2560 | } |
2561 | EXPORT_SYMBOL_GPL(phylink_suspend); |
2562 | |
2563 | /** |
2564 | * phylink_prepare_resume() - prepare to resume a network device |
2565 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2566 | * |
2567 | * Optional, but if called must be called prior to phylink_resume(). |
2568 | * |
2569 | * Prepare to resume a network device, preparing the PHY as necessary. |
2570 | */ |
2571 | void phylink_prepare_resume(struct phylink *pl) |
2572 | { |
2573 | struct phy_device *phydev = pl->phydev; |
2574 | |
2575 | ASSERT_RTNL(); |
2576 | |
2577 | /* IEEE 802.3 22.2.4.1.5 allows PHYs to stop their receive clock |
2578 | * when PDOWN is set. However, some MACs require RXC to be running |
2579 | * in order to resume. If the MAC requires RXC, and we have a PHY, |
2580 | * then resume the PHY. Note that 802.3 allows PHYs 500ms before |
2581 | * the clock meets requirements. We do not implement this delay. |
2582 | */ |
2583 | if (pl->config->mac_requires_rxc && phydev && phydev->suspended) |
2584 | phy_resume(phydev); |
2585 | } |
2586 | EXPORT_SYMBOL_GPL(phylink_prepare_resume); |
2587 | |
2588 | /** |
2589 | * phylink_resume() - handle a network device resume event |
2590 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2591 | * |
2592 | * Undo the effects of phylink_suspend(), returning the link to an |
2593 | * operational state. |
2594 | */ |
2595 | void phylink_resume(struct phylink *pl) |
2596 | { |
2597 | ASSERT_RTNL(); |
2598 | |
2599 | if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) { |
2600 | /* Wake-on-Lan enabled, MAC handling */ |
2601 | |
2602 | if (pl->suspend_link_up) { |
2603 | /* Call mac_link_down() so we keep the overall state |
2604 | * balanced. Do this under the state_mutex lock for |
2605 | * consistency. This will cause a "Link Down" message |
2606 | * to be printed during resume, which is harmless - |
2607 | * the true link state will be printed when we run a |
2608 | * resolve. |
2609 | */ |
2610 | mutex_lock(&pl->state_mutex); |
2611 | phylink_link_down(pl); |
2612 | mutex_unlock(lock: &pl->state_mutex); |
2613 | } |
2614 | |
2615 | /* Re-apply the link parameters so that all the settings get |
2616 | * restored to the MAC. |
2617 | */ |
2618 | phylink_mac_initial_config(pl, force_restart: true); |
2619 | |
2620 | /* Re-enable and re-resolve the link parameters */ |
2621 | phylink_enable_and_run_resolve(pl, bit: PHYLINK_DISABLE_MAC_WOL); |
2622 | } else { |
2623 | phylink_start(pl); |
2624 | } |
2625 | } |
2626 | EXPORT_SYMBOL_GPL(phylink_resume); |
2627 | |
2628 | /** |
2629 | * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY |
2630 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2631 | * @wol: a pointer to &struct ethtool_wolinfo to hold the read parameters |
2632 | * |
2633 | * Read the wake on lan parameters from the PHY attached to the phylink |
2634 | * instance specified by @pl. If no PHY is currently attached, report no |
2635 | * support for wake on lan. |
2636 | */ |
2637 | void phylink_ethtool_get_wol(struct phylink *pl, struct ethtool_wolinfo *wol) |
2638 | { |
2639 | ASSERT_RTNL(); |
2640 | |
2641 | wol->supported = 0; |
2642 | wol->wolopts = 0; |
2643 | |
2644 | if (pl->phydev) |
2645 | phy_ethtool_get_wol(phydev: pl->phydev, wol); |
2646 | } |
2647 | EXPORT_SYMBOL_GPL(phylink_ethtool_get_wol); |
2648 | |
2649 | /** |
2650 | * phylink_ethtool_set_wol() - set wake on lan parameters |
2651 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2652 | * @wol: a pointer to &struct ethtool_wolinfo for the desired parameters |
2653 | * |
2654 | * Set the wake on lan parameters for the PHY attached to the phylink |
2655 | * instance specified by @pl. If no PHY is attached, returns %EOPNOTSUPP |
2656 | * error. |
2657 | * |
2658 | * Returns zero on success or negative errno code. |
2659 | */ |
2660 | int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol) |
2661 | { |
2662 | int ret = -EOPNOTSUPP; |
2663 | |
2664 | ASSERT_RTNL(); |
2665 | |
2666 | if (pl->phydev) |
2667 | ret = phy_ethtool_set_wol(phydev: pl->phydev, wol); |
2668 | |
2669 | return ret; |
2670 | } |
2671 | EXPORT_SYMBOL_GPL(phylink_ethtool_set_wol); |
2672 | |
2673 | static phy_interface_t phylink_sfp_select_interface(struct phylink *pl, |
2674 | const unsigned long *link_modes) |
2675 | { |
2676 | phy_interface_t interface; |
2677 | |
2678 | interface = sfp_select_interface(bus: pl->sfp_bus, link_modes); |
2679 | if (interface == PHY_INTERFACE_MODE_NA) { |
2680 | phylink_err(pl, |
2681 | "selection of interface failed, advertisement %*pb\n", |
2682 | __ETHTOOL_LINK_MODE_MASK_NBITS, |
2683 | link_modes); |
2684 | return interface; |
2685 | } |
2686 | |
2687 | if (!test_bit(interface, pl->config->supported_interfaces)) { |
2688 | phylink_err(pl, |
2689 | "selection of interface failed, SFP selected %s (%u) but MAC supports %*pbl\n", |
2690 | phy_modes(interface), interface, |
2691 | (int)PHY_INTERFACE_MODE_MAX, |
2692 | pl->config->supported_interfaces); |
2693 | return PHY_INTERFACE_MODE_NA; |
2694 | } |
2695 | |
2696 | return interface; |
2697 | } |
2698 | |
2699 | static void phylink_merge_link_mode(unsigned long *dst, const unsigned long *b) |
2700 | { |
2701 | __ETHTOOL_DECLARE_LINK_MODE_MASK(mask); |
2702 | |
2703 | linkmode_zero(dst: mask); |
2704 | phylink_set_port_modes(mask); |
2705 | |
2706 | linkmode_and(dst, a: dst, b: mask); |
2707 | linkmode_or(dst, a: dst, b); |
2708 | } |
2709 | |
2710 | static void phylink_get_ksettings(const struct phylink_link_state *state, |
2711 | struct ethtool_link_ksettings *kset) |
2712 | { |
2713 | phylink_merge_link_mode(dst: kset->link_modes.advertising, b: state->advertising); |
2714 | linkmode_copy(dst: kset->link_modes.lp_advertising, src: state->lp_advertising); |
2715 | if (kset->base.rate_matching == RATE_MATCH_NONE) { |
2716 | kset->base.speed = state->speed; |
2717 | kset->base.duplex = state->duplex; |
2718 | } |
2719 | kset->base.autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, |
2720 | state->advertising) ? |
2721 | AUTONEG_ENABLE : AUTONEG_DISABLE; |
2722 | } |
2723 | |
2724 | /** |
2725 | * phylink_ethtool_ksettings_get() - get the current link settings |
2726 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2727 | * @kset: a pointer to a &struct ethtool_link_ksettings to hold link settings |
2728 | * |
2729 | * Read the current link settings for the phylink instance specified by @pl. |
2730 | * This will be the link settings read from the MAC, PHY or fixed link |
2731 | * settings depending on the current negotiation mode. |
2732 | */ |
2733 | int phylink_ethtool_ksettings_get(struct phylink *pl, |
2734 | struct ethtool_link_ksettings *kset) |
2735 | { |
2736 | struct phylink_link_state link_state; |
2737 | |
2738 | ASSERT_RTNL(); |
2739 | |
2740 | if (pl->phydev) |
2741 | phy_ethtool_ksettings_get(phydev: pl->phydev, cmd: kset); |
2742 | else |
2743 | kset->base.port = pl->link_port; |
2744 | |
2745 | linkmode_copy(dst: kset->link_modes.supported, src: pl->supported); |
2746 | |
2747 | switch (pl->act_link_an_mode) { |
2748 | case MLO_AN_FIXED: |
2749 | /* We are using fixed settings. Report these as the |
2750 | * current link settings - and note that these also |
2751 | * represent the supported speeds/duplex/pause modes. |
2752 | */ |
2753 | phylink_get_fixed_state(pl, state: &link_state); |
2754 | phylink_get_ksettings(state: &link_state, kset); |
2755 | break; |
2756 | |
2757 | case MLO_AN_INBAND: |
2758 | /* If there is a phy attached, then use the reported |
2759 | * settings from the phy with no modification. |
2760 | */ |
2761 | if (pl->phydev) |
2762 | break; |
2763 | |
2764 | phylink_mac_pcs_get_state(pl, state: &link_state); |
2765 | |
2766 | /* The MAC is reporting the link results from its own PCS |
2767 | * layer via in-band status. Report these as the current |
2768 | * link settings. |
2769 | */ |
2770 | phylink_get_ksettings(state: &link_state, kset); |
2771 | break; |
2772 | } |
2773 | |
2774 | return 0; |
2775 | } |
2776 | EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get); |
2777 | |
2778 | static bool phylink_validate_pcs_inband_autoneg(struct phylink *pl, |
2779 | phy_interface_t interface, |
2780 | unsigned long *adv) |
2781 | { |
2782 | unsigned int inband = phylink_inband_caps(pl, interface); |
2783 | unsigned int mask; |
2784 | |
2785 | /* If the PCS doesn't implement inband support, be permissive. */ |
2786 | if (!inband) |
2787 | return true; |
2788 | |
2789 | if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, adv)) |
2790 | mask = LINK_INBAND_ENABLE; |
2791 | else |
2792 | mask = LINK_INBAND_DISABLE; |
2793 | |
2794 | /* Check whether the PCS implements the required mode */ |
2795 | return !!(inband & mask); |
2796 | } |
2797 | |
2798 | /** |
2799 | * phylink_ethtool_ksettings_set() - set the link settings |
2800 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2801 | * @kset: a pointer to a &struct ethtool_link_ksettings for the desired modes |
2802 | */ |
2803 | int phylink_ethtool_ksettings_set(struct phylink *pl, |
2804 | const struct ethtool_link_ksettings *kset) |
2805 | { |
2806 | __ETHTOOL_DECLARE_LINK_MODE_MASK(support); |
2807 | const struct link_capabilities *c; |
2808 | struct phylink_link_state config; |
2809 | |
2810 | ASSERT_RTNL(); |
2811 | |
2812 | if (pl->phydev) { |
2813 | struct ethtool_link_ksettings phy_kset = *kset; |
2814 | |
2815 | linkmode_and(dst: phy_kset.link_modes.advertising, |
2816 | a: phy_kset.link_modes.advertising, |
2817 | b: pl->supported); |
2818 | |
2819 | /* We can rely on phylib for this update; we also do not need |
2820 | * to update the pl->link_config settings: |
2821 | * - the configuration returned via ksettings_get() will come |
2822 | * from phylib whenever a PHY is present. |
2823 | * - link_config.interface will be updated by the PHY calling |
2824 | * back via phylink_phy_change() and a subsequent resolve. |
2825 | * - initial link configuration for PHY mode comes from the |
2826 | * last phy state updated via phylink_phy_change(). |
2827 | * - other configuration changes (e.g. pause modes) are |
2828 | * performed directly via phylib. |
2829 | * - if in in-band mode with a PHY, the link configuration |
2830 | * is passed on the link from the PHY, and all of |
2831 | * link_config.{speed,duplex,an_enabled,pause} are not used. |
2832 | * - the only possible use would be link_config.advertising |
2833 | * pause modes when in 1000base-X mode with a PHY, but in |
2834 | * the presence of a PHY, this should not be changed as that |
2835 | * should be determined from the media side advertisement. |
2836 | */ |
2837 | return phy_ethtool_ksettings_set(phydev: pl->phydev, cmd: &phy_kset); |
2838 | } |
2839 | |
2840 | config = pl->link_config; |
2841 | /* Mask out unsupported advertisements */ |
2842 | linkmode_and(dst: config.advertising, a: kset->link_modes.advertising, |
2843 | b: pl->supported); |
2844 | |
2845 | /* FIXME: should we reject autoneg if phy/mac does not support it? */ |
2846 | switch (kset->base.autoneg) { |
2847 | case AUTONEG_DISABLE: |
2848 | /* Autonegotiation disabled, select a suitable speed and |
2849 | * duplex. |
2850 | */ |
2851 | c = phy_caps_lookup(speed: kset->base.speed, duplex: kset->base.duplex, |
2852 | supported: pl->supported, exact: false); |
2853 | if (!c) |
2854 | return -EINVAL; |
2855 | |
2856 | /* If we have a fixed link, refuse to change link parameters. |
2857 | * If the link parameters match, accept them but do nothing. |
2858 | */ |
2859 | if (pl->req_link_an_mode == MLO_AN_FIXED) { |
2860 | if (c->speed != pl->link_config.speed || |
2861 | c->duplex != pl->link_config.duplex) |
2862 | return -EINVAL; |
2863 | return 0; |
2864 | } |
2865 | |
2866 | config.speed = c->speed; |
2867 | config.duplex = c->duplex; |
2868 | break; |
2869 | |
2870 | case AUTONEG_ENABLE: |
2871 | /* If we have a fixed link, allow autonegotiation (since that |
2872 | * is our default case) but do not allow the advertisement to |
2873 | * be changed. If the advertisement matches, simply return. |
2874 | */ |
2875 | if (pl->req_link_an_mode == MLO_AN_FIXED) { |
2876 | if (!linkmode_equal(src1: config.advertising, |
2877 | src2: pl->link_config.advertising)) |
2878 | return -EINVAL; |
2879 | return 0; |
2880 | } |
2881 | |
2882 | config.speed = SPEED_UNKNOWN; |
2883 | config.duplex = DUPLEX_UNKNOWN; |
2884 | break; |
2885 | |
2886 | default: |
2887 | return -EINVAL; |
2888 | } |
2889 | |
2890 | /* We have ruled out the case with a PHY attached, and the |
2891 | * fixed-link cases. All that is left are in-band links. |
2892 | */ |
2893 | linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising, |
2894 | kset->base.autoneg == AUTONEG_ENABLE); |
2895 | |
2896 | /* If this link is with an SFP, ensure that changes to advertised modes |
2897 | * also cause the associated interface to be selected such that the |
2898 | * link can be configured correctly. |
2899 | */ |
2900 | if (pl->sfp_bus) { |
2901 | config.interface = phylink_sfp_select_interface(pl, |
2902 | link_modes: config.advertising); |
2903 | if (config.interface == PHY_INTERFACE_MODE_NA) |
2904 | return -EINVAL; |
2905 | |
2906 | /* Revalidate with the selected interface */ |
2907 | linkmode_copy(dst: support, src: pl->supported); |
2908 | if (phylink_validate(pl, supported: support, state: &config)) { |
2909 | phylink_err(pl, "validation of %s/%s with support %*pb failed\n", |
2910 | phylink_an_mode_str(pl->req_link_an_mode), |
2911 | phy_modes(config.interface), |
2912 | __ETHTOOL_LINK_MODE_MASK_NBITS, support); |
2913 | return -EINVAL; |
2914 | } |
2915 | } else { |
2916 | /* Validate without changing the current supported mask. */ |
2917 | linkmode_copy(dst: support, src: pl->supported); |
2918 | if (phylink_validate(pl, supported: support, state: &config)) |
2919 | return -EINVAL; |
2920 | } |
2921 | |
2922 | /* If autonegotiation is enabled, we must have an advertisement */ |
2923 | if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, |
2924 | config.advertising) && |
2925 | phylink_is_empty_linkmode(linkmode: config.advertising)) |
2926 | return -EINVAL; |
2927 | |
2928 | /* Validate the autonegotiation state. We don't have a PHY in this |
2929 | * situation, so the PCS is the media-facing entity. |
2930 | */ |
2931 | if (!phylink_validate_pcs_inband_autoneg(pl, interface: config.interface, |
2932 | adv: config.advertising)) |
2933 | return -EINVAL; |
2934 | |
2935 | mutex_lock(&pl->state_mutex); |
2936 | pl->link_config.speed = config.speed; |
2937 | pl->link_config.duplex = config.duplex; |
2938 | |
2939 | if (pl->link_config.interface != config.interface) { |
2940 | /* The interface changed, e.g. 1000base-X <-> 2500base-X */ |
2941 | /* We need to force the link down, then change the interface */ |
2942 | if (pl->old_link_state) { |
2943 | phylink_link_down(pl); |
2944 | pl->old_link_state = false; |
2945 | } |
2946 | if (!test_bit(PHYLINK_DISABLE_STOPPED, |
2947 | &pl->phylink_disable_state)) |
2948 | phylink_major_config(pl, restart: false, state: &config); |
2949 | pl->link_config.interface = config.interface; |
2950 | linkmode_copy(dst: pl->link_config.advertising, src: config.advertising); |
2951 | } else if (!linkmode_equal(src1: pl->link_config.advertising, |
2952 | src2: config.advertising)) { |
2953 | linkmode_copy(dst: pl->link_config.advertising, src: config.advertising); |
2954 | phylink_change_inband_advert(pl); |
2955 | } |
2956 | mutex_unlock(lock: &pl->state_mutex); |
2957 | |
2958 | return 0; |
2959 | } |
2960 | EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_set); |
2961 | |
2962 | /** |
2963 | * phylink_ethtool_nway_reset() - restart negotiation |
2964 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2965 | * |
2966 | * Restart negotiation for the phylink instance specified by @pl. This will |
2967 | * cause any attached phy to restart negotiation with the link partner, and |
2968 | * if the MAC is in a BaseX mode, the MAC will also be requested to restart |
2969 | * negotiation. |
2970 | * |
2971 | * Returns zero on success, or negative error code. |
2972 | */ |
2973 | int phylink_ethtool_nway_reset(struct phylink *pl) |
2974 | { |
2975 | int ret = 0; |
2976 | |
2977 | ASSERT_RTNL(); |
2978 | |
2979 | if (pl->phydev) |
2980 | ret = phy_restart_aneg(phydev: pl->phydev); |
2981 | phylink_pcs_an_restart(pl); |
2982 | |
2983 | return ret; |
2984 | } |
2985 | EXPORT_SYMBOL_GPL(phylink_ethtool_nway_reset); |
2986 | |
2987 | /** |
2988 | * phylink_ethtool_get_pauseparam() - get the current pause parameters |
2989 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
2990 | * @pause: a pointer to a &struct ethtool_pauseparam |
2991 | */ |
2992 | void phylink_ethtool_get_pauseparam(struct phylink *pl, |
2993 | struct ethtool_pauseparam *pause) |
2994 | { |
2995 | ASSERT_RTNL(); |
2996 | |
2997 | pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); |
2998 | pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); |
2999 | pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); |
3000 | } |
3001 | EXPORT_SYMBOL_GPL(phylink_ethtool_get_pauseparam); |
3002 | |
3003 | /** |
3004 | * phylink_ethtool_set_pauseparam() - set the current pause parameters |
3005 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
3006 | * @pause: a pointer to a &struct ethtool_pauseparam |
3007 | */ |
3008 | int phylink_ethtool_set_pauseparam(struct phylink *pl, |
3009 | struct ethtool_pauseparam *pause) |
3010 | { |
3011 | struct phylink_link_state *config = &pl->link_config; |
3012 | bool manual_changed; |
3013 | int pause_state; |
3014 | |
3015 | ASSERT_RTNL(); |
3016 | |
3017 | if (pl->req_link_an_mode == MLO_AN_FIXED) |
3018 | return -EOPNOTSUPP; |
3019 | |
3020 | if (!phylink_test(pl->supported, Pause) && |
3021 | !phylink_test(pl->supported, Asym_Pause)) |
3022 | return -EOPNOTSUPP; |
3023 | |
3024 | if (!phylink_test(pl->supported, Asym_Pause) && |
3025 | pause->rx_pause != pause->tx_pause) |
3026 | return -EINVAL; |
3027 | |
3028 | pause_state = 0; |
3029 | if (pause->autoneg) |
3030 | pause_state |= MLO_PAUSE_AN; |
3031 | if (pause->rx_pause) |
3032 | pause_state |= MLO_PAUSE_RX; |
3033 | if (pause->tx_pause) |
3034 | pause_state |= MLO_PAUSE_TX; |
3035 | |
3036 | mutex_lock(&pl->state_mutex); |
3037 | /* |
3038 | * See the comments for linkmode_set_pause(), wrt the deficiencies |
3039 | * with the current implementation. A solution to this issue would |
3040 | * be: |
3041 | * ethtool Local device |
3042 | * rx tx Pause AsymDir |
3043 | * 0 0 0 0 |
3044 | * 1 0 1 1 |
3045 | * 0 1 0 1 |
3046 | * 1 1 1 1 |
3047 | * and then use the ethtool rx/tx enablement status to mask the |
3048 | * rx/tx pause resolution. |
3049 | */ |
3050 | linkmode_set_pause(advertisement: config->advertising, tx: pause->tx_pause, |
3051 | rx: pause->rx_pause); |
3052 | |
3053 | manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN || |
3054 | (!(pause_state & MLO_PAUSE_AN) && |
3055 | (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK); |
3056 | |
3057 | config->pause = pause_state; |
3058 | |
3059 | /* Update our in-band advertisement, triggering a renegotiation if |
3060 | * the advertisement changed. |
3061 | */ |
3062 | if (!pl->phydev) |
3063 | phylink_change_inband_advert(pl); |
3064 | |
3065 | mutex_unlock(lock: &pl->state_mutex); |
3066 | |
3067 | /* If we have a PHY, a change of the pause frame advertisement will |
3068 | * cause phylib to renegotiate (if AN is enabled) which will in turn |
3069 | * call our phylink_phy_change() and trigger a resolve. Note that |
3070 | * we can't hold our state mutex while calling phy_set_asym_pause(). |
3071 | */ |
3072 | if (pl->phydev) |
3073 | phy_set_asym_pause(phydev: pl->phydev, rx: pause->rx_pause, |
3074 | tx: pause->tx_pause); |
3075 | |
3076 | /* If the manual pause settings changed, make sure we trigger a |
3077 | * resolve to update their state; we can not guarantee that the |
3078 | * link will cycle. |
3079 | */ |
3080 | if (manual_changed) { |
3081 | pl->link_failed = true; |
3082 | phylink_run_resolve(pl); |
3083 | } |
3084 | |
3085 | return 0; |
3086 | } |
3087 | EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam); |
3088 | |
3089 | /** |
3090 | * phylink_get_eee_err() - read the energy efficient ethernet error |
3091 | * counter |
3092 | * @pl: a pointer to a &struct phylink returned from phylink_create(). |
3093 | * |
3094 | * Read the Energy Efficient Ethernet error counter from the PHY associated |
3095 | * with the phylink instance specified by @pl. |
3096 | * |
3097 | * Returns positive error counter value, or negative error code. |
3098 | */ |
3099 | int phylink_get_eee_err(struct phylink *pl) |
3100 | { |
3101 | int ret = 0; |
3102 | |
3103 | ASSERT_RTNL(); |
3104 | |
3105 | if (pl->phydev) |
3106 | ret = phy_get_eee_err(phydev: pl->phydev); |
3107 | |
3108 | return ret; |
3109 | } |
3110 | EXPORT_SYMBOL_GPL(phylink_get_eee_err); |
3111 | |
3112 | /** |
3113 | * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters |
3114 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
3115 | * @eee: a pointer to a &struct ethtool_keee for the read parameters |
3116 | */ |
3117 | int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_keee *eee) |
3118 | { |
3119 | int ret = -EOPNOTSUPP; |
3120 | |
3121 | ASSERT_RTNL(); |
3122 | |
3123 | if (pl->mac_supports_eee_ops && !pl->mac_supports_eee) |
3124 | return ret; |
3125 | |
3126 | if (pl->phydev) { |
3127 | ret = phy_ethtool_get_eee(phydev: pl->phydev, data: eee); |
3128 | /* Restrict supported linkmode mask */ |
3129 | if (ret == 0 && pl->mac_supports_eee_ops) |
3130 | linkmode_and(dst: eee->supported, a: eee->supported, |
3131 | b: pl->supported_lpi); |
3132 | } |
3133 | |
3134 | return ret; |
3135 | } |
3136 | EXPORT_SYMBOL_GPL(phylink_ethtool_get_eee); |
3137 | |
3138 | /** |
3139 | * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters |
3140 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
3141 | * @eee: a pointer to a &struct ethtool_keee for the desired parameters |
3142 | */ |
3143 | int phylink_ethtool_set_eee(struct phylink *pl, struct ethtool_keee *eee) |
3144 | { |
3145 | bool mac_eee = pl->mac_supports_eee; |
3146 | int ret = -EOPNOTSUPP; |
3147 | |
3148 | ASSERT_RTNL(); |
3149 | |
3150 | phylink_dbg(pl, "mac %s phylink EEE%s, adv %*pbl, LPI%s timer %uus\n", |
3151 | mac_eee ? "supports": "does not support", |
3152 | eee->eee_enabled ? ", enabled": "", |
3153 | __ETHTOOL_LINK_MODE_MASK_NBITS, eee->advertised, |
3154 | eee->tx_lpi_enabled ? " enabled": "", eee->tx_lpi_timer); |
3155 | |
3156 | if (pl->mac_supports_eee_ops && !mac_eee) |
3157 | return ret; |
3158 | |
3159 | if (pl->phydev) { |
3160 | /* Restrict advertisement mask */ |
3161 | if (pl->mac_supports_eee_ops) |
3162 | linkmode_and(dst: eee->advertised, a: eee->advertised, |
3163 | b: pl->supported_lpi); |
3164 | ret = phy_ethtool_set_eee(phydev: pl->phydev, data: eee); |
3165 | if (ret == 0) |
3166 | eee_to_eeecfg(eeecfg: &pl->eee_cfg, eee); |
3167 | } |
3168 | |
3169 | return ret; |
3170 | } |
3171 | EXPORT_SYMBOL_GPL(phylink_ethtool_set_eee); |
3172 | |
3173 | /* This emulates MII registers for a fixed-mode phy operating as per the |
3174 | * passed in state. "aneg" defines if we report negotiation is possible. |
3175 | * |
3176 | * FIXME: should deal with negotiation state too. |
3177 | */ |
3178 | static int phylink_mii_emul_read(unsigned int reg, |
3179 | struct phylink_link_state *state) |
3180 | { |
3181 | struct fixed_phy_status fs; |
3182 | unsigned long *lpa = state->lp_advertising; |
3183 | int val; |
3184 | |
3185 | fs.link = state->link; |
3186 | fs.speed = state->speed; |
3187 | fs.duplex = state->duplex; |
3188 | fs.pause = test_bit(ETHTOOL_LINK_MODE_Pause_BIT, lpa); |
3189 | fs.asym_pause = test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, lpa); |
3190 | |
3191 | val = swphy_read_reg(reg, state: &fs); |
3192 | if (reg == MII_BMSR) { |
3193 | if (!state->an_complete) |
3194 | val &= ~BMSR_ANEGCOMPLETE; |
3195 | } |
3196 | return val; |
3197 | } |
3198 | |
3199 | static int phylink_phy_read(struct phylink *pl, unsigned int phy_id, |
3200 | unsigned int reg) |
3201 | { |
3202 | struct phy_device *phydev = pl->phydev; |
3203 | int prtad, devad; |
3204 | |
3205 | if (mdio_phy_id_is_c45(phy_id)) { |
3206 | prtad = mdio_phy_id_prtad(phy_id); |
3207 | devad = mdio_phy_id_devad(phy_id); |
3208 | return mdiobus_c45_read(bus: pl->phydev->mdio.bus, addr: prtad, devad, |
3209 | regnum: reg); |
3210 | } |
3211 | |
3212 | if (phydev->is_c45) { |
3213 | switch (reg) { |
3214 | case MII_BMCR: |
3215 | case MII_BMSR: |
3216 | case MII_PHYSID1: |
3217 | case MII_PHYSID2: |
3218 | devad = __ffs(phydev->c45_ids.mmds_present); |
3219 | break; |
3220 | case MII_ADVERTISE: |
3221 | case MII_LPA: |
3222 | if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) |
3223 | return -EINVAL; |
3224 | devad = MDIO_MMD_AN; |
3225 | if (reg == MII_ADVERTISE) |
3226 | reg = MDIO_AN_ADVERTISE; |
3227 | else |
3228 | reg = MDIO_AN_LPA; |
3229 | break; |
3230 | default: |
3231 | return -EINVAL; |
3232 | } |
3233 | prtad = phy_id; |
3234 | return mdiobus_c45_read(bus: pl->phydev->mdio.bus, addr: prtad, devad, |
3235 | regnum: reg); |
3236 | } |
3237 | |
3238 | return mdiobus_read(bus: pl->phydev->mdio.bus, addr: phy_id, regnum: reg); |
3239 | } |
3240 | |
3241 | static int phylink_phy_write(struct phylink *pl, unsigned int phy_id, |
3242 | unsigned int reg, unsigned int val) |
3243 | { |
3244 | struct phy_device *phydev = pl->phydev; |
3245 | int prtad, devad; |
3246 | |
3247 | if (mdio_phy_id_is_c45(phy_id)) { |
3248 | prtad = mdio_phy_id_prtad(phy_id); |
3249 | devad = mdio_phy_id_devad(phy_id); |
3250 | return mdiobus_c45_write(bus: pl->phydev->mdio.bus, addr: prtad, devad, |
3251 | regnum: reg, val); |
3252 | } |
3253 | |
3254 | if (phydev->is_c45) { |
3255 | switch (reg) { |
3256 | case MII_BMCR: |
3257 | case MII_BMSR: |
3258 | case MII_PHYSID1: |
3259 | case MII_PHYSID2: |
3260 | devad = __ffs(phydev->c45_ids.mmds_present); |
3261 | break; |
3262 | case MII_ADVERTISE: |
3263 | case MII_LPA: |
3264 | if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) |
3265 | return -EINVAL; |
3266 | devad = MDIO_MMD_AN; |
3267 | if (reg == MII_ADVERTISE) |
3268 | reg = MDIO_AN_ADVERTISE; |
3269 | else |
3270 | reg = MDIO_AN_LPA; |
3271 | break; |
3272 | default: |
3273 | return -EINVAL; |
3274 | } |
3275 | return mdiobus_c45_write(bus: pl->phydev->mdio.bus, addr: phy_id, devad, |
3276 | regnum: reg, val); |
3277 | } |
3278 | |
3279 | return mdiobus_write(bus: phydev->mdio.bus, addr: phy_id, regnum: reg, val); |
3280 | } |
3281 | |
3282 | static int phylink_mii_read(struct phylink *pl, unsigned int phy_id, |
3283 | unsigned int reg) |
3284 | { |
3285 | struct phylink_link_state state; |
3286 | int val = 0xffff; |
3287 | |
3288 | switch (pl->act_link_an_mode) { |
3289 | case MLO_AN_FIXED: |
3290 | if (phy_id == 0) { |
3291 | phylink_get_fixed_state(pl, state: &state); |
3292 | val = phylink_mii_emul_read(reg, state: &state); |
3293 | } |
3294 | break; |
3295 | |
3296 | case MLO_AN_PHY: |
3297 | return -EOPNOTSUPP; |
3298 | |
3299 | case MLO_AN_INBAND: |
3300 | if (phy_id == 0) { |
3301 | phylink_mac_pcs_get_state(pl, state: &state); |
3302 | val = phylink_mii_emul_read(reg, state: &state); |
3303 | } |
3304 | break; |
3305 | } |
3306 | |
3307 | return val & 0xffff; |
3308 | } |
3309 | |
3310 | static int phylink_mii_write(struct phylink *pl, unsigned int phy_id, |
3311 | unsigned int reg, unsigned int val) |
3312 | { |
3313 | switch (pl->act_link_an_mode) { |
3314 | case MLO_AN_FIXED: |
3315 | break; |
3316 | |
3317 | case MLO_AN_PHY: |
3318 | return -EOPNOTSUPP; |
3319 | |
3320 | case MLO_AN_INBAND: |
3321 | break; |
3322 | } |
3323 | |
3324 | return 0; |
3325 | } |
3326 | |
3327 | /** |
3328 | * phylink_mii_ioctl() - generic mii ioctl interface |
3329 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
3330 | * @ifr: a pointer to a &struct ifreq for socket ioctls |
3331 | * @cmd: ioctl cmd to execute |
3332 | * |
3333 | * Perform the specified MII ioctl on the PHY attached to the phylink instance |
3334 | * specified by @pl. If no PHY is attached, emulate the presence of the PHY. |
3335 | * |
3336 | * Returns: zero on success or negative error code. |
3337 | * |
3338 | * %SIOCGMIIPHY: |
3339 | * read register from the current PHY. |
3340 | * %SIOCGMIIREG: |
3341 | * read register from the specified PHY. |
3342 | * %SIOCSMIIREG: |
3343 | * set a register on the specified PHY. |
3344 | */ |
3345 | int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd) |
3346 | { |
3347 | struct mii_ioctl_data *mii = if_mii(rq: ifr); |
3348 | int ret; |
3349 | |
3350 | ASSERT_RTNL(); |
3351 | |
3352 | if (pl->phydev) { |
3353 | /* PHYs only exist for MLO_AN_PHY and SGMII */ |
3354 | switch (cmd) { |
3355 | case SIOCGMIIPHY: |
3356 | mii->phy_id = pl->phydev->mdio.addr; |
3357 | fallthrough; |
3358 | |
3359 | case SIOCGMIIREG: |
3360 | ret = phylink_phy_read(pl, phy_id: mii->phy_id, reg: mii->reg_num); |
3361 | if (ret >= 0) { |
3362 | mii->val_out = ret; |
3363 | ret = 0; |
3364 | } |
3365 | break; |
3366 | |
3367 | case SIOCSMIIREG: |
3368 | ret = phylink_phy_write(pl, phy_id: mii->phy_id, reg: mii->reg_num, |
3369 | val: mii->val_in); |
3370 | break; |
3371 | |
3372 | default: |
3373 | ret = phy_mii_ioctl(phydev: pl->phydev, ifr, cmd); |
3374 | break; |
3375 | } |
3376 | } else { |
3377 | switch (cmd) { |
3378 | case SIOCGMIIPHY: |
3379 | mii->phy_id = 0; |
3380 | fallthrough; |
3381 | |
3382 | case SIOCGMIIREG: |
3383 | ret = phylink_mii_read(pl, phy_id: mii->phy_id, reg: mii->reg_num); |
3384 | if (ret >= 0) { |
3385 | mii->val_out = ret; |
3386 | ret = 0; |
3387 | } |
3388 | break; |
3389 | |
3390 | case SIOCSMIIREG: |
3391 | ret = phylink_mii_write(pl, phy_id: mii->phy_id, reg: mii->reg_num, |
3392 | val: mii->val_in); |
3393 | break; |
3394 | |
3395 | default: |
3396 | ret = -EOPNOTSUPP; |
3397 | break; |
3398 | } |
3399 | } |
3400 | |
3401 | return ret; |
3402 | } |
3403 | EXPORT_SYMBOL_GPL(phylink_mii_ioctl); |
3404 | |
3405 | /** |
3406 | * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both |
3407 | * link partners |
3408 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
3409 | * @sync: perform action synchronously |
3410 | * |
3411 | * If we have a PHY that is not part of a SFP module, then set the speed |
3412 | * as described in the phy_speed_down() function. Please see this function |
3413 | * for a description of the @sync parameter. |
3414 | * |
3415 | * Returns zero if there is no PHY, otherwise as per phy_speed_down(). |
3416 | */ |
3417 | int phylink_speed_down(struct phylink *pl, bool sync) |
3418 | { |
3419 | int ret = 0; |
3420 | |
3421 | ASSERT_RTNL(); |
3422 | |
3423 | if (!pl->sfp_bus && pl->phydev) |
3424 | ret = phy_speed_down(phydev: pl->phydev, sync); |
3425 | |
3426 | return ret; |
3427 | } |
3428 | EXPORT_SYMBOL_GPL(phylink_speed_down); |
3429 | |
3430 | /** |
3431 | * phylink_speed_up() - restore the advertised speeds prior to the call to |
3432 | * phylink_speed_down() |
3433 | * @pl: a pointer to a &struct phylink returned from phylink_create() |
3434 | * |
3435 | * If we have a PHY that is not part of a SFP module, then restore the |
3436 | * PHY speeds as per phy_speed_up(). |
3437 | * |
3438 | * Returns zero if there is no PHY, otherwise as per phy_speed_up(). |
3439 | */ |
3440 | int phylink_speed_up(struct phylink *pl) |
3441 | { |
3442 | int ret = 0; |
3443 | |
3444 | ASSERT_RTNL(); |
3445 | |
3446 | if (!pl->sfp_bus && pl->phydev) |
3447 | ret = phy_speed_up(phydev: pl->phydev); |
3448 | |
3449 | return ret; |
3450 | } |
3451 | EXPORT_SYMBOL_GPL(phylink_speed_up); |
3452 | |
3453 | static void phylink_sfp_attach(void *upstream, struct sfp_bus *bus) |
3454 | { |
3455 | struct phylink *pl = upstream; |
3456 | |
3457 | pl->netdev->sfp_bus = bus; |
3458 | } |
3459 | |
3460 | static void phylink_sfp_detach(void *upstream, struct sfp_bus *bus) |
3461 | { |
3462 | struct phylink *pl = upstream; |
3463 | |
3464 | pl->netdev->sfp_bus = NULL; |
3465 | } |
3466 | |
3467 | static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl, |
3468 | const unsigned long *intf) |
3469 | { |
3470 | phy_interface_t interface; |
3471 | size_t i; |
3472 | |
3473 | interface = PHY_INTERFACE_MODE_NA; |
3474 | for (i = 0; i < ARRAY_SIZE(phylink_sfp_interface_preference); i++) |
3475 | if (test_bit(phylink_sfp_interface_preference[i], intf)) { |
3476 | interface = phylink_sfp_interface_preference[i]; |
3477 | break; |
3478 | } |
3479 | |
3480 | return interface; |
3481 | } |
3482 | |
3483 | static void phylink_sfp_set_config(struct phylink *pl, unsigned long *supported, |
3484 | struct phylink_link_state *state, |
3485 | bool changed) |
3486 | { |
3487 | u8 mode = MLO_AN_INBAND; |
3488 | |
3489 | phylink_dbg(pl, "requesting link mode %s/%s with support %*pb\n", |
3490 | phylink_an_mode_str(mode), phy_modes(state->interface), |
3491 | __ETHTOOL_LINK_MODE_MASK_NBITS, supported); |
3492 | |
3493 | if (!linkmode_equal(src1: pl->supported, src2: supported)) { |
3494 | linkmode_copy(dst: pl->supported, src: supported); |
3495 | changed = true; |
3496 | } |
3497 | |
3498 | if (!linkmode_equal(src1: pl->link_config.advertising, src2: state->advertising)) { |
3499 | linkmode_copy(dst: pl->link_config.advertising, src: state->advertising); |
3500 | changed = true; |
3501 | } |
3502 | |
3503 | if (pl->req_link_an_mode != mode || |
3504 | pl->link_config.interface != state->interface) { |
3505 | pl->req_link_an_mode = mode; |
3506 | pl->link_config.interface = state->interface; |
3507 | |
3508 | changed = true; |
3509 | |
3510 | phylink_info(pl, "switched to %s/%s link mode\n", |
3511 | phylink_an_mode_str(mode), |
3512 | phy_modes(state->interface)); |
3513 | } |
3514 | |
3515 | if (changed && !test_bit(PHYLINK_DISABLE_STOPPED, |
3516 | &pl->phylink_disable_state)) |
3517 | phylink_mac_initial_config(pl, force_restart: false); |
3518 | } |
3519 | |
3520 | static int phylink_sfp_config_phy(struct phylink *pl, struct phy_device *phy) |
3521 | { |
3522 | __ETHTOOL_DECLARE_LINK_MODE_MASK(support); |
3523 | struct phylink_link_state config; |
3524 | int ret; |
3525 | |
3526 | linkmode_copy(dst: support, src: phy->supported); |
3527 | |
3528 | memset(&config, 0, sizeof(config)); |
3529 | linkmode_copy(dst: config.advertising, src: phy->advertising); |
3530 | config.interface = PHY_INTERFACE_MODE_NA; |
3531 | config.speed = SPEED_UNKNOWN; |
3532 | config.duplex = DUPLEX_UNKNOWN; |
3533 | config.pause = MLO_PAUSE_AN; |
3534 | |
3535 | /* Ignore errors if we're expecting a PHY to attach later */ |
3536 | ret = phylink_validate(pl, supported: support, state: &config); |
3537 | if (ret) { |
3538 | phylink_err(pl, "validation with support %*pb failed: %pe\n", |
3539 | __ETHTOOL_LINK_MODE_MASK_NBITS, support, |
3540 | ERR_PTR(ret)); |
3541 | return ret; |
3542 | } |
3543 | |
3544 | config.interface = phylink_sfp_select_interface(pl, link_modes: config.advertising); |
3545 | if (config.interface == PHY_INTERFACE_MODE_NA) |
3546 | return -EINVAL; |
3547 | |
3548 | /* Attach the PHY so that the PHY is present when we do the major |
3549 | * configuration step. |
3550 | */ |
3551 | ret = phylink_attach_phy(pl, phy, interface: config.interface); |
3552 | if (ret < 0) |
3553 | return ret; |
3554 | |
3555 | /* This will validate the configuration for us. */ |
3556 | ret = phylink_bringup_phy(pl, phy, interface: config.interface); |
3557 | if (ret < 0) { |
3558 | phy_detach(phydev: phy); |
3559 | return ret; |
3560 | } |
3561 | |
3562 | pl->link_port = pl->sfp_port; |
3563 | |
3564 | phylink_sfp_set_config(pl, supported: support, state: &config, changed: true); |
3565 | |
3566 | return 0; |
3567 | } |
3568 | |
3569 | static int phylink_sfp_config_optical(struct phylink *pl) |
3570 | { |
3571 | __ETHTOOL_DECLARE_LINK_MODE_MASK(support); |
3572 | DECLARE_PHY_INTERFACE_MASK(interfaces); |
3573 | struct phylink_link_state config; |
3574 | phy_interface_t interface; |
3575 | int ret; |
3576 | |
3577 | phylink_dbg(pl, "optical SFP: interfaces=[mac=%*pbl, sfp=%*pbl]\n", |
3578 | (int)PHY_INTERFACE_MODE_MAX, |
3579 | pl->config->supported_interfaces, |
3580 | (int)PHY_INTERFACE_MODE_MAX, |
3581 | pl->sfp_interfaces); |
3582 | |
3583 | /* Find the union of the supported interfaces by the PCS/MAC and |
3584 | * the SFP module. |
3585 | */ |
3586 | phy_interface_and(dst: interfaces, a: pl->config->supported_interfaces, |
3587 | b: pl->sfp_interfaces); |
3588 | if (phy_interface_empty(intf: interfaces)) { |
3589 | phylink_err(pl, "unsupported SFP module: no common interface modes\n"); |
3590 | return -EINVAL; |
3591 | } |
3592 | |
3593 | memset(&config, 0, sizeof(config)); |
3594 | linkmode_copy(dst: support, src: pl->sfp_support); |
3595 | linkmode_copy(dst: config.advertising, src: pl->sfp_support); |
3596 | config.speed = SPEED_UNKNOWN; |
3597 | config.duplex = DUPLEX_UNKNOWN; |
3598 | config.pause = MLO_PAUSE_AN; |
3599 | |
3600 | /* For all the interfaces that are supported, reduce the sfp_support |
3601 | * mask to only those link modes that can be supported. |
3602 | */ |
3603 | ret = phylink_validate_mask(pl, NULL, supported: pl->sfp_support, state: &config, |
3604 | interfaces); |
3605 | if (ret) { |
3606 | phylink_err(pl, "unsupported SFP module: validation with support %*pb failed\n", |
3607 | __ETHTOOL_LINK_MODE_MASK_NBITS, support); |
3608 | return ret; |
3609 | } |
3610 | |
3611 | interface = phylink_choose_sfp_interface(pl, intf: interfaces); |
3612 | if (interface == PHY_INTERFACE_MODE_NA) { |
3613 | phylink_err(pl, "failed to select SFP interface\n"); |
3614 | return -EINVAL; |
3615 | } |
3616 | |
3617 | phylink_dbg(pl, "optical SFP: chosen %s interface\n", |
3618 | phy_modes(interface)); |
3619 | |
3620 | if (!phylink_validate_pcs_inband_autoneg(pl, interface, |
3621 | adv: config.advertising)) { |
3622 | phylink_err(pl, "autoneg setting not compatible with PCS"); |
3623 | return -EINVAL; |
3624 | } |
3625 | |
3626 | config.interface = interface; |
3627 | |
3628 | /* Ignore errors if we're expecting a PHY to attach later */ |
3629 | ret = phylink_validate(pl, supported: support, state: &config); |
3630 | if (ret) { |
3631 | phylink_err(pl, "validation with support %*pb failed: %pe\n", |
3632 | __ETHTOOL_LINK_MODE_MASK_NBITS, support, |
3633 | ERR_PTR(ret)); |
3634 | return ret; |
3635 | } |
3636 | |
3637 | pl->link_port = pl->sfp_port; |
3638 | |
3639 | phylink_sfp_set_config(pl, supported: pl->sfp_support, state: &config, changed: false); |
3640 | |
3641 | return 0; |
3642 | } |
3643 | |
3644 | static int phylink_sfp_module_insert(void *upstream, |
3645 | const struct sfp_eeprom_id *id) |
3646 | { |
3647 | struct phylink *pl = upstream; |
3648 | |
3649 | ASSERT_RTNL(); |
3650 | |
3651 | linkmode_zero(dst: pl->sfp_support); |
3652 | phy_interface_zero(intf: pl->sfp_interfaces); |
3653 | sfp_parse_support(bus: pl->sfp_bus, id, support: pl->sfp_support, interfaces: pl->sfp_interfaces); |
3654 | pl->sfp_port = sfp_parse_port(bus: pl->sfp_bus, id, support: pl->sfp_support); |
3655 | |
3656 | /* If this module may have a PHY connecting later, defer until later */ |
3657 | pl->sfp_may_have_phy = sfp_may_have_phy(bus: pl->sfp_bus, id); |
3658 | if (pl->sfp_may_have_phy) |
3659 | return 0; |
3660 | |
3661 | return phylink_sfp_config_optical(pl); |
3662 | } |
3663 | |
3664 | static int phylink_sfp_module_start(void *upstream) |
3665 | { |
3666 | struct phylink *pl = upstream; |
3667 | |
3668 | /* If this SFP module has a PHY, start the PHY now. */ |
3669 | if (pl->phydev) { |
3670 | phy_start(phydev: pl->phydev); |
3671 | return 0; |
3672 | } |
3673 | |
3674 | /* If the module may have a PHY but we didn't detect one we |
3675 | * need to configure the MAC here. |
3676 | */ |
3677 | if (!pl->sfp_may_have_phy) |
3678 | return 0; |
3679 | |
3680 | return phylink_sfp_config_optical(pl); |
3681 | } |
3682 | |
3683 | static void phylink_sfp_module_stop(void *upstream) |
3684 | { |
3685 | struct phylink *pl = upstream; |
3686 | |
3687 | /* If this SFP module has a PHY, stop it. */ |
3688 | if (pl->phydev) |
3689 | phy_stop(phydev: pl->phydev); |
3690 | } |
3691 | |
3692 | static void phylink_sfp_link_down(void *upstream) |
3693 | { |
3694 | struct phylink *pl = upstream; |
3695 | |
3696 | ASSERT_RTNL(); |
3697 | |
3698 | phylink_run_resolve_and_disable(pl, bit: PHYLINK_DISABLE_LINK); |
3699 | } |
3700 | |
3701 | static void phylink_sfp_link_up(void *upstream) |
3702 | { |
3703 | struct phylink *pl = upstream; |
3704 | |
3705 | ASSERT_RTNL(); |
3706 | |
3707 | phylink_enable_and_run_resolve(pl, bit: PHYLINK_DISABLE_LINK); |
3708 | } |
3709 | |
3710 | static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) |
3711 | { |
3712 | struct phylink *pl = upstream; |
3713 | |
3714 | if (!phy->drv) { |
3715 | phylink_err(pl, "PHY %s (id 0x%.8lx) has no driver loaded\n", |
3716 | phydev_name(phy), (unsigned long)phy->phy_id); |
3717 | phylink_err(pl, "Drivers which handle known common cases: CONFIG_BCM84881_PHY, CONFIG_MARVELL_PHY\n"); |
3718 | return -EINVAL; |
3719 | } |
3720 | |
3721 | /* |
3722 | * This is the new way of dealing with flow control for PHYs, |
3723 | * as described by Timur Tabi in commit 529ed1275263 ("net: phy: |
3724 | * phy drivers should not set SUPPORTED_[Asym_]Pause") except |
3725 | * using our validate call to the MAC, we rely upon the MAC |
3726 | * clearing the bits from both supported and advertising fields. |
3727 | */ |
3728 | phy_support_asym_pause(phydev: phy); |
3729 | |
3730 | /* Set the PHY's host supported interfaces */ |
3731 | phy_interface_and(dst: phy->host_interfaces, a: phylink_sfp_interfaces, |
3732 | b: pl->config->supported_interfaces); |
3733 | |
3734 | /* Do the initial configuration */ |
3735 | return phylink_sfp_config_phy(pl, phy); |
3736 | } |
3737 | |
3738 | static void phylink_sfp_disconnect_phy(void *upstream, |
3739 | struct phy_device *phydev) |
3740 | { |
3741 | phylink_disconnect_phy(upstream); |
3742 | } |
3743 | |
3744 | static const struct sfp_upstream_ops sfp_phylink_ops = { |
3745 | .attach = phylink_sfp_attach, |
3746 | .detach = phylink_sfp_detach, |
3747 | .module_insert = phylink_sfp_module_insert, |
3748 | .module_start = phylink_sfp_module_start, |
3749 | .module_stop = phylink_sfp_module_stop, |
3750 | .link_up = phylink_sfp_link_up, |
3751 | .link_down = phylink_sfp_link_down, |
3752 | .connect_phy = phylink_sfp_connect_phy, |
3753 | .disconnect_phy = phylink_sfp_disconnect_phy, |
3754 | }; |
3755 | |
3756 | /* Helpers for MAC drivers */ |
3757 | |
3758 | static struct { |
3759 | int bit; |
3760 | int speed; |
3761 | } phylink_c73_priority_resolution[] = { |
3762 | { ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, SPEED_100000 }, |
3763 | { ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, SPEED_100000 }, |
3764 | /* 100GBASE-KP4 and 100GBASE-CR10 not supported */ |
3765 | { ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, SPEED_40000 }, |
3766 | { ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, SPEED_40000 }, |
3767 | { ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, SPEED_10000 }, |
3768 | { ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, SPEED_10000 }, |
3769 | /* 5GBASE-KR not supported */ |
3770 | { ETHTOOL_LINK_MODE_2500baseX_Full_BIT, SPEED_2500 }, |
3771 | { ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, SPEED_1000 }, |
3772 | }; |
3773 | |
3774 | void phylink_resolve_c73(struct phylink_link_state *state) |
3775 | { |
3776 | int i; |
3777 | |
3778 | for (i = 0; i < ARRAY_SIZE(phylink_c73_priority_resolution); i++) { |
3779 | int bit = phylink_c73_priority_resolution[i].bit; |
3780 | if (linkmode_test_bit(bit, state->advertising) && |
3781 | linkmode_test_bit(bit, state->lp_advertising)) |
3782 | break; |
3783 | } |
3784 | |
3785 | if (i < ARRAY_SIZE(phylink_c73_priority_resolution)) { |
3786 | state->speed = phylink_c73_priority_resolution[i].speed; |
3787 | state->duplex = DUPLEX_FULL; |
3788 | } else { |
3789 | /* negotiation failure */ |
3790 | state->link = false; |
3791 | } |
3792 | |
3793 | phylink_resolve_an_pause(state); |
3794 | } |
3795 | EXPORT_SYMBOL_GPL(phylink_resolve_c73); |
3796 | |
3797 | static void phylink_decode_c37_word(struct phylink_link_state *state, |
3798 | uint16_t config_reg, int speed) |
3799 | { |
3800 | int fd_bit; |
3801 | |
3802 | if (speed == SPEED_2500) |
3803 | fd_bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT; |
3804 | else |
3805 | fd_bit = ETHTOOL_LINK_MODE_1000baseX_Full_BIT; |
3806 | |
3807 | mii_lpa_mod_linkmode_x(linkmodes: state->lp_advertising, lpa: config_reg, fd_bit); |
3808 | |
3809 | if (linkmode_test_bit(fd_bit, state->advertising) && |
3810 | linkmode_test_bit(fd_bit, state->lp_advertising)) { |
3811 | state->speed = speed; |
3812 | state->duplex = DUPLEX_FULL; |
3813 | } else { |
3814 | /* negotiation failure */ |
3815 | state->link = false; |
3816 | } |
3817 | |
3818 | phylink_resolve_an_pause(state); |
3819 | } |
3820 | |
3821 | static void phylink_decode_sgmii_word(struct phylink_link_state *state, |
3822 | uint16_t config_reg) |
3823 | { |
3824 | if (!(config_reg & LPA_SGMII_LINK)) { |
3825 | state->link = false; |
3826 | return; |
3827 | } |
3828 | |
3829 | switch (config_reg & LPA_SGMII_SPD_MASK) { |
3830 | case LPA_SGMII_10: |
3831 | state->speed = SPEED_10; |
3832 | break; |
3833 | case LPA_SGMII_100: |
3834 | state->speed = SPEED_100; |
3835 | break; |
3836 | case LPA_SGMII_1000: |
3837 | state->speed = SPEED_1000; |
3838 | break; |
3839 | default: |
3840 | state->link = false; |
3841 | return; |
3842 | } |
3843 | if (config_reg & LPA_SGMII_FULL_DUPLEX) |
3844 | state->duplex = DUPLEX_FULL; |
3845 | else |
3846 | state->duplex = DUPLEX_HALF; |
3847 | } |
3848 | |
3849 | /** |
3850 | * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS |
3851 | * @state: a pointer to a struct phylink_link_state. |
3852 | * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word |
3853 | * |
3854 | * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation |
3855 | * code word. Decode the USXGMII code word and populate the corresponding fields |
3856 | * (speed, duplex) into the phylink_link_state structure. |
3857 | */ |
3858 | void phylink_decode_usxgmii_word(struct phylink_link_state *state, |
3859 | uint16_t lpa) |
3860 | { |
3861 | switch (lpa & MDIO_USXGMII_SPD_MASK) { |
3862 | case MDIO_USXGMII_10: |
3863 | state->speed = SPEED_10; |
3864 | break; |
3865 | case MDIO_USXGMII_100: |
3866 | state->speed = SPEED_100; |
3867 | break; |
3868 | case MDIO_USXGMII_1000: |
3869 | state->speed = SPEED_1000; |
3870 | break; |
3871 | case MDIO_USXGMII_2500: |
3872 | state->speed = SPEED_2500; |
3873 | break; |
3874 | case MDIO_USXGMII_5000: |
3875 | state->speed = SPEED_5000; |
3876 | break; |
3877 | case MDIO_USXGMII_10G: |
3878 | state->speed = SPEED_10000; |
3879 | break; |
3880 | default: |
3881 | state->link = false; |
3882 | return; |
3883 | } |
3884 | |
3885 | if (lpa & MDIO_USXGMII_FULL_DUPLEX) |
3886 | state->duplex = DUPLEX_FULL; |
3887 | else |
3888 | state->duplex = DUPLEX_HALF; |
3889 | } |
3890 | EXPORT_SYMBOL_GPL(phylink_decode_usxgmii_word); |
3891 | |
3892 | /** |
3893 | * phylink_decode_usgmii_word() - decode the USGMII word from a MAC PCS |
3894 | * @state: a pointer to a struct phylink_link_state. |
3895 | * @lpa: a 16 bit value which stores the USGMII auto-negotiation word |
3896 | * |
3897 | * Helper for MAC PCS supporting the USGMII protocol and the auto-negotiation |
3898 | * code word. Decode the USGMII code word and populate the corresponding fields |
3899 | * (speed, duplex) into the phylink_link_state structure. The structure for this |
3900 | * word is the same as the USXGMII word, except it only supports speeds up to |
3901 | * 1Gbps. |
3902 | */ |
3903 | static void phylink_decode_usgmii_word(struct phylink_link_state *state, |
3904 | uint16_t lpa) |
3905 | { |
3906 | switch (lpa & MDIO_USXGMII_SPD_MASK) { |
3907 | case MDIO_USXGMII_10: |
3908 | state->speed = SPEED_10; |
3909 | break; |
3910 | case MDIO_USXGMII_100: |
3911 | state->speed = SPEED_100; |
3912 | break; |
3913 | case MDIO_USXGMII_1000: |
3914 | state->speed = SPEED_1000; |
3915 | break; |
3916 | default: |
3917 | state->link = false; |
3918 | return; |
3919 | } |
3920 | |
3921 | if (lpa & MDIO_USXGMII_FULL_DUPLEX) |
3922 | state->duplex = DUPLEX_FULL; |
3923 | else |
3924 | state->duplex = DUPLEX_HALF; |
3925 | } |
3926 | |
3927 | /** |
3928 | * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers |
3929 | * @state: a pointer to a &struct phylink_link_state. |
3930 | * @neg_mode: link negotiation mode (PHYLINK_PCS_NEG_xxx) |
3931 | * @bmsr: The value of the %MII_BMSR register |
3932 | * @lpa: The value of the %MII_LPA register |
3933 | * |
3934 | * Helper for MAC PCS supporting the 802.3 clause 22 register set for |
3935 | * clause 37 negotiation and/or SGMII control. |
3936 | * |
3937 | * Parse the Clause 37 or Cisco SGMII link partner negotiation word into |
3938 | * the phylink @state structure. This is suitable to be used for implementing |
3939 | * the pcs_get_state() member of the struct phylink_pcs_ops structure if |
3940 | * accessing @bmsr and @lpa cannot be done with MDIO directly. |
3941 | */ |
3942 | void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, |
3943 | unsigned int neg_mode, u16 bmsr, u16 lpa) |
3944 | { |
3945 | state->link = !!(bmsr & BMSR_LSTATUS); |
3946 | state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); |
3947 | |
3948 | /* If the link is down, the advertisement data is undefined. */ |
3949 | if (!state->link) |
3950 | return; |
3951 | |
3952 | switch (state->interface) { |
3953 | case PHY_INTERFACE_MODE_1000BASEX: |
3954 | if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { |
3955 | phylink_decode_c37_word(state, config_reg: lpa, SPEED_1000); |
3956 | } else { |
3957 | state->speed = SPEED_1000; |
3958 | state->duplex = DUPLEX_FULL; |
3959 | state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX; |
3960 | } |
3961 | break; |
3962 | |
3963 | case PHY_INTERFACE_MODE_2500BASEX: |
3964 | if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { |
3965 | phylink_decode_c37_word(state, config_reg: lpa, SPEED_2500); |
3966 | } else { |
3967 | state->speed = SPEED_2500; |
3968 | state->duplex = DUPLEX_FULL; |
3969 | state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX; |
3970 | } |
3971 | break; |
3972 | |
3973 | case PHY_INTERFACE_MODE_SGMII: |
3974 | case PHY_INTERFACE_MODE_QSGMII: |
3975 | if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) |
3976 | phylink_decode_sgmii_word(state, config_reg: lpa); |
3977 | break; |
3978 | |
3979 | case PHY_INTERFACE_MODE_QUSGMII: |
3980 | if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) |
3981 | phylink_decode_usgmii_word(state, lpa); |
3982 | break; |
3983 | |
3984 | default: |
3985 | state->link = false; |
3986 | break; |
3987 | } |
3988 | } |
3989 | EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state); |
3990 | |
3991 | /** |
3992 | * phylink_mii_c22_pcs_get_state() - read the MAC PCS state |
3993 | * @pcs: a pointer to a &struct mdio_device. |
3994 | * @neg_mode: link negotiation mode (PHYLINK_PCS_NEG_xxx) |
3995 | * @state: a pointer to a &struct phylink_link_state. |
3996 | * |
3997 | * Helper for MAC PCS supporting the 802.3 clause 22 register set for |
3998 | * clause 37 negotiation and/or SGMII control. |
3999 | * |
4000 | * Read the MAC PCS state from the MII device configured in @config and |
4001 | * parse the Clause 37 or Cisco SGMII link partner negotiation word into |
4002 | * the phylink @state structure. This is suitable to be directly plugged |
4003 | * into the pcs_get_state() member of the struct phylink_pcs_ops |
4004 | * structure. |
4005 | */ |
4006 | void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs, |
4007 | unsigned int neg_mode, |
4008 | struct phylink_link_state *state) |
4009 | { |
4010 | int bmsr, lpa; |
4011 | |
4012 | bmsr = mdiodev_read(mdiodev: pcs, MII_BMSR); |
4013 | lpa = mdiodev_read(mdiodev: pcs, MII_LPA); |
4014 | if (bmsr < 0 || lpa < 0) { |
4015 | state->link = false; |
4016 | return; |
4017 | } |
4018 | |
4019 | phylink_mii_c22_pcs_decode_state(state, neg_mode, bmsr, lpa); |
4020 | } |
4021 | EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state); |
4022 | |
4023 | /** |
4024 | * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS |
4025 | * advertisement |
4026 | * @interface: the PHY interface mode being configured |
4027 | * @advertising: the ethtool advertisement mask |
4028 | * |
4029 | * Helper for MAC PCS supporting the 802.3 clause 22 register set for |
4030 | * clause 37 negotiation and/or SGMII control. |
4031 | * |
4032 | * Encode the clause 37 PCS advertisement as specified by @interface and |
4033 | * @advertising. |
4034 | * |
4035 | * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed. |
4036 | */ |
4037 | int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, |
4038 | const unsigned long *advertising) |
4039 | { |
4040 | u16 adv; |
4041 | |
4042 | switch (interface) { |
4043 | case PHY_INTERFACE_MODE_1000BASEX: |
4044 | case PHY_INTERFACE_MODE_2500BASEX: |
4045 | adv = ADVERTISE_1000XFULL; |
4046 | if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
4047 | advertising)) |
4048 | adv |= ADVERTISE_1000XPAUSE; |
4049 | if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
4050 | advertising)) |
4051 | adv |= ADVERTISE_1000XPSE_ASYM; |
4052 | return adv; |
4053 | case PHY_INTERFACE_MODE_SGMII: |
4054 | case PHY_INTERFACE_MODE_QSGMII: |
4055 | return 0x0001; |
4056 | default: |
4057 | /* Nothing to do for other modes */ |
4058 | return -EINVAL; |
4059 | } |
4060 | } |
4061 | EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement); |
4062 | |
4063 | /** |
4064 | * phylink_mii_c22_pcs_config() - configure clause 22 PCS |
4065 | * @pcs: a pointer to a &struct mdio_device. |
4066 | * @interface: the PHY interface mode being configured |
4067 | * @advertising: the ethtool advertisement mask |
4068 | * @neg_mode: PCS negotiation mode |
4069 | * |
4070 | * Configure a Clause 22 PCS PHY with the appropriate negotiation |
4071 | * parameters for the @mode, @interface and @advertising parameters. |
4072 | * Returns negative error number on failure, zero if the advertisement |
4073 | * has not changed, or positive if there is a change. |
4074 | */ |
4075 | int phylink_mii_c22_pcs_config(struct mdio_device *pcs, |
4076 | phy_interface_t interface, |
4077 | const unsigned long *advertising, |
4078 | unsigned int neg_mode) |
4079 | { |
4080 | bool changed = 0; |
4081 | u16 bmcr; |
4082 | int ret, adv; |
4083 | |
4084 | adv = phylink_mii_c22_pcs_encode_advertisement(interface, advertising); |
4085 | if (adv >= 0) { |
4086 | ret = mdiobus_modify_changed(bus: pcs->bus, addr: pcs->addr, |
4087 | MII_ADVERTISE, mask: 0xffff, set: adv); |
4088 | if (ret < 0) |
4089 | return ret; |
4090 | changed = ret; |
4091 | } |
4092 | |
4093 | if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) |
4094 | bmcr = BMCR_ANENABLE; |
4095 | else |
4096 | bmcr = 0; |
4097 | |
4098 | /* Configure the inband state. Ensure ISOLATE bit is disabled */ |
4099 | ret = mdiodev_modify(mdiodev: pcs, MII_BMCR, BMCR_ANENABLE | BMCR_ISOLATE, set: bmcr); |
4100 | if (ret < 0) |
4101 | return ret; |
4102 | |
4103 | return changed; |
4104 | } |
4105 | EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_config); |
4106 | |
4107 | /** |
4108 | * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation |
4109 | * @pcs: a pointer to a &struct mdio_device. |
4110 | * |
4111 | * Helper for MAC PCS supporting the 802.3 clause 22 register set for |
4112 | * clause 37 negotiation. |
4113 | * |
4114 | * Restart the clause 37 negotiation with the link partner. This is |
4115 | * suitable to be directly plugged into the pcs_get_state() member |
4116 | * of the struct phylink_pcs_ops structure. |
4117 | */ |
4118 | void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs) |
4119 | { |
4120 | int val = mdiodev_read(mdiodev: pcs, MII_BMCR); |
4121 | |
4122 | if (val >= 0) { |
4123 | val |= BMCR_ANRESTART; |
4124 | |
4125 | mdiodev_write(mdiodev: pcs, MII_BMCR, val); |
4126 | } |
4127 | } |
4128 | EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_an_restart); |
4129 | |
4130 | void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs, |
4131 | struct phylink_link_state *state) |
4132 | { |
4133 | struct mii_bus *bus = pcs->bus; |
4134 | int addr = pcs->addr; |
4135 | int stat; |
4136 | |
4137 | stat = mdiobus_c45_read(bus, addr, MDIO_MMD_PCS, MDIO_STAT1); |
4138 | if (stat < 0) { |
4139 | state->link = false; |
4140 | return; |
4141 | } |
4142 | |
4143 | state->link = !!(stat & MDIO_STAT1_LSTATUS); |
4144 | if (!state->link) |
4145 | return; |
4146 | |
4147 | switch (state->interface) { |
4148 | case PHY_INTERFACE_MODE_10GBASER: |
4149 | state->speed = SPEED_10000; |
4150 | state->duplex = DUPLEX_FULL; |
4151 | break; |
4152 | |
4153 | default: |
4154 | break; |
4155 | } |
4156 | } |
4157 | EXPORT_SYMBOL_GPL(phylink_mii_c45_pcs_get_state); |
4158 | |
4159 | static int __init phylink_init(void) |
4160 | { |
4161 | for (int i = 0; i < ARRAY_SIZE(phylink_sfp_interface_preference); ++i) |
4162 | __set_bit(phylink_sfp_interface_preference[i], |
4163 | phylink_sfp_interfaces); |
4164 | |
4165 | return 0; |
4166 | } |
4167 | |
4168 | module_init(phylink_init); |
4169 | |
4170 | MODULE_LICENSE("GPL v2"); |
4171 | MODULE_DESCRIPTION("phylink models the MAC to optional PHY connection"); |
4172 |
Definitions
- phylink
- phylink_sfp_interface_preference
- phylink_sfp_interfaces
- phylink_set_port_modes
- phylink_is_empty_linkmode
- phylink_an_mode_str
- phylink_pcs_mode_str
- phylink_interface_signal_rate
- phylink_interface_max_speed
- phylink_caps_params
- phylink_caps_to_link_caps
- phylink_link_caps_to_mac_caps
- phylink_caps_to_linkmodes
- phylink_limit_mac_speed
- phylink_cap_from_speed_duplex
- phylink_get_capabilities
- phylink_validate_mask_caps
- phylink_validate_mac_and_pcs
- phylink_validate_one
- phylink_validate_mask
- phylink_validate
- phylink_fill_fixedlink_supported
- phylink_parse_fixedlink
- phylink_parse_mode
- phylink_apply_manual_flow
- phylink_resolve_an_pause
- phylink_pcs_inband_caps
- phylink_pcs_pre_config
- phylink_pcs_post_config
- phylink_pcs_disable
- phylink_pcs_enable
- phylink_pcs_config
- phylink_pcs_link_up
- phylink_pcs_disable_eee
- phylink_pcs_enable_eee
- phylink_inband_caps
- phylink_pcs_poll_stop
- phylink_pcs_poll_start
- phylink_pcs_pre_init
- phylink_mac_config
- phylink_pcs_an_restart
- phylink_pcs_neg_mode
- phylink_major_config
- phylink_change_inband_advert
- phylink_mac_pcs_get_state
- phylink_get_fixed_state
- phylink_mac_initial_config
- phylink_pause_to_str
- phylink_deactivate_lpi
- phylink_activate_lpi
- phylink_link_up
- phylink_link_down
- phylink_link_is_up
- phylink_resolve
- phylink_run_resolve
- phylink_run_resolve_and_disable
- phylink_enable_and_run_resolve
- phylink_fixed_poll
- sfp_phylink_ops
- phylink_register_sfp
- phylink_set_fixed_link
- phylink_create
- phylink_destroy
- phylink_expects_phy
- phylink_phy_change
- phylink_validate_phy
- phylink_bringup_phy
- phylink_attach_phy
- phylink_connect_phy
- phylink_of_phy_connect
- phylink_fwnode_phy_connect
- phylink_disconnect_phy
- phylink_link_changed
- phylink_mac_change
- phylink_pcs_change
- phylink_link_handler
- phylink_start
- phylink_stop
- phylink_rx_clk_stop_block
- phylink_rx_clk_stop_unblock
- phylink_suspend
- phylink_prepare_resume
- phylink_resume
- phylink_ethtool_get_wol
- phylink_ethtool_set_wol
- phylink_sfp_select_interface
- phylink_merge_link_mode
- phylink_get_ksettings
- phylink_ethtool_ksettings_get
- phylink_validate_pcs_inband_autoneg
- phylink_ethtool_ksettings_set
- phylink_ethtool_nway_reset
- phylink_ethtool_get_pauseparam
- phylink_ethtool_set_pauseparam
- phylink_get_eee_err
- phylink_ethtool_get_eee
- phylink_ethtool_set_eee
- phylink_mii_emul_read
- phylink_phy_read
- phylink_phy_write
- phylink_mii_read
- phylink_mii_write
- phylink_mii_ioctl
- phylink_speed_down
- phylink_speed_up
- phylink_sfp_attach
- phylink_sfp_detach
- phylink_choose_sfp_interface
- phylink_sfp_set_config
- phylink_sfp_config_phy
- phylink_sfp_config_optical
- phylink_sfp_module_insert
- phylink_sfp_module_start
- phylink_sfp_module_stop
- phylink_sfp_link_down
- phylink_sfp_link_up
- phylink_sfp_connect_phy
- phylink_sfp_disconnect_phy
- sfp_phylink_ops
- phylink_c73_priority_resolution
- phylink_resolve_c73
- phylink_decode_c37_word
- phylink_decode_sgmii_word
- phylink_decode_usxgmii_word
- phylink_decode_usgmii_word
- phylink_mii_c22_pcs_decode_state
- phylink_mii_c22_pcs_get_state
- phylink_mii_c22_pcs_encode_advertisement
- phylink_mii_c22_pcs_config
- phylink_mii_c22_pcs_an_restart
- phylink_mii_c45_pcs_get_state
Improve your Profiling and Debugging skills
Find out more