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