hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/net/phy/phylink.c
....@@ -1,12 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * phylink models the MAC to optional PHY connection, supporting
34 * technologies such as SFP cages where the PHY is hot-pluggable.
45 *
56 * Copyright (C) 2015 Russell King
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
107 */
118 #include <linux/ethtool.h>
129 #include <linux/export.h>
....@@ -43,12 +40,18 @@
4340 struct phylink {
4441 /* private: */
4542 struct net_device *netdev;
46
- const struct phylink_mac_ops *ops;
43
+ const struct phylink_mac_ops *mac_ops;
44
+ const struct phylink_pcs_ops *pcs_ops;
45
+ struct phylink_config *config;
46
+ struct phylink_pcs *pcs;
47
+ struct device *dev;
48
+ unsigned int old_link_state:1;
4749
4850 unsigned long phylink_disable_state; /* bitmask of disables */
4951 struct phy_device *phydev;
5052 phy_interface_t link_interface; /* PHY_INTERFACE_xxx */
51
- u8 link_an_mode; /* MLO_AN_xxx */
53
+ u8 cfg_link_an_mode; /* MLO_AN_xxx */
54
+ u8 cur_link_an_mode;
5255 u8 link_port; /* The current non-phy ethtool port */
5356 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
5457
....@@ -59,6 +62,7 @@
5962 phy_interface_t cur_interface;
6063
6164 struct gpio_desc *link_gpio;
65
+ unsigned int link_irq;
6266 struct timer_list link_poll;
6367 void (*get_fixed_state)(struct net_device *dev,
6468 struct phylink_link_state *s);
....@@ -70,34 +74,43 @@
7074 bool mac_link_dropped;
7175
7276 struct sfp_bus *sfp_bus;
77
+ bool sfp_may_have_phy;
78
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
79
+ u8 sfp_port;
7380 };
7481
75
-static inline void linkmode_zero(unsigned long *dst)
76
-{
77
- bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
78
-}
82
+#define phylink_printk(level, pl, fmt, ...) \
83
+ do { \
84
+ if ((pl)->config->type == PHYLINK_NETDEV) \
85
+ netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
86
+ else if ((pl)->config->type == PHYLINK_DEV) \
87
+ dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
88
+ } while (0)
7989
80
-static inline void linkmode_copy(unsigned long *dst, const unsigned long *src)
81
-{
82
- bitmap_copy(dst, src, __ETHTOOL_LINK_MODE_MASK_NBITS);
83
-}
84
-
85
-static inline void linkmode_and(unsigned long *dst, const unsigned long *a,
86
- const unsigned long *b)
87
-{
88
- bitmap_and(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS);
89
-}
90
-
91
-static inline void linkmode_or(unsigned long *dst, const unsigned long *a,
92
- const unsigned long *b)
93
-{
94
- bitmap_or(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS);
95
-}
96
-
97
-static inline bool linkmode_empty(const unsigned long *src)
98
-{
99
- return bitmap_empty(src, __ETHTOOL_LINK_MODE_MASK_NBITS);
100
-}
90
+#define phylink_err(pl, fmt, ...) \
91
+ phylink_printk(KERN_ERR, pl, fmt, ##__VA_ARGS__)
92
+#define phylink_warn(pl, fmt, ...) \
93
+ phylink_printk(KERN_WARNING, pl, fmt, ##__VA_ARGS__)
94
+#define phylink_info(pl, fmt, ...) \
95
+ phylink_printk(KERN_INFO, pl, fmt, ##__VA_ARGS__)
96
+#if defined(CONFIG_DYNAMIC_DEBUG)
97
+#define phylink_dbg(pl, fmt, ...) \
98
+do { \
99
+ if ((pl)->config->type == PHYLINK_NETDEV) \
100
+ netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
101
+ else if ((pl)->config->type == PHYLINK_DEV) \
102
+ dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
103
+} while (0)
104
+#elif defined(DEBUG)
105
+#define phylink_dbg(pl, fmt, ...) \
106
+ phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__)
107
+#else
108
+#define phylink_dbg(pl, fmt, ...) \
109
+({ \
110
+ if (0) \
111
+ phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__); \
112
+})
113
+#endif
101114
102115 /**
103116 * phylink_set_port_modes() - set the port type modes in the ethtool mask
....@@ -126,9 +139,7 @@
126139 phylink_set(tmp, Pause);
127140 phylink_set(tmp, Asym_Pause);
128141
129
- bitmap_andnot(tmp, linkmode, tmp, __ETHTOOL_LINK_MODE_MASK_NBITS);
130
-
131
- return linkmode_empty(tmp);
142
+ return linkmode_subset(linkmode, tmp);
132143 }
133144
134145 static const char *phylink_an_mode_str(unsigned int mode)
....@@ -145,7 +156,7 @@
145156 static int phylink_validate(struct phylink *pl, unsigned long *supported,
146157 struct phylink_link_state *state)
147158 {
148
- pl->ops->validate(pl->netdev, supported, state);
159
+ pl->mac_ops->validate(pl->config, supported, state);
149160
150161 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
151162 }
....@@ -172,13 +183,15 @@
172183 /* We treat the "pause" and "asym-pause" terminology as
173184 * defining the link partner's ability. */
174185 if (fwnode_property_read_bool(fixed_node, "pause"))
175
- pl->link_config.pause |= MLO_PAUSE_SYM;
186
+ __set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
187
+ pl->link_config.lp_advertising);
176188 if (fwnode_property_read_bool(fixed_node, "asym-pause"))
177
- pl->link_config.pause |= MLO_PAUSE_ASYM;
189
+ __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
190
+ pl->link_config.lp_advertising);
178191
179192 if (ret == 0) {
180
- desc = fwnode_get_named_gpiod(fixed_node, "link-gpios",
181
- 0, GPIOD_IN, "?");
193
+ desc = fwnode_gpiod_get_index(fixed_node, "link", 0,
194
+ GPIOD_IN, "?");
182195
183196 if (!IS_ERR(desc))
184197 pl->link_gpio = desc;
....@@ -195,7 +208,7 @@
195208 ret = fwnode_property_read_u32_array(fwnode, "fixed-link",
196209 NULL, 0);
197210 if (ret != ARRAY_SIZE(prop)) {
198
- netdev_err(pl->netdev, "broken fixed-link?\n");
211
+ phylink_err(pl, "broken fixed-link?\n");
199212 return -EINVAL;
200213 }
201214
....@@ -206,34 +219,37 @@
206219 DUPLEX_FULL : DUPLEX_HALF;
207220 pl->link_config.speed = prop[2];
208221 if (prop[3])
209
- pl->link_config.pause |= MLO_PAUSE_SYM;
222
+ __set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
223
+ pl->link_config.lp_advertising);
210224 if (prop[4])
211
- pl->link_config.pause |= MLO_PAUSE_ASYM;
225
+ __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
226
+ pl->link_config.lp_advertising);
212227 }
213228 }
214229
215230 if (pl->link_config.speed > SPEED_1000 &&
216231 pl->link_config.duplex != DUPLEX_FULL)
217
- netdev_warn(pl->netdev, "fixed link specifies half duplex for %dMbps link?\n",
218
- pl->link_config.speed);
232
+ phylink_warn(pl, "fixed link specifies half duplex for %dMbps link?\n",
233
+ pl->link_config.speed);
219234
220235 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
221236 linkmode_copy(pl->link_config.advertising, pl->supported);
222237 phylink_validate(pl, pl->supported, &pl->link_config);
223238
224239 s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex,
225
- pl->supported,
226
- __ETHTOOL_LINK_MODE_MASK_NBITS, true);
240
+ pl->supported, true);
227241 linkmode_zero(pl->supported);
228242 phylink_set(pl->supported, MII);
229243 phylink_set(pl->supported, Pause);
230244 phylink_set(pl->supported, Asym_Pause);
245
+ phylink_set(pl->supported, Autoneg);
231246 if (s) {
232247 __set_bit(s->bit, pl->supported);
248
+ __set_bit(s->bit, pl->link_config.lp_advertising);
233249 } else {
234
- netdev_warn(pl->netdev, "fixed link %s duplex %dMbps not recognised\n",
235
- pl->link_config.duplex == DUPLEX_FULL ? "full" : "half",
236
- pl->link_config.speed);
250
+ phylink_warn(pl, "fixed link %s duplex %dMbps not recognised\n",
251
+ pl->link_config.duplex == DUPLEX_FULL ? "full" : "half",
252
+ pl->link_config.speed);
237253 }
238254
239255 linkmode_and(pl->link_config.advertising, pl->link_config.advertising,
....@@ -252,14 +268,14 @@
252268
253269 dn = fwnode_get_named_child_node(fwnode, "fixed-link");
254270 if (dn || fwnode_property_present(fwnode, "fixed-link"))
255
- pl->link_an_mode = MLO_AN_FIXED;
271
+ pl->cfg_link_an_mode = MLO_AN_FIXED;
256272 fwnode_handle_put(dn);
257273
258274 if (fwnode_property_read_string(fwnode, "managed", &managed) == 0 &&
259275 strcmp(managed, "in-band-status") == 0) {
260
- if (pl->link_an_mode == MLO_AN_FIXED) {
261
- netdev_err(pl->netdev,
262
- "can't use both fixed-link and in-band-status\n");
276
+ if (pl->cfg_link_an_mode == MLO_AN_FIXED) {
277
+ phylink_err(pl,
278
+ "can't use both fixed-link and in-band-status\n");
263279 return -EINVAL;
264280 }
265281
....@@ -269,10 +285,11 @@
269285 phylink_set(pl->supported, Asym_Pause);
270286 phylink_set(pl->supported, Pause);
271287 pl->link_config.an_enabled = true;
272
- pl->link_an_mode = MLO_AN_INBAND;
288
+ pl->cfg_link_an_mode = MLO_AN_INBAND;
273289
274290 switch (pl->link_config.interface) {
275291 case PHY_INTERFACE_MODE_SGMII:
292
+ case PHY_INTERFACE_MODE_QSGMII:
276293 phylink_set(pl->supported, 10baseT_Half);
277294 phylink_set(pl->supported, 10baseT_Full);
278295 phylink_set(pl->supported, 100baseT_Half);
....@@ -289,7 +306,9 @@
289306 phylink_set(pl->supported, 2500baseX_Full);
290307 break;
291308
309
+ case PHY_INTERFACE_MODE_USXGMII:
292310 case PHY_INTERFACE_MODE_10GKR:
311
+ case PHY_INTERFACE_MODE_10GBASER:
293312 phylink_set(pl->supported, 10baseT_Half);
294313 phylink_set(pl->supported, 10baseT_Full);
295314 phylink_set(pl->supported, 100baseT_Half);
....@@ -297,7 +316,13 @@
297316 phylink_set(pl->supported, 1000baseT_Half);
298317 phylink_set(pl->supported, 1000baseT_Full);
299318 phylink_set(pl->supported, 1000baseX_Full);
319
+ phylink_set(pl->supported, 1000baseKX_Full);
320
+ phylink_set(pl->supported, 2500baseT_Full);
321
+ phylink_set(pl->supported, 2500baseX_Full);
322
+ phylink_set(pl->supported, 5000baseT_Full);
323
+ phylink_set(pl->supported, 10000baseT_Full);
300324 phylink_set(pl->supported, 10000baseKR_Full);
325
+ phylink_set(pl->supported, 10000baseKX4_Full);
301326 phylink_set(pl->supported, 10000baseCR_Full);
302327 phylink_set(pl->supported, 10000baseSR_Full);
303328 phylink_set(pl->supported, 10000baseLR_Full);
....@@ -305,51 +330,199 @@
305330 phylink_set(pl->supported, 10000baseER_Full);
306331 break;
307332
333
+ case PHY_INTERFACE_MODE_XLGMII:
334
+ phylink_set(pl->supported, 25000baseCR_Full);
335
+ phylink_set(pl->supported, 25000baseKR_Full);
336
+ phylink_set(pl->supported, 25000baseSR_Full);
337
+ phylink_set(pl->supported, 40000baseKR4_Full);
338
+ phylink_set(pl->supported, 40000baseCR4_Full);
339
+ phylink_set(pl->supported, 40000baseSR4_Full);
340
+ phylink_set(pl->supported, 40000baseLR4_Full);
341
+ phylink_set(pl->supported, 50000baseCR2_Full);
342
+ phylink_set(pl->supported, 50000baseKR2_Full);
343
+ phylink_set(pl->supported, 50000baseSR2_Full);
344
+ phylink_set(pl->supported, 50000baseKR_Full);
345
+ phylink_set(pl->supported, 50000baseSR_Full);
346
+ phylink_set(pl->supported, 50000baseCR_Full);
347
+ phylink_set(pl->supported, 50000baseLR_ER_FR_Full);
348
+ phylink_set(pl->supported, 50000baseDR_Full);
349
+ phylink_set(pl->supported, 100000baseKR4_Full);
350
+ phylink_set(pl->supported, 100000baseSR4_Full);
351
+ phylink_set(pl->supported, 100000baseCR4_Full);
352
+ phylink_set(pl->supported, 100000baseLR4_ER4_Full);
353
+ phylink_set(pl->supported, 100000baseKR2_Full);
354
+ phylink_set(pl->supported, 100000baseSR2_Full);
355
+ phylink_set(pl->supported, 100000baseCR2_Full);
356
+ phylink_set(pl->supported, 100000baseLR2_ER2_FR2_Full);
357
+ phylink_set(pl->supported, 100000baseDR2_Full);
358
+ break;
359
+
308360 default:
309
- netdev_err(pl->netdev,
310
- "incorrect link mode %s for in-band status\n",
311
- phy_modes(pl->link_config.interface));
361
+ phylink_err(pl,
362
+ "incorrect link mode %s for in-band status\n",
363
+ phy_modes(pl->link_config.interface));
312364 return -EINVAL;
313365 }
314366
315367 linkmode_copy(pl->link_config.advertising, pl->supported);
316368
317369 if (phylink_validate(pl, pl->supported, &pl->link_config)) {
318
- netdev_err(pl->netdev,
319
- "failed to validate link configuration for in-band status\n");
370
+ phylink_err(pl,
371
+ "failed to validate link configuration for in-band status\n");
320372 return -EINVAL;
321373 }
374
+
375
+ /* Check if MAC/PCS also supports Autoneg. */
376
+ pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg);
322377 }
323378
324379 return 0;
325380 }
326381
382
+static void phylink_apply_manual_flow(struct phylink *pl,
383
+ struct phylink_link_state *state)
384
+{
385
+ /* If autoneg is disabled, pause AN is also disabled */
386
+ if (!state->an_enabled)
387
+ state->pause &= ~MLO_PAUSE_AN;
388
+
389
+ /* Manual configuration of pause modes */
390
+ if (!(pl->link_config.pause & MLO_PAUSE_AN))
391
+ state->pause = pl->link_config.pause;
392
+}
393
+
394
+static void phylink_resolve_flow(struct phylink_link_state *state)
395
+{
396
+ bool tx_pause, rx_pause;
397
+
398
+ state->pause = MLO_PAUSE_NONE;
399
+ if (state->duplex == DUPLEX_FULL) {
400
+ linkmode_resolve_pause(state->advertising,
401
+ state->lp_advertising,
402
+ &tx_pause, &rx_pause);
403
+ if (tx_pause)
404
+ state->pause |= MLO_PAUSE_TX;
405
+ if (rx_pause)
406
+ state->pause |= MLO_PAUSE_RX;
407
+ }
408
+}
409
+
327410 static void phylink_mac_config(struct phylink *pl,
328411 const struct phylink_link_state *state)
329412 {
330
- netdev_dbg(pl->netdev,
331
- "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
332
- __func__, phylink_an_mode_str(pl->link_an_mode),
333
- phy_modes(state->interface),
334
- phy_speed_to_str(state->speed),
335
- phy_duplex_to_str(state->duplex),
336
- __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising,
337
- state->pause, state->link, state->an_enabled);
413
+ phylink_dbg(pl,
414
+ "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
415
+ __func__, phylink_an_mode_str(pl->cur_link_an_mode),
416
+ phy_modes(state->interface),
417
+ phy_speed_to_str(state->speed),
418
+ phy_duplex_to_str(state->duplex),
419
+ __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising,
420
+ state->pause, state->link, state->an_enabled);
338421
339
- pl->ops->mac_config(pl->netdev, pl->link_an_mode, state);
422
+ pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, state);
340423 }
341424
342
-static void phylink_mac_an_restart(struct phylink *pl)
425
+static void phylink_mac_pcs_an_restart(struct phylink *pl)
343426 {
344427 if (pl->link_config.an_enabled &&
345
- phy_interface_mode_is_8023z(pl->link_config.interface))
346
- pl->ops->mac_an_restart(pl->netdev);
428
+ phy_interface_mode_is_8023z(pl->link_config.interface) &&
429
+ phylink_autoneg_inband(pl->cur_link_an_mode)) {
430
+ if (pl->pcs_ops)
431
+ pl->pcs_ops->pcs_an_restart(pl->pcs);
432
+ else
433
+ pl->mac_ops->mac_an_restart(pl->config);
434
+ }
347435 }
348436
349
-static int phylink_get_mac_state(struct phylink *pl, struct phylink_link_state *state)
437
+static void phylink_major_config(struct phylink *pl, bool restart,
438
+ const struct phylink_link_state *state)
350439 {
351
- struct net_device *ndev = pl->netdev;
440
+ int err;
352441
442
+ phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
443
+
444
+ if (pl->mac_ops->mac_prepare) {
445
+ err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
446
+ state->interface);
447
+ if (err < 0) {
448
+ phylink_err(pl, "mac_prepare failed: %pe\n",
449
+ ERR_PTR(err));
450
+ return;
451
+ }
452
+ }
453
+
454
+ phylink_mac_config(pl, state);
455
+
456
+ if (pl->pcs_ops) {
457
+ err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
458
+ state->interface,
459
+ state->advertising,
460
+ !!(pl->link_config.pause &
461
+ MLO_PAUSE_AN));
462
+ if (err < 0)
463
+ phylink_err(pl, "pcs_config failed: %pe\n",
464
+ ERR_PTR(err));
465
+ if (err > 0)
466
+ restart = true;
467
+ }
468
+ if (restart)
469
+ phylink_mac_pcs_an_restart(pl);
470
+
471
+ if (pl->mac_ops->mac_finish) {
472
+ err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode,
473
+ state->interface);
474
+ if (err < 0)
475
+ phylink_err(pl, "mac_finish failed: %pe\n",
476
+ ERR_PTR(err));
477
+ }
478
+}
479
+
480
+/*
481
+ * Reconfigure for a change of inband advertisement.
482
+ * If we have a separate PCS, we only need to call its pcs_config() method,
483
+ * and then restart AN if it indicates something changed. Otherwise, we do
484
+ * the full MAC reconfiguration.
485
+ */
486
+static int phylink_change_inband_advert(struct phylink *pl)
487
+{
488
+ int ret;
489
+
490
+ if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
491
+ return 0;
492
+
493
+ if (!pl->pcs_ops) {
494
+ /* Legacy method */
495
+ phylink_mac_config(pl, &pl->link_config);
496
+ phylink_mac_pcs_an_restart(pl);
497
+ return 0;
498
+ }
499
+
500
+ phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__,
501
+ phylink_an_mode_str(pl->cur_link_an_mode),
502
+ phy_modes(pl->link_config.interface),
503
+ __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
504
+ pl->link_config.pause);
505
+
506
+ /* Modern PCS-based method; update the advert at the PCS, and
507
+ * restart negotiation if the pcs_config() helper indicates that
508
+ * the programmed advertisement has changed.
509
+ */
510
+ ret = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
511
+ pl->link_config.interface,
512
+ pl->link_config.advertising,
513
+ !!(pl->link_config.pause & MLO_PAUSE_AN));
514
+ if (ret < 0)
515
+ return ret;
516
+
517
+ if (ret > 0)
518
+ phylink_mac_pcs_an_restart(pl);
519
+
520
+ return 0;
521
+}
522
+
523
+static void phylink_mac_pcs_get_state(struct phylink *pl,
524
+ struct phylink_link_state *state)
525
+{
353526 linkmode_copy(state->advertising, pl->link_config.advertising);
354527 linkmode_zero(state->lp_advertising);
355528 state->interface = pl->link_config.interface;
....@@ -360,55 +533,56 @@
360533 state->an_complete = 0;
361534 state->link = 1;
362535
363
- return pl->ops->mac_link_state(ndev, state);
536
+ if (pl->pcs_ops)
537
+ pl->pcs_ops->pcs_get_state(pl->pcs, state);
538
+ else if (pl->mac_ops->mac_pcs_get_state)
539
+ pl->mac_ops->mac_pcs_get_state(pl->config, state);
540
+ else
541
+ state->link = 0;
364542 }
365543
366544 /* The fixed state is... fixed except for the link state,
367545 * which may be determined by a GPIO or a callback.
368546 */
369
-static void phylink_get_fixed_state(struct phylink *pl, struct phylink_link_state *state)
547
+static void phylink_get_fixed_state(struct phylink *pl,
548
+ struct phylink_link_state *state)
370549 {
371550 *state = pl->link_config;
372
- if (pl->get_fixed_state)
373
- pl->get_fixed_state(pl->netdev, state);
551
+ if (pl->config->get_fixed_state)
552
+ pl->config->get_fixed_state(pl->config, state);
374553 else if (pl->link_gpio)
375554 state->link = !!gpiod_get_value_cansleep(pl->link_gpio);
555
+
556
+ phylink_resolve_flow(state);
376557 }
377558
378
-/* Flow control is resolved according to our and the link partners
379
- * advertisements using the following drawn from the 802.3 specs:
380
- * Local device Link partner
381
- * Pause AsymDir Pause AsymDir Result
382
- * 1 X 1 X TX+RX
383
- * 0 1 1 1 TX
384
- * 1 1 0 1 RX
385
- */
386
-static void phylink_resolve_flow(struct phylink *pl,
387
- struct phylink_link_state *state)
559
+static void phylink_mac_initial_config(struct phylink *pl, bool force_restart)
388560 {
389
- int new_pause = 0;
561
+ struct phylink_link_state link_state;
390562
391
- if (pl->link_config.pause & MLO_PAUSE_AN) {
392
- int pause = 0;
563
+ switch (pl->cur_link_an_mode) {
564
+ case MLO_AN_PHY:
565
+ link_state = pl->phy_state;
566
+ break;
393567
394
- if (phylink_test(pl->link_config.advertising, Pause))
395
- pause |= MLO_PAUSE_SYM;
396
- if (phylink_test(pl->link_config.advertising, Asym_Pause))
397
- pause |= MLO_PAUSE_ASYM;
568
+ case MLO_AN_FIXED:
569
+ phylink_get_fixed_state(pl, &link_state);
570
+ break;
398571
399
- pause &= state->pause;
572
+ case MLO_AN_INBAND:
573
+ link_state = pl->link_config;
574
+ if (link_state.interface == PHY_INTERFACE_MODE_SGMII)
575
+ link_state.pause = MLO_PAUSE_NONE;
576
+ break;
400577
401
- if (pause & MLO_PAUSE_SYM)
402
- new_pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
403
- else if (pause & MLO_PAUSE_ASYM)
404
- new_pause = state->pause & MLO_PAUSE_SYM ?
405
- MLO_PAUSE_TX : MLO_PAUSE_RX;
406
- } else {
407
- new_pause = pl->link_config.pause & MLO_PAUSE_TXRX_MASK;
578
+ default: /* can't happen */
579
+ return;
408580 }
409581
410
- state->pause &= ~MLO_PAUSE_TXRX_MASK;
411
- state->pause |= new_pause;
582
+ link_state.link = false;
583
+
584
+ phylink_apply_manual_flow(pl, &link_state);
585
+ phylink_major_config(pl, force_restart, &link_state);
412586 }
413587
414588 static const char *phylink_pause_to_str(int pause)
....@@ -425,81 +599,153 @@
425599 }
426600 }
427601
602
+static void phylink_link_up(struct phylink *pl,
603
+ struct phylink_link_state link_state)
604
+{
605
+ struct net_device *ndev = pl->netdev;
606
+
607
+ pl->cur_interface = link_state.interface;
608
+
609
+ if (pl->pcs_ops && pl->pcs_ops->pcs_link_up)
610
+ pl->pcs_ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode,
611
+ pl->cur_interface,
612
+ link_state.speed, link_state.duplex);
613
+
614
+ pl->mac_ops->mac_link_up(pl->config, pl->phydev,
615
+ pl->cur_link_an_mode, pl->cur_interface,
616
+ link_state.speed, link_state.duplex,
617
+ !!(link_state.pause & MLO_PAUSE_TX),
618
+ !!(link_state.pause & MLO_PAUSE_RX));
619
+
620
+ if (ndev)
621
+ netif_carrier_on(ndev);
622
+
623
+ phylink_info(pl,
624
+ "Link is Up - %s/%s - flow control %s\n",
625
+ phy_speed_to_str(link_state.speed),
626
+ phy_duplex_to_str(link_state.duplex),
627
+ phylink_pause_to_str(link_state.pause));
628
+}
629
+
630
+static void phylink_link_down(struct phylink *pl)
631
+{
632
+ struct net_device *ndev = pl->netdev;
633
+
634
+ if (ndev)
635
+ netif_carrier_off(ndev);
636
+ pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode,
637
+ pl->cur_interface);
638
+ phylink_info(pl, "Link is Down\n");
639
+}
640
+
428641 static void phylink_resolve(struct work_struct *w)
429642 {
430643 struct phylink *pl = container_of(w, struct phylink, resolve);
431644 struct phylink_link_state link_state;
432645 struct net_device *ndev = pl->netdev;
646
+ bool mac_config = false;
647
+ bool retrigger = false;
648
+ bool cur_link_state;
433649
434650 mutex_lock(&pl->state_mutex);
651
+ if (pl->netdev)
652
+ cur_link_state = netif_carrier_ok(ndev);
653
+ else
654
+ cur_link_state = pl->old_link_state;
655
+
435656 if (pl->phylink_disable_state) {
436657 pl->mac_link_dropped = false;
437658 link_state.link = false;
438659 } else if (pl->mac_link_dropped) {
439660 link_state.link = false;
661
+ retrigger = true;
440662 } else {
441
- switch (pl->link_an_mode) {
663
+ switch (pl->cur_link_an_mode) {
442664 case MLO_AN_PHY:
443665 link_state = pl->phy_state;
444
- phylink_resolve_flow(pl, &link_state);
445
- phylink_mac_config(pl, &link_state);
666
+ phylink_apply_manual_flow(pl, &link_state);
667
+ mac_config = link_state.link;
446668 break;
447669
448670 case MLO_AN_FIXED:
449671 phylink_get_fixed_state(pl, &link_state);
450
- phylink_mac_config(pl, &link_state);
672
+ mac_config = link_state.link;
451673 break;
452674
453675 case MLO_AN_INBAND:
454
- phylink_get_mac_state(pl, &link_state);
455
- if (pl->phydev) {
456
- bool changed = false;
676
+ phylink_mac_pcs_get_state(pl, &link_state);
457677
458
- link_state.link = link_state.link &&
459
- pl->phy_state.link;
460
-
461
- if (pl->phy_state.interface !=
462
- link_state.interface) {
463
- link_state.interface = pl->phy_state.interface;
464
- changed = true;
465
- }
466
-
467
- /* Propagate the flow control from the PHY
468
- * to the MAC. Also propagate the interface
469
- * if changed.
470
- */
471
- if (pl->phy_state.link || changed) {
472
- link_state.pause |= pl->phy_state.pause;
473
- phylink_resolve_flow(pl, &link_state);
474
-
475
- phylink_mac_config(pl, &link_state);
476
- }
678
+ /* The PCS may have a latching link-fail indicator.
679
+ * If the link was up, bring the link down and
680
+ * re-trigger the resolve. Otherwise, re-read the
681
+ * PCS state to get the current status of the link.
682
+ */
683
+ if (!link_state.link) {
684
+ if (cur_link_state)
685
+ retrigger = true;
686
+ else
687
+ phylink_mac_pcs_get_state(pl,
688
+ &link_state);
477689 }
690
+
691
+ /* If we have a phy, the "up" state is the union of
692
+ * both the PHY and the MAC */
693
+ if (pl->phydev)
694
+ link_state.link &= pl->phy_state.link;
695
+
696
+ /* Only update if the PHY link is up */
697
+ if (pl->phydev && pl->phy_state.link) {
698
+ /* If the interface has changed, force a
699
+ * link down event if the link isn't already
700
+ * down, and re-resolve.
701
+ */
702
+ if (link_state.interface !=
703
+ pl->phy_state.interface) {
704
+ retrigger = true;
705
+ link_state.link = false;
706
+ }
707
+ link_state.interface = pl->phy_state.interface;
708
+
709
+ /* If we have a PHY, we need to update with
710
+ * the PHY flow control bits. */
711
+ link_state.pause = pl->phy_state.pause;
712
+ mac_config = true;
713
+ }
714
+ phylink_apply_manual_flow(pl, &link_state);
478715 break;
479716 }
480717 }
481718
482
- if (link_state.link != netif_carrier_ok(ndev)) {
483
- if (!link_state.link) {
484
- netif_carrier_off(ndev);
485
- pl->ops->mac_link_down(ndev, pl->link_an_mode,
486
- pl->cur_interface);
487
- netdev_info(ndev, "Link is Down\n");
488
- } else {
489
- pl->cur_interface = link_state.interface;
490
- pl->ops->mac_link_up(ndev, pl->link_an_mode,
491
- pl->cur_interface, pl->phydev);
492
-
493
- netif_carrier_on(ndev);
494
-
495
- netdev_info(ndev,
496
- "Link is Up - %s/%s - flow control %s\n",
497
- phy_speed_to_str(link_state.speed),
498
- phy_duplex_to_str(link_state.duplex),
499
- phylink_pause_to_str(link_state.pause));
719
+ if (mac_config) {
720
+ if (link_state.interface != pl->link_config.interface) {
721
+ /* The interface has changed, force the link down and
722
+ * then reconfigure.
723
+ */
724
+ if (cur_link_state) {
725
+ phylink_link_down(pl);
726
+ cur_link_state = false;
727
+ }
728
+ phylink_major_config(pl, false, &link_state);
729
+ pl->link_config.interface = link_state.interface;
730
+ } else if (!pl->pcs_ops) {
731
+ /* The interface remains unchanged, only the speed,
732
+ * duplex or pause settings have changed. Call the
733
+ * old mac_config() method to configure the MAC/PCS
734
+ * only if we do not have a PCS installed (an
735
+ * unconverted user.)
736
+ */
737
+ phylink_mac_config(pl, &link_state);
500738 }
501739 }
502
- if (!link_state.link && pl->mac_link_dropped) {
740
+
741
+ if (link_state.link != cur_link_state) {
742
+ pl->old_link_state = link_state.link;
743
+ if (!link_state.link)
744
+ phylink_link_down(pl);
745
+ else
746
+ phylink_link_up(pl, link_state);
747
+ }
748
+ if (!link_state.link && retrigger) {
503749 pl->mac_link_dropped = false;
504750 queue_work(system_power_efficient_wq, &pl->resolve);
505751 }
....@@ -537,54 +783,47 @@
537783 static int phylink_register_sfp(struct phylink *pl,
538784 struct fwnode_handle *fwnode)
539785 {
540
- struct fwnode_reference_args ref;
786
+ struct sfp_bus *bus;
541787 int ret;
542788
543789 if (!fwnode)
544790 return 0;
545791
546
- ret = fwnode_property_get_reference_args(fwnode, "sfp", NULL,
547
- 0, 0, &ref);
548
- if (ret < 0) {
549
- if (ret == -ENOENT)
550
- return 0;
551
-
552
- netdev_err(pl->netdev, "unable to parse \"sfp\" node: %d\n",
553
- ret);
792
+ bus = sfp_bus_find_fwnode(fwnode);
793
+ if (IS_ERR(bus)) {
794
+ ret = PTR_ERR(bus);
795
+ phylink_err(pl, "unable to attach SFP bus: %d\n", ret);
554796 return ret;
555797 }
556798
557
- if (!fwnode_device_is_available(ref.fwnode)) {
558
- fwnode_handle_put(ref.fwnode);
559
- return 0;
560
- }
799
+ pl->sfp_bus = bus;
561800
562
- pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl->netdev, pl,
563
- &sfp_phylink_ops);
564
- if (!pl->sfp_bus)
565
- return -ENOMEM;
801
+ ret = sfp_bus_add_upstream(bus, pl, &sfp_phylink_ops);
802
+ sfp_bus_put(bus);
566803
567
- return 0;
804
+ return ret;
568805 }
569806
570807 /**
571808 * phylink_create() - create a phylink instance
572
- * @ndev: a pointer to the &struct net_device
809
+ * @config: a pointer to the target &struct phylink_config
573810 * @fwnode: a pointer to a &struct fwnode_handle describing the network
574811 * interface
575812 * @iface: the desired link mode defined by &typedef phy_interface_t
576
- * @ops: a pointer to a &struct phylink_mac_ops for the MAC.
813
+ * @mac_ops: a pointer to a &struct phylink_mac_ops for the MAC.
577814 *
578815 * Create a new phylink instance, and parse the link parameters found in @np.
579816 * This will parse in-band modes, fixed-link or SFP configuration.
580817 *
818
+ * Note: the rtnl lock must not be held when calling this function.
819
+ *
581820 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
582821 * must use IS_ERR() to check for errors from this function.
583822 */
584
-struct phylink *phylink_create(struct net_device *ndev,
823
+struct phylink *phylink_create(struct phylink_config *config,
585824 struct fwnode_handle *fwnode,
586825 phy_interface_t iface,
587
- const struct phylink_mac_ops *ops)
826
+ const struct phylink_mac_ops *mac_ops)
588827 {
589828 struct phylink *pl;
590829 int ret;
....@@ -595,7 +834,17 @@
595834
596835 mutex_init(&pl->state_mutex);
597836 INIT_WORK(&pl->resolve, phylink_resolve);
598
- pl->netdev = ndev;
837
+
838
+ pl->config = config;
839
+ if (config->type == PHYLINK_NETDEV) {
840
+ pl->netdev = to_net_dev(config->dev);
841
+ } else if (config->type == PHYLINK_DEV) {
842
+ pl->dev = config->dev;
843
+ } else {
844
+ kfree(pl);
845
+ return ERR_PTR(-EINVAL);
846
+ }
847
+
599848 pl->phy_state.interface = iface;
600849 pl->link_interface = iface;
601850 if (iface == PHY_INTERFACE_MODE_MOCA)
....@@ -607,7 +856,7 @@
607856 pl->link_config.speed = SPEED_UNKNOWN;
608857 pl->link_config.duplex = DUPLEX_UNKNOWN;
609858 pl->link_config.an_enabled = true;
610
- pl->ops = ops;
859
+ pl->mac_ops = mac_ops;
611860 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
612861 timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
613862
....@@ -621,13 +870,15 @@
621870 return ERR_PTR(ret);
622871 }
623872
624
- if (pl->link_an_mode == MLO_AN_FIXED) {
873
+ if (pl->cfg_link_an_mode == MLO_AN_FIXED) {
625874 ret = phylink_parse_fixedlink(pl, fwnode);
626875 if (ret < 0) {
627876 kfree(pl);
628877 return ERR_PTR(ret);
629878 }
630879 }
880
+
881
+ pl->cur_link_an_mode = pl->cfg_link_an_mode;
631882
632883 ret = phylink_register_sfp(pl, fwnode);
633884 if (ret < 0) {
....@@ -640,17 +891,39 @@
640891 EXPORT_SYMBOL_GPL(phylink_create);
641892
642893 /**
894
+ * phylink_set_pcs() - set the current PCS for phylink to use
895
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
896
+ * @pcs: a pointer to the &struct phylink_pcs
897
+ *
898
+ * Bind the MAC PCS to phylink. This may be called after phylink_create(),
899
+ * in mac_prepare() or mac_config() methods if it is desired to dynamically
900
+ * change the PCS.
901
+ *
902
+ * Please note that there are behavioural changes with the mac_config()
903
+ * callback if a PCS is present (denoting a newer setup) so removing a PCS
904
+ * is not supported, and if a PCS is going to be used, it must be registered
905
+ * by calling phylink_set_pcs() at the latest in the first mac_config() call.
906
+ */
907
+void phylink_set_pcs(struct phylink *pl, struct phylink_pcs *pcs)
908
+{
909
+ pl->pcs = pcs;
910
+ pl->pcs_ops = pcs->ops;
911
+}
912
+EXPORT_SYMBOL_GPL(phylink_set_pcs);
913
+
914
+/**
643915 * phylink_destroy() - cleanup and destroy the phylink instance
644916 * @pl: a pointer to a &struct phylink returned from phylink_create()
645917 *
646918 * Destroy a phylink instance. Any PHY that has been attached must have been
647919 * cleaned up via phylink_disconnect_phy() prior to calling this function.
920
+ *
921
+ * Note: the rtnl lock must not be held when calling this function.
648922 */
649923 void phylink_destroy(struct phylink *pl)
650924 {
651
- if (pl->sfp_bus)
652
- sfp_unregister_upstream(pl->sfp_bus);
653
- if (!IS_ERR_OR_NULL(pl->link_gpio))
925
+ sfp_bus_del_upstream(pl->sfp_bus);
926
+ if (pl->link_gpio)
654927 gpiod_put(pl->link_gpio);
655928
656929 cancel_work_sync(&pl->resolve);
....@@ -658,43 +931,40 @@
658931 }
659932 EXPORT_SYMBOL_GPL(phylink_destroy);
660933
661
-static void phylink_phy_change(struct phy_device *phydev, bool up,
662
- bool do_carrier)
934
+static void phylink_phy_change(struct phy_device *phydev, bool up)
663935 {
664936 struct phylink *pl = phydev->phylink;
937
+ bool tx_pause, rx_pause;
938
+
939
+ phy_get_pause(phydev, &tx_pause, &rx_pause);
665940
666941 mutex_lock(&pl->state_mutex);
667942 pl->phy_state.speed = phydev->speed;
668943 pl->phy_state.duplex = phydev->duplex;
669944 pl->phy_state.pause = MLO_PAUSE_NONE;
670
- if (phydev->pause)
671
- pl->phy_state.pause |= MLO_PAUSE_SYM;
672
- if (phydev->asym_pause)
673
- pl->phy_state.pause |= MLO_PAUSE_ASYM;
945
+ if (tx_pause)
946
+ pl->phy_state.pause |= MLO_PAUSE_TX;
947
+ if (rx_pause)
948
+ pl->phy_state.pause |= MLO_PAUSE_RX;
674949 pl->phy_state.interface = phydev->interface;
675950 pl->phy_state.link = up;
676951 mutex_unlock(&pl->state_mutex);
677952
678953 phylink_run_resolve(pl);
679954
680
- netdev_dbg(pl->netdev, "phy link %s %s/%s/%s\n", up ? "up" : "down",
681
- phy_modes(phydev->interface),
682
- phy_speed_to_str(phydev->speed),
683
- phy_duplex_to_str(phydev->duplex));
955
+ phylink_dbg(pl, "phy link %s %s/%s/%s\n", up ? "up" : "down",
956
+ phy_modes(phydev->interface),
957
+ phy_speed_to_str(phydev->speed),
958
+ phy_duplex_to_str(phydev->duplex));
684959 }
685960
686
-static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
961
+static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
962
+ phy_interface_t interface)
687963 {
688964 struct phylink_link_state config;
689965 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
690
- u32 advertising;
966
+ char *irq_str;
691967 int ret;
692
-
693
- memset(&config, 0, sizeof(config));
694
- ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
695
- ethtool_convert_legacy_u32_to_link_mode(config.advertising,
696
- phy->advertising);
697
- config.interface = pl->link_config.interface;
698968
699969 /*
700970 * This is the new way of dealing with flow control for PHYs,
....@@ -703,68 +973,82 @@
703973 * using our validate call to the MAC, we rely upon the MAC
704974 * clearing the bits from both supported and advertising fields.
705975 */
706
- if (phylink_test(supported, Pause))
707
- phylink_set(config.advertising, Pause);
708
- if (phylink_test(supported, Asym_Pause))
709
- phylink_set(config.advertising, Asym_Pause);
976
+ phy_support_asym_pause(phy);
977
+
978
+ memset(&config, 0, sizeof(config));
979
+ linkmode_copy(supported, phy->supported);
980
+ linkmode_copy(config.advertising, phy->advertising);
981
+
982
+ /* Clause 45 PHYs switch their Serdes lane between several different
983
+ * modes, normally 10GBASE-R, SGMII. Some use 2500BASE-X for 2.5G
984
+ * speeds. We really need to know which interface modes the PHY and
985
+ * MAC supports to properly work out which linkmodes can be supported.
986
+ */
987
+ if (phy->is_c45 &&
988
+ interface != PHY_INTERFACE_MODE_RXAUI &&
989
+ interface != PHY_INTERFACE_MODE_XAUI &&
990
+ interface != PHY_INTERFACE_MODE_USXGMII)
991
+ config.interface = PHY_INTERFACE_MODE_NA;
992
+ else
993
+ config.interface = interface;
710994
711995 ret = phylink_validate(pl, supported, &config);
712
- if (ret)
996
+ if (ret) {
997
+ phylink_warn(pl, "validation of %s with support %*pb and advertisement %*pb failed: %d\n",
998
+ phy_modes(config.interface),
999
+ __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported,
1000
+ __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising,
1001
+ ret);
7131002 return ret;
1003
+ }
7141004
7151005 phy->phylink = pl;
7161006 phy->phy_link_change = phylink_phy_change;
7171007
718
- netdev_info(pl->netdev,
719
- "PHY [%s] driver [%s]\n", dev_name(&phy->mdio.dev),
720
- phy->drv->name);
1008
+ irq_str = phy_attached_info_irq(phy);
1009
+ phylink_info(pl,
1010
+ "PHY [%s] driver [%s] (irq=%s)\n",
1011
+ dev_name(&phy->mdio.dev), phy->drv->name, irq_str);
1012
+ kfree(irq_str);
7211013
7221014 mutex_lock(&phy->lock);
7231015 mutex_lock(&pl->state_mutex);
7241016 pl->phydev = phy;
1017
+ pl->phy_state.interface = interface;
1018
+ pl->phy_state.pause = MLO_PAUSE_NONE;
1019
+ pl->phy_state.speed = SPEED_UNKNOWN;
1020
+ pl->phy_state.duplex = DUPLEX_UNKNOWN;
7251021 linkmode_copy(pl->supported, supported);
7261022 linkmode_copy(pl->link_config.advertising, config.advertising);
7271023
7281024 /* Restrict the phy advertisement according to the MAC support. */
729
- ethtool_convert_link_mode_to_legacy_u32(&advertising, config.advertising);
730
- phy->advertising = advertising;
1025
+ linkmode_copy(phy->advertising, config.advertising);
7311026 mutex_unlock(&pl->state_mutex);
7321027 mutex_unlock(&phy->lock);
7331028
734
- netdev_dbg(pl->netdev,
735
- "phy: setting supported %*pb advertising 0x%08x\n",
736
- __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported,
737
- phy->advertising);
1029
+ phylink_dbg(pl,
1030
+ "phy: setting supported %*pb advertising %*pb\n",
1031
+ __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported,
1032
+ __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising);
7381033
739
- phy_start_machine(phy);
740
- if (phy->irq > 0)
741
- phy_start_interrupts(phy);
1034
+ if (phy_interrupt_is_valid(phy))
1035
+ phy_request_interrupt(phy);
7421036
7431037 return 0;
7441038 }
7451039
746
-static int __phylink_connect_phy(struct phylink *pl, struct phy_device *phy,
747
- phy_interface_t interface)
1040
+static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,
1041
+ phy_interface_t interface)
7481042 {
749
- int ret;
750
-
751
- if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED ||
752
- (pl->link_an_mode == MLO_AN_INBAND &&
1043
+ if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED ||
1044
+ (pl->cfg_link_an_mode == MLO_AN_INBAND &&
7531045 phy_interface_mode_is_8023z(interface))))
7541046 return -EINVAL;
7551047
7561048 if (pl->phydev)
7571049 return -EBUSY;
7581050
759
- ret = phy_attach_direct(pl->netdev, phy, 0, interface);
760
- if (ret)
761
- return ret;
762
-
763
- ret = phylink_bringup_phy(pl, phy);
764
- if (ret)
765
- phy_detach(phy);
766
-
767
- return ret;
1051
+ return phy_attach_direct(pl->netdev, phy, 0, interface);
7681052 }
7691053
7701054 /**
....@@ -784,13 +1068,23 @@
7841068 */
7851069 int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
7861070 {
1071
+ int ret;
1072
+
7871073 /* Use PHY device/driver interface */
7881074 if (pl->link_interface == PHY_INTERFACE_MODE_NA) {
7891075 pl->link_interface = phy->interface;
7901076 pl->link_config.interface = pl->link_interface;
7911077 }
7921078
793
- return __phylink_connect_phy(pl, phy, pl->link_interface);
1079
+ ret = phylink_attach_phy(pl, phy, pl->link_interface);
1080
+ if (ret < 0)
1081
+ return ret;
1082
+
1083
+ ret = phylink_bringup_phy(pl, phy, pl->link_config.interface);
1084
+ if (ret)
1085
+ phy_detach(phy);
1086
+
1087
+ return ret;
7941088 }
7951089 EXPORT_SYMBOL_GPL(phylink_connect_phy);
7961090
....@@ -814,8 +1108,8 @@
8141108 int ret;
8151109
8161110 /* Fixed links and 802.3z are handled without needing a PHY */
817
- if (pl->link_an_mode == MLO_AN_FIXED ||
818
- (pl->link_an_mode == MLO_AN_INBAND &&
1111
+ if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
1112
+ (pl->cfg_link_an_mode == MLO_AN_INBAND &&
8191113 phy_interface_mode_is_8023z(pl->link_interface)))
8201114 return 0;
8211115
....@@ -826,20 +1120,23 @@
8261120 phy_node = of_parse_phandle(dn, "phy-device", 0);
8271121
8281122 if (!phy_node) {
829
- if (pl->link_an_mode == MLO_AN_PHY)
1123
+ if (pl->cfg_link_an_mode == MLO_AN_PHY)
8301124 return -ENODEV;
8311125 return 0;
8321126 }
8331127
834
- phy_dev = of_phy_attach(pl->netdev, phy_node, flags,
835
- pl->link_interface);
1128
+ phy_dev = of_phy_find_device(phy_node);
8361129 /* We're done with the phy_node handle */
8371130 of_node_put(phy_node);
838
-
8391131 if (!phy_dev)
8401132 return -ENODEV;
8411133
842
- ret = phylink_bringup_phy(pl, phy_dev);
1134
+ ret = phy_attach_direct(pl->netdev, phy_dev, flags,
1135
+ pl->link_interface);
1136
+ if (ret)
1137
+ return ret;
1138
+
1139
+ ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface);
8431140 if (ret)
8441141 phy_detach(phy_dev);
8451142
....@@ -875,32 +1172,6 @@
8751172 EXPORT_SYMBOL_GPL(phylink_disconnect_phy);
8761173
8771174 /**
878
- * phylink_fixed_state_cb() - allow setting a fixed link callback
879
- * @pl: a pointer to a &struct phylink returned from phylink_create()
880
- * @cb: callback to execute to determine the fixed link state.
881
- *
882
- * The MAC driver should call this driver when the state of its link
883
- * can be determined through e.g: an out of band MMIO register.
884
- */
885
-int phylink_fixed_state_cb(struct phylink *pl,
886
- void (*cb)(struct net_device *dev,
887
- struct phylink_link_state *state))
888
-{
889
- /* It does not make sense to let the link be overriden unless we use
890
- * MLO_AN_FIXED
891
- */
892
- if (pl->link_an_mode != MLO_AN_FIXED)
893
- return -EINVAL;
894
-
895
- mutex_lock(&pl->state_mutex);
896
- pl->get_fixed_state = cb;
897
- mutex_unlock(&pl->state_mutex);
898
-
899
- return 0;
900
-}
901
-EXPORT_SYMBOL_GPL(phylink_fixed_state_cb);
902
-
903
-/**
9041175 * phylink_mac_change() - notify phylink of a change in MAC state
9051176 * @pl: a pointer to a &struct phylink returned from phylink_create()
9061177 * @up: indicates whether the link is currently up.
....@@ -913,9 +1184,18 @@
9131184 if (!up)
9141185 pl->mac_link_dropped = true;
9151186 phylink_run_resolve(pl);
916
- netdev_dbg(pl->netdev, "mac link %s\n", up ? "up" : "down");
1187
+ phylink_dbg(pl, "mac link %s\n", up ? "up" : "down");
9171188 }
9181189 EXPORT_SYMBOL_GPL(phylink_mac_change);
1190
+
1191
+static irqreturn_t phylink_link_handler(int irq, void *data)
1192
+{
1193
+ struct phylink *pl = data;
1194
+
1195
+ phylink_run_resolve(pl);
1196
+
1197
+ return IRQ_HANDLED;
1198
+}
9191199
9201200 /**
9211201 * phylink_start() - start a phylink instance
....@@ -927,37 +1207,63 @@
9271207 */
9281208 void phylink_start(struct phylink *pl)
9291209 {
1210
+ bool poll = false;
1211
+
9301212 ASSERT_RTNL();
9311213
932
- netdev_info(pl->netdev, "configuring for %s/%s link mode\n",
933
- phylink_an_mode_str(pl->link_an_mode),
934
- phy_modes(pl->link_config.interface));
1214
+ phylink_info(pl, "configuring for %s/%s link mode\n",
1215
+ phylink_an_mode_str(pl->cur_link_an_mode),
1216
+ phy_modes(pl->link_config.interface));
9351217
9361218 /* Always set the carrier off */
937
- netif_carrier_off(pl->netdev);
1219
+ if (pl->netdev)
1220
+ netif_carrier_off(pl->netdev);
9381221
9391222 /* Apply the link configuration to the MAC when starting. This allows
9401223 * a fixed-link to start with the correct parameters, and also
9411224 * ensures that we set the appropriate advertisement for Serdes links.
942
- */
943
- phylink_resolve_flow(pl, &pl->link_config);
944
- phylink_mac_config(pl, &pl->link_config);
945
-
946
- /* Restart autonegotiation if using 802.3z to ensure that the link
1225
+ *
1226
+ * Restart autonegotiation if using 802.3z to ensure that the link
9471227 * parameters are properly negotiated. This is necessary for DSA
9481228 * switches using 802.3z negotiation to ensure they see our modes.
9491229 */
950
- phylink_mac_an_restart(pl);
1230
+ phylink_mac_initial_config(pl, true);
9511231
9521232 clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
9531233 phylink_run_resolve(pl);
9541234
955
- if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio))
1235
+ if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) {
1236
+ int irq = gpiod_to_irq(pl->link_gpio);
1237
+
1238
+ if (irq > 0) {
1239
+ if (!request_irq(irq, phylink_link_handler,
1240
+ IRQF_TRIGGER_RISING |
1241
+ IRQF_TRIGGER_FALLING,
1242
+ "netdev link", pl))
1243
+ pl->link_irq = irq;
1244
+ else
1245
+ irq = 0;
1246
+ }
1247
+ if (irq <= 0)
1248
+ poll = true;
1249
+ }
1250
+
1251
+ switch (pl->cfg_link_an_mode) {
1252
+ case MLO_AN_FIXED:
1253
+ poll |= pl->config->poll_fixed_state;
1254
+ break;
1255
+ case MLO_AN_INBAND:
1256
+ poll |= pl->config->pcs_poll;
1257
+ if (pl->pcs)
1258
+ poll |= pl->pcs->poll;
1259
+ break;
1260
+ }
1261
+ if (poll)
9561262 mod_timer(&pl->link_poll, jiffies + HZ);
957
- if (pl->sfp_bus)
958
- sfp_upstream_start(pl->sfp_bus);
9591263 if (pl->phydev)
9601264 phy_start(pl->phydev);
1265
+ if (pl->sfp_bus)
1266
+ sfp_upstream_start(pl->sfp_bus);
9611267 }
9621268 EXPORT_SYMBOL_GPL(phylink_start);
9631269
....@@ -974,12 +1280,15 @@
9741280 {
9751281 ASSERT_RTNL();
9761282
977
- if (pl->phydev)
978
- phy_stop(pl->phydev);
9791283 if (pl->sfp_bus)
9801284 sfp_upstream_stop(pl->sfp_bus);
981
- if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio))
982
- del_timer_sync(&pl->link_poll);
1285
+ if (pl->phydev)
1286
+ phy_stop(pl->phydev);
1287
+ del_timer_sync(&pl->link_poll);
1288
+ if (pl->link_irq) {
1289
+ free_irq(pl->link_irq, pl);
1290
+ pl->link_irq = 0;
1291
+ }
9831292
9841293 phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
9851294 }
....@@ -1076,7 +1385,7 @@
10761385
10771386 linkmode_copy(kset->link_modes.supported, pl->supported);
10781387
1079
- switch (pl->link_an_mode) {
1388
+ switch (pl->cur_link_an_mode) {
10801389 case MLO_AN_FIXED:
10811390 /* We are using fixed settings. Report these as the
10821391 * current link settings - and note that these also
....@@ -1093,7 +1402,7 @@
10931402 if (pl->phydev)
10941403 break;
10951404
1096
- phylink_get_mac_state(pl, &link_state);
1405
+ phylink_mac_pcs_get_state(pl, &link_state);
10971406
10981407 /* The MAC is reporting the link results from its own PCS
10991408 * layer via in-band status. Report these as the current
....@@ -1115,90 +1424,146 @@
11151424 int phylink_ethtool_ksettings_set(struct phylink *pl,
11161425 const struct ethtool_link_ksettings *kset)
11171426 {
1118
- struct ethtool_link_ksettings our_kset;
1427
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support);
11191428 struct phylink_link_state config;
1120
- int ret;
1429
+ const struct phy_setting *s;
11211430
11221431 ASSERT_RTNL();
11231432
1124
- if (kset->base.autoneg != AUTONEG_DISABLE &&
1125
- kset->base.autoneg != AUTONEG_ENABLE)
1126
- return -EINVAL;
1433
+ if (pl->phydev) {
1434
+ /* We can rely on phylib for this update; we also do not need
1435
+ * to update the pl->link_config settings:
1436
+ * - the configuration returned via ksettings_get() will come
1437
+ * from phylib whenever a PHY is present.
1438
+ * - link_config.interface will be updated by the PHY calling
1439
+ * back via phylink_phy_change() and a subsequent resolve.
1440
+ * - initial link configuration for PHY mode comes from the
1441
+ * last phy state updated via phylink_phy_change().
1442
+ * - other configuration changes (e.g. pause modes) are
1443
+ * performed directly via phylib.
1444
+ * - if in in-band mode with a PHY, the link configuration
1445
+ * is passed on the link from the PHY, and all of
1446
+ * link_config.{speed,duplex,an_enabled,pause} are not used.
1447
+ * - the only possible use would be link_config.advertising
1448
+ * pause modes when in 1000base-X mode with a PHY, but in
1449
+ * the presence of a PHY, this should not be changed as that
1450
+ * should be determined from the media side advertisement.
1451
+ */
1452
+ return phy_ethtool_ksettings_set(pl->phydev, kset);
1453
+ }
11271454
1455
+ linkmode_copy(support, pl->supported);
11281456 config = pl->link_config;
1457
+ config.an_enabled = kset->base.autoneg == AUTONEG_ENABLE;
11291458
1130
- /* Mask out unsupported advertisements */
1459
+ /* Mask out unsupported advertisements, and force the autoneg bit */
11311460 linkmode_and(config.advertising, kset->link_modes.advertising,
1132
- pl->supported);
1461
+ support);
1462
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising,
1463
+ config.an_enabled);
11331464
11341465 /* FIXME: should we reject autoneg if phy/mac does not support it? */
1135
- if (kset->base.autoneg == AUTONEG_DISABLE) {
1136
- const struct phy_setting *s;
1137
-
1466
+ switch (kset->base.autoneg) {
1467
+ case AUTONEG_DISABLE:
11381468 /* Autonegotiation disabled, select a suitable speed and
11391469 * duplex.
11401470 */
11411471 s = phy_lookup_setting(kset->base.speed, kset->base.duplex,
1142
- pl->supported,
1143
- __ETHTOOL_LINK_MODE_MASK_NBITS, false);
1472
+ support, false);
11441473 if (!s)
11451474 return -EINVAL;
11461475
1147
- /* If we have a fixed link (as specified by firmware), refuse
1148
- * to change link parameters.
1476
+ /* If we have a fixed link, refuse to change link parameters.
1477
+ * If the link parameters match, accept them but do nothing.
11491478 */
1150
- if (pl->link_an_mode == MLO_AN_FIXED &&
1151
- (s->speed != pl->link_config.speed ||
1152
- s->duplex != pl->link_config.duplex))
1153
- return -EINVAL;
1479
+ if (pl->cur_link_an_mode == MLO_AN_FIXED) {
1480
+ if (s->speed != pl->link_config.speed ||
1481
+ s->duplex != pl->link_config.duplex)
1482
+ return -EINVAL;
1483
+ return 0;
1484
+ }
11541485
11551486 config.speed = s->speed;
11561487 config.duplex = s->duplex;
1157
- config.an_enabled = false;
1488
+ break;
11581489
1159
- __clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
1160
- } else {
1161
- /* If we have a fixed link, refuse to enable autonegotiation */
1162
- if (pl->link_an_mode == MLO_AN_FIXED)
1163
- return -EINVAL;
1490
+ case AUTONEG_ENABLE:
1491
+ /* If we have a fixed link, allow autonegotiation (since that
1492
+ * is our default case) but do not allow the advertisement to
1493
+ * be changed. If the advertisement matches, simply return.
1494
+ */
1495
+ if (pl->cur_link_an_mode == MLO_AN_FIXED) {
1496
+ if (!linkmode_equal(config.advertising,
1497
+ pl->link_config.advertising))
1498
+ return -EINVAL;
1499
+ return 0;
1500
+ }
11641501
11651502 config.speed = SPEED_UNKNOWN;
11661503 config.duplex = DUPLEX_UNKNOWN;
1167
- config.an_enabled = true;
1504
+ break;
11681505
1169
- __set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
1506
+ default:
1507
+ return -EINVAL;
11701508 }
11711509
1172
- if (phylink_validate(pl, pl->supported, &config))
1510
+ /* We have ruled out the case with a PHY attached, and the
1511
+ * fixed-link cases. All that is left are in-band links.
1512
+ */
1513
+ if (phylink_validate(pl, support, &config))
11731514 return -EINVAL;
11741515
11751516 /* If autonegotiation is enabled, we must have an advertisement */
11761517 if (config.an_enabled && phylink_is_empty_linkmode(config.advertising))
11771518 return -EINVAL;
11781519
1179
- our_kset = *kset;
1180
- linkmode_copy(our_kset.link_modes.advertising, config.advertising);
1181
- our_kset.base.speed = config.speed;
1182
- our_kset.base.duplex = config.duplex;
1520
+ /* If this link is with an SFP, ensure that changes to advertised modes
1521
+ * also cause the associated interface to be selected such that the
1522
+ * link can be configured correctly.
1523
+ */
1524
+ if (pl->sfp_port && pl->sfp_bus) {
1525
+ config.interface = sfp_select_interface(pl->sfp_bus,
1526
+ config.advertising);
1527
+ if (config.interface == PHY_INTERFACE_MODE_NA) {
1528
+ phylink_err(pl,
1529
+ "selection of interface failed, advertisement %*pb\n",
1530
+ __ETHTOOL_LINK_MODE_MASK_NBITS,
1531
+ config.advertising);
1532
+ return -EINVAL;
1533
+ }
11831534
1184
- /* If we have a PHY, configure the phy */
1185
- if (pl->phydev) {
1186
- ret = phy_ethtool_ksettings_set(pl->phydev, &our_kset);
1187
- if (ret)
1188
- return ret;
1535
+ /* Revalidate with the selected interface */
1536
+ linkmode_copy(support, pl->supported);
1537
+ if (phylink_validate(pl, support, &config)) {
1538
+ phylink_err(pl, "validation of %s/%s with support %*pb failed\n",
1539
+ phylink_an_mode_str(pl->cur_link_an_mode),
1540
+ phy_modes(config.interface),
1541
+ __ETHTOOL_LINK_MODE_MASK_NBITS, support);
1542
+ return -EINVAL;
1543
+ }
11891544 }
11901545
11911546 mutex_lock(&pl->state_mutex);
1192
- /* Configure the MAC to match the new settings */
1193
- linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising);
1194
- pl->link_config.interface = config.interface;
1195
- pl->link_config.speed = our_kset.base.speed;
1196
- pl->link_config.duplex = our_kset.base.duplex;
1197
- pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE;
1547
+ pl->link_config.speed = config.speed;
1548
+ pl->link_config.duplex = config.duplex;
1549
+ pl->link_config.an_enabled = config.an_enabled;
11981550
1199
- if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
1200
- phylink_mac_config(pl, &pl->link_config);
1201
- phylink_mac_an_restart(pl);
1551
+ if (pl->link_config.interface != config.interface) {
1552
+ /* The interface changed, e.g. 1000base-X <-> 2500base-X */
1553
+ /* We need to force the link down, then change the interface */
1554
+ if (pl->old_link_state) {
1555
+ phylink_link_down(pl);
1556
+ pl->old_link_state = false;
1557
+ }
1558
+ if (!test_bit(PHYLINK_DISABLE_STOPPED,
1559
+ &pl->phylink_disable_state))
1560
+ phylink_major_config(pl, false, &config);
1561
+ pl->link_config.interface = config.interface;
1562
+ linkmode_copy(pl->link_config.advertising, config.advertising);
1563
+ } else if (!linkmode_equal(pl->link_config.advertising,
1564
+ config.advertising)) {
1565
+ linkmode_copy(pl->link_config.advertising, config.advertising);
1566
+ phylink_change_inband_advert(pl);
12021567 }
12031568 mutex_unlock(&pl->state_mutex);
12041569
....@@ -1225,7 +1590,7 @@
12251590
12261591 if (pl->phydev)
12271592 ret = phy_restart_aneg(pl->phydev);
1228
- phylink_mac_an_restart(pl);
1593
+ phylink_mac_pcs_an_restart(pl);
12291594
12301595 return ret;
12311596 }
....@@ -1256,8 +1621,13 @@
12561621 struct ethtool_pauseparam *pause)
12571622 {
12581623 struct phylink_link_state *config = &pl->link_config;
1624
+ bool manual_changed;
1625
+ int pause_state;
12591626
12601627 ASSERT_RTNL();
1628
+
1629
+ if (pl->cur_link_an_mode == MLO_AN_FIXED)
1630
+ return -EOPNOTSUPP;
12611631
12621632 if (!phylink_test(pl->supported, Pause) &&
12631633 !phylink_test(pl->supported, Asym_Pause))
....@@ -1267,34 +1637,61 @@
12671637 pause->rx_pause != pause->tx_pause)
12681638 return -EINVAL;
12691639
1270
- config->pause &= ~(MLO_PAUSE_AN | MLO_PAUSE_TXRX_MASK);
1271
-
1640
+ pause_state = 0;
12721641 if (pause->autoneg)
1273
- config->pause |= MLO_PAUSE_AN;
1642
+ pause_state |= MLO_PAUSE_AN;
12741643 if (pause->rx_pause)
1275
- config->pause |= MLO_PAUSE_RX;
1644
+ pause_state |= MLO_PAUSE_RX;
12761645 if (pause->tx_pause)
1277
- config->pause |= MLO_PAUSE_TX;
1646
+ pause_state |= MLO_PAUSE_TX;
12781647
1279
- if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
1280
- switch (pl->link_an_mode) {
1281
- case MLO_AN_PHY:
1282
- /* Silently mark the carrier down, and then trigger a resolve */
1283
- netif_carrier_off(pl->netdev);
1284
- phylink_run_resolve(pl);
1285
- break;
1648
+ mutex_lock(&pl->state_mutex);
1649
+ /*
1650
+ * See the comments for linkmode_set_pause(), wrt the deficiencies
1651
+ * with the current implementation. A solution to this issue would
1652
+ * be:
1653
+ * ethtool Local device
1654
+ * rx tx Pause AsymDir
1655
+ * 0 0 0 0
1656
+ * 1 0 1 1
1657
+ * 0 1 0 1
1658
+ * 1 1 1 1
1659
+ * and then use the ethtool rx/tx enablement status to mask the
1660
+ * rx/tx pause resolution.
1661
+ */
1662
+ linkmode_set_pause(config->advertising, pause->tx_pause,
1663
+ pause->rx_pause);
12861664
1287
- case MLO_AN_FIXED:
1288
- /* Should we allow fixed links to change against the config? */
1289
- phylink_resolve_flow(pl, config);
1290
- phylink_mac_config(pl, config);
1291
- break;
1665
+ manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN ||
1666
+ (!(pause_state & MLO_PAUSE_AN) &&
1667
+ (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK);
12921668
1293
- case MLO_AN_INBAND:
1294
- phylink_mac_config(pl, config);
1295
- phylink_mac_an_restart(pl);
1296
- break;
1297
- }
1669
+ config->pause = pause_state;
1670
+
1671
+ /* Update our in-band advertisement, triggering a renegotiation if
1672
+ * the advertisement changed.
1673
+ */
1674
+ if (!pl->phydev)
1675
+ phylink_change_inband_advert(pl);
1676
+
1677
+ mutex_unlock(&pl->state_mutex);
1678
+
1679
+ /* If we have a PHY, a change of the pause frame advertisement will
1680
+ * cause phylib to renegotiate (if AN is enabled) which will in turn
1681
+ * call our phylink_phy_change() and trigger a resolve. Note that
1682
+ * we can't hold our state mutex while calling phy_set_asym_pause().
1683
+ */
1684
+ if (pl->phydev)
1685
+ phy_set_asym_pause(pl->phydev, pause->rx_pause,
1686
+ pause->tx_pause);
1687
+
1688
+ /* If the manual pause settings changed, make sure we trigger a
1689
+ * resolve to update their state; we can not guarantee that the
1690
+ * link will cycle.
1691
+ */
1692
+ if (manual_changed) {
1693
+ pl->mac_link_dropped = true;
1694
+ phylink_run_resolve(pl);
12981695 }
12991696
13001697 return 0;
....@@ -1323,6 +1720,24 @@
13231720 return ret;
13241721 }
13251722 EXPORT_SYMBOL_GPL(phylink_get_eee_err);
1723
+
1724
+/**
1725
+ * phylink_init_eee() - init and check the EEE features
1726
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
1727
+ * @clk_stop_enable: allow PHY to stop receive clock
1728
+ *
1729
+ * Must be called either with RTNL held or within mac_link_up()
1730
+ */
1731
+int phylink_init_eee(struct phylink *pl, bool clk_stop_enable)
1732
+{
1733
+ int ret = -EOPNOTSUPP;
1734
+
1735
+ if (pl->phydev)
1736
+ ret = phy_init_eee(pl->phydev, clk_stop_enable);
1737
+
1738
+ return ret;
1739
+}
1740
+EXPORT_SYMBOL_GPL(phylink_init_eee);
13261741
13271742 /**
13281743 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
....@@ -1365,24 +1780,23 @@
13651780 *
13661781 * FIXME: should deal with negotiation state too.
13671782 */
1368
-static int phylink_mii_emul_read(struct net_device *ndev, unsigned int reg,
1369
- struct phylink_link_state *state, bool aneg)
1783
+static int phylink_mii_emul_read(unsigned int reg,
1784
+ struct phylink_link_state *state)
13701785 {
13711786 struct fixed_phy_status fs;
1787
+ unsigned long *lpa = state->lp_advertising;
13721788 int val;
13731789
13741790 fs.link = state->link;
13751791 fs.speed = state->speed;
13761792 fs.duplex = state->duplex;
1377
- fs.pause = state->pause & MLO_PAUSE_SYM;
1378
- fs.asym_pause = state->pause & MLO_PAUSE_ASYM;
1793
+ fs.pause = test_bit(ETHTOOL_LINK_MODE_Pause_BIT, lpa);
1794
+ fs.asym_pause = test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, lpa);
13791795
13801796 val = swphy_read_reg(reg, &fs);
13811797 if (reg == MII_BMSR) {
13821798 if (!state->an_complete)
13831799 val &= ~BMSR_ANEGCOMPLETE;
1384
- if (!aneg)
1385
- val &= ~BMSR_ANEGCAPABLE;
13861800 }
13871801 return val;
13881802 }
....@@ -1396,18 +1810,18 @@
13961810 if (mdio_phy_id_is_c45(phy_id)) {
13971811 prtad = mdio_phy_id_prtad(phy_id);
13981812 devad = mdio_phy_id_devad(phy_id);
1399
- devad = MII_ADDR_C45 | devad << 16 | reg;
1813
+ devad = mdiobus_c45_addr(devad, reg);
14001814 } else if (phydev->is_c45) {
14011815 switch (reg) {
14021816 case MII_BMCR:
14031817 case MII_BMSR:
14041818 case MII_PHYSID1:
14051819 case MII_PHYSID2:
1406
- devad = __ffs(phydev->c45_ids.devices_in_package);
1820
+ devad = __ffs(phydev->c45_ids.mmds_present);
14071821 break;
14081822 case MII_ADVERTISE:
14091823 case MII_LPA:
1410
- if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN))
1824
+ if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN))
14111825 return -EINVAL;
14121826 devad = MDIO_MMD_AN;
14131827 if (reg == MII_ADVERTISE)
....@@ -1419,7 +1833,7 @@
14191833 return -EINVAL;
14201834 }
14211835 prtad = phy_id;
1422
- devad = MII_ADDR_C45 | devad << 16 | reg;
1836
+ devad = mdiobus_c45_addr(devad, reg);
14231837 } else {
14241838 prtad = phy_id;
14251839 devad = reg;
....@@ -1436,18 +1850,18 @@
14361850 if (mdio_phy_id_is_c45(phy_id)) {
14371851 prtad = mdio_phy_id_prtad(phy_id);
14381852 devad = mdio_phy_id_devad(phy_id);
1439
- devad = MII_ADDR_C45 | devad << 16 | reg;
1853
+ devad = mdiobus_c45_addr(devad, reg);
14401854 } else if (phydev->is_c45) {
14411855 switch (reg) {
14421856 case MII_BMCR:
14431857 case MII_BMSR:
14441858 case MII_PHYSID1:
14451859 case MII_PHYSID2:
1446
- devad = __ffs(phydev->c45_ids.devices_in_package);
1860
+ devad = __ffs(phydev->c45_ids.mmds_present);
14471861 break;
14481862 case MII_ADVERTISE:
14491863 case MII_LPA:
1450
- if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN))
1864
+ if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN))
14511865 return -EINVAL;
14521866 devad = MDIO_MMD_AN;
14531867 if (reg == MII_ADVERTISE)
....@@ -1459,7 +1873,7 @@
14591873 return -EINVAL;
14601874 }
14611875 prtad = phy_id;
1462
- devad = MII_ADDR_C45 | devad << 16 | reg;
1876
+ devad = mdiobus_c45_addr(devad, reg);
14631877 } else {
14641878 prtad = phy_id;
14651879 devad = reg;
....@@ -1474,12 +1888,11 @@
14741888 struct phylink_link_state state;
14751889 int val = 0xffff;
14761890
1477
- switch (pl->link_an_mode) {
1891
+ switch (pl->cur_link_an_mode) {
14781892 case MLO_AN_FIXED:
14791893 if (phy_id == 0) {
14801894 phylink_get_fixed_state(pl, &state);
1481
- val = phylink_mii_emul_read(pl->netdev, reg, &state,
1482
- true);
1895
+ val = phylink_mii_emul_read(reg, &state);
14831896 }
14841897 break;
14851898
....@@ -1488,12 +1901,8 @@
14881901
14891902 case MLO_AN_INBAND:
14901903 if (phy_id == 0) {
1491
- val = phylink_get_mac_state(pl, &state);
1492
- if (val < 0)
1493
- return val;
1494
-
1495
- val = phylink_mii_emul_read(pl->netdev, reg, &state,
1496
- true);
1904
+ phylink_mac_pcs_get_state(pl, &state);
1905
+ val = phylink_mii_emul_read(reg, &state);
14971906 }
14981907 break;
14991908 }
....@@ -1504,7 +1913,7 @@
15041913 static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
15051914 unsigned int reg, unsigned int val)
15061915 {
1507
- switch (pl->link_an_mode) {
1916
+ switch (pl->cur_link_an_mode) {
15081917 case MLO_AN_FIXED:
15091918 break;
15101919
....@@ -1548,7 +1957,7 @@
15481957 switch (cmd) {
15491958 case SIOCGMIIPHY:
15501959 mii->phy_id = pl->phydev->mdio.addr;
1551
- /* fall through */
1960
+ fallthrough;
15521961
15531962 case SIOCGMIIREG:
15541963 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num);
....@@ -1571,7 +1980,7 @@
15711980 switch (cmd) {
15721981 case SIOCGMIIPHY:
15731982 mii->phy_id = 0;
1574
- /* fall through */
1983
+ fallthrough;
15751984
15761985 case SIOCGMIIREG:
15771986 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num);
....@@ -1596,24 +2005,83 @@
15962005 }
15972006 EXPORT_SYMBOL_GPL(phylink_mii_ioctl);
15982007
1599
-static int phylink_sfp_module_insert(void *upstream,
1600
- const struct sfp_eeprom_id *id)
2008
+/**
2009
+ * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
2010
+ * link partners
2011
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
2012
+ * @sync: perform action synchronously
2013
+ *
2014
+ * If we have a PHY that is not part of a SFP module, then set the speed
2015
+ * as described in the phy_speed_down() function. Please see this function
2016
+ * for a description of the @sync parameter.
2017
+ *
2018
+ * Returns zero if there is no PHY, otherwise as per phy_speed_down().
2019
+ */
2020
+int phylink_speed_down(struct phylink *pl, bool sync)
16012021 {
1602
- struct phylink *pl = upstream;
1603
- __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
1604
- struct phylink_link_state config;
1605
- phy_interface_t iface;
16062022 int ret = 0;
1607
- bool changed;
1608
- u8 port;
16092023
16102024 ASSERT_RTNL();
16112025
1612
- sfp_parse_support(pl->sfp_bus, id, support);
1613
- port = sfp_parse_port(pl->sfp_bus, id, support);
2026
+ if (!pl->sfp_bus && pl->phydev)
2027
+ ret = phy_speed_down(pl->phydev, sync);
2028
+
2029
+ return ret;
2030
+}
2031
+EXPORT_SYMBOL_GPL(phylink_speed_down);
2032
+
2033
+/**
2034
+ * phylink_speed_up() - restore the advertised speeds prior to the call to
2035
+ * phylink_speed_down()
2036
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
2037
+ *
2038
+ * If we have a PHY that is not part of a SFP module, then restore the
2039
+ * PHY speeds as per phy_speed_up().
2040
+ *
2041
+ * Returns zero if there is no PHY, otherwise as per phy_speed_up().
2042
+ */
2043
+int phylink_speed_up(struct phylink *pl)
2044
+{
2045
+ int ret = 0;
2046
+
2047
+ ASSERT_RTNL();
2048
+
2049
+ if (!pl->sfp_bus && pl->phydev)
2050
+ ret = phy_speed_up(pl->phydev);
2051
+
2052
+ return ret;
2053
+}
2054
+EXPORT_SYMBOL_GPL(phylink_speed_up);
2055
+
2056
+static void phylink_sfp_attach(void *upstream, struct sfp_bus *bus)
2057
+{
2058
+ struct phylink *pl = upstream;
2059
+
2060
+ pl->netdev->sfp_bus = bus;
2061
+}
2062
+
2063
+static void phylink_sfp_detach(void *upstream, struct sfp_bus *bus)
2064
+{
2065
+ struct phylink *pl = upstream;
2066
+
2067
+ pl->netdev->sfp_bus = NULL;
2068
+}
2069
+
2070
+static int phylink_sfp_config(struct phylink *pl, u8 mode,
2071
+ const unsigned long *supported,
2072
+ const unsigned long *advertising)
2073
+{
2074
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support1);
2075
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support);
2076
+ struct phylink_link_state config;
2077
+ phy_interface_t iface;
2078
+ bool changed;
2079
+ int ret;
2080
+
2081
+ linkmode_copy(support, supported);
16142082
16152083 memset(&config, 0, sizeof(config));
1616
- linkmode_copy(config.advertising, support);
2084
+ linkmode_copy(config.advertising, advertising);
16172085 config.interface = PHY_INTERFACE_MODE_NA;
16182086 config.speed = SPEED_UNKNOWN;
16192087 config.duplex = DUPLEX_UNKNOWN;
....@@ -1623,63 +2091,113 @@
16232091 /* Ignore errors if we're expecting a PHY to attach later */
16242092 ret = phylink_validate(pl, support, &config);
16252093 if (ret) {
1626
- netdev_err(pl->netdev, "validation with support %*pb failed: %d\n",
1627
- __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret);
2094
+ phylink_err(pl, "validation with support %*pb failed: %d\n",
2095
+ __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret);
16282096 return ret;
16292097 }
16302098
1631
- iface = sfp_select_interface(pl->sfp_bus, id, config.advertising);
2099
+ iface = sfp_select_interface(pl->sfp_bus, config.advertising);
16322100 if (iface == PHY_INTERFACE_MODE_NA) {
1633
- netdev_err(pl->netdev,
1634
- "selection of interface failed, advertisement %*pb\n",
1635
- __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising);
2101
+ phylink_err(pl,
2102
+ "selection of interface failed, advertisement %*pb\n",
2103
+ __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising);
16362104 return -EINVAL;
16372105 }
16382106
16392107 config.interface = iface;
1640
- ret = phylink_validate(pl, support, &config);
2108
+ linkmode_copy(support1, support);
2109
+ ret = phylink_validate(pl, support1, &config);
16412110 if (ret) {
1642
- netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n",
1643
- phylink_an_mode_str(MLO_AN_INBAND),
1644
- phy_modes(config.interface),
1645
- __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret);
2111
+ phylink_err(pl, "validation of %s/%s with support %*pb failed: %d\n",
2112
+ phylink_an_mode_str(mode),
2113
+ phy_modes(config.interface),
2114
+ __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret);
16462115 return ret;
16472116 }
16482117
1649
- netdev_dbg(pl->netdev, "requesting link mode %s/%s with support %*pb\n",
1650
- phylink_an_mode_str(MLO_AN_INBAND),
1651
- phy_modes(config.interface),
1652
- __ETHTOOL_LINK_MODE_MASK_NBITS, support);
2118
+ phylink_dbg(pl, "requesting link mode %s/%s with support %*pb\n",
2119
+ phylink_an_mode_str(mode), phy_modes(config.interface),
2120
+ __ETHTOOL_LINK_MODE_MASK_NBITS, support);
16532121
16542122 if (phy_interface_mode_is_8023z(iface) && pl->phydev)
16552123 return -EINVAL;
16562124
1657
- changed = !bitmap_equal(pl->supported, support,
1658
- __ETHTOOL_LINK_MODE_MASK_NBITS);
2125
+ changed = !linkmode_equal(pl->supported, support) ||
2126
+ !linkmode_equal(pl->link_config.advertising,
2127
+ config.advertising);
16592128 if (changed) {
16602129 linkmode_copy(pl->supported, support);
16612130 linkmode_copy(pl->link_config.advertising, config.advertising);
16622131 }
16632132
1664
- if (pl->link_an_mode != MLO_AN_INBAND ||
2133
+ if (pl->cur_link_an_mode != mode ||
16652134 pl->link_config.interface != config.interface) {
16662135 pl->link_config.interface = config.interface;
1667
- pl->link_an_mode = MLO_AN_INBAND;
2136
+ pl->cur_link_an_mode = mode;
16682137
16692138 changed = true;
16702139
1671
- netdev_info(pl->netdev, "switched to %s/%s link mode\n",
1672
- phylink_an_mode_str(MLO_AN_INBAND),
1673
- phy_modes(config.interface));
2140
+ phylink_info(pl, "switched to %s/%s link mode\n",
2141
+ phylink_an_mode_str(mode),
2142
+ phy_modes(config.interface));
16742143 }
16752144
1676
- pl->link_port = port;
2145
+ pl->link_port = pl->sfp_port;
16772146
16782147 if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
16792148 &pl->phylink_disable_state))
1680
- phylink_mac_config(pl, &pl->link_config);
2149
+ phylink_mac_initial_config(pl, false);
16812150
16822151 return ret;
2152
+}
2153
+
2154
+static int phylink_sfp_module_insert(void *upstream,
2155
+ const struct sfp_eeprom_id *id)
2156
+{
2157
+ struct phylink *pl = upstream;
2158
+ unsigned long *support = pl->sfp_support;
2159
+
2160
+ ASSERT_RTNL();
2161
+
2162
+ linkmode_zero(support);
2163
+ sfp_parse_support(pl->sfp_bus, id, support);
2164
+ pl->sfp_port = sfp_parse_port(pl->sfp_bus, id, support);
2165
+
2166
+ /* If this module may have a PHY connecting later, defer until later */
2167
+ pl->sfp_may_have_phy = sfp_may_have_phy(pl->sfp_bus, id);
2168
+ if (pl->sfp_may_have_phy)
2169
+ return 0;
2170
+
2171
+ return phylink_sfp_config(pl, MLO_AN_INBAND, support, support);
2172
+}
2173
+
2174
+static int phylink_sfp_module_start(void *upstream)
2175
+{
2176
+ struct phylink *pl = upstream;
2177
+
2178
+ /* If this SFP module has a PHY, start the PHY now. */
2179
+ if (pl->phydev) {
2180
+ phy_start(pl->phydev);
2181
+ return 0;
2182
+ }
2183
+
2184
+ /* If the module may have a PHY but we didn't detect one we
2185
+ * need to configure the MAC here.
2186
+ */
2187
+ if (!pl->sfp_may_have_phy)
2188
+ return 0;
2189
+
2190
+ return phylink_sfp_config(pl, MLO_AN_INBAND,
2191
+ pl->sfp_support, pl->sfp_support);
2192
+}
2193
+
2194
+static void phylink_sfp_module_stop(void *upstream)
2195
+{
2196
+ struct phylink *pl = upstream;
2197
+
2198
+ /* If this SFP module has a PHY, stop it. */
2199
+ if (pl->phydev)
2200
+ phy_stop(pl->phydev);
16832201 }
16842202
16852203 static void phylink_sfp_link_down(void *upstream)
....@@ -1701,11 +2219,51 @@
17012219 phylink_run_resolve(pl);
17022220 }
17032221
2222
+/* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII
2223
+ * or 802.3z control word, so inband will not work.
2224
+ */
2225
+static bool phylink_phy_no_inband(struct phy_device *phy)
2226
+{
2227
+ return phy->is_c45 &&
2228
+ (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150;
2229
+}
2230
+
17042231 static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
17052232 {
17062233 struct phylink *pl = upstream;
2234
+ phy_interface_t interface;
2235
+ u8 mode;
2236
+ int ret;
17072237
1708
- return __phylink_connect_phy(upstream, phy, pl->link_config.interface);
2238
+ /*
2239
+ * This is the new way of dealing with flow control for PHYs,
2240
+ * as described by Timur Tabi in commit 529ed1275263 ("net: phy:
2241
+ * phy drivers should not set SUPPORTED_[Asym_]Pause") except
2242
+ * using our validate call to the MAC, we rely upon the MAC
2243
+ * clearing the bits from both supported and advertising fields.
2244
+ */
2245
+ phy_support_asym_pause(phy);
2246
+
2247
+ if (phylink_phy_no_inband(phy))
2248
+ mode = MLO_AN_PHY;
2249
+ else
2250
+ mode = MLO_AN_INBAND;
2251
+
2252
+ /* Do the initial configuration */
2253
+ ret = phylink_sfp_config(pl, mode, phy->supported, phy->advertising);
2254
+ if (ret < 0)
2255
+ return ret;
2256
+
2257
+ interface = pl->link_config.interface;
2258
+ ret = phylink_attach_phy(pl, phy, interface);
2259
+ if (ret < 0)
2260
+ return ret;
2261
+
2262
+ ret = phylink_bringup_phy(pl, phy, interface);
2263
+ if (ret)
2264
+ phy_detach(phy);
2265
+
2266
+ return ret;
17092267 }
17102268
17112269 static void phylink_sfp_disconnect_phy(void *upstream)
....@@ -1714,7 +2272,11 @@
17142272 }
17152273
17162274 static const struct sfp_upstream_ops sfp_phylink_ops = {
2275
+ .attach = phylink_sfp_attach,
2276
+ .detach = phylink_sfp_detach,
17172277 .module_insert = phylink_sfp_module_insert,
2278
+ .module_start = phylink_sfp_module_start,
2279
+ .module_stop = phylink_sfp_module_stop,
17182280 .link_up = phylink_sfp_link_up,
17192281 .link_down = phylink_sfp_link_down,
17202282 .connect_phy = phylink_sfp_connect_phy,
....@@ -1751,4 +2313,322 @@
17512313 }
17522314 EXPORT_SYMBOL_GPL(phylink_helper_basex_speed);
17532315
1754
-MODULE_LICENSE("GPL");
2316
+static void phylink_decode_c37_word(struct phylink_link_state *state,
2317
+ uint16_t config_reg, int speed)
2318
+{
2319
+ bool tx_pause, rx_pause;
2320
+ int fd_bit;
2321
+
2322
+ if (speed == SPEED_2500)
2323
+ fd_bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT;
2324
+ else
2325
+ fd_bit = ETHTOOL_LINK_MODE_1000baseX_Full_BIT;
2326
+
2327
+ mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit);
2328
+
2329
+ if (linkmode_test_bit(fd_bit, state->advertising) &&
2330
+ linkmode_test_bit(fd_bit, state->lp_advertising)) {
2331
+ state->speed = speed;
2332
+ state->duplex = DUPLEX_FULL;
2333
+ } else {
2334
+ /* negotiation failure */
2335
+ state->link = false;
2336
+ }
2337
+
2338
+ linkmode_resolve_pause(state->advertising, state->lp_advertising,
2339
+ &tx_pause, &rx_pause);
2340
+
2341
+ if (tx_pause)
2342
+ state->pause |= MLO_PAUSE_TX;
2343
+ if (rx_pause)
2344
+ state->pause |= MLO_PAUSE_RX;
2345
+}
2346
+
2347
+static void phylink_decode_sgmii_word(struct phylink_link_state *state,
2348
+ uint16_t config_reg)
2349
+{
2350
+ if (!(config_reg & LPA_SGMII_LINK)) {
2351
+ state->link = false;
2352
+ return;
2353
+ }
2354
+
2355
+ switch (config_reg & LPA_SGMII_SPD_MASK) {
2356
+ case LPA_SGMII_10:
2357
+ state->speed = SPEED_10;
2358
+ break;
2359
+ case LPA_SGMII_100:
2360
+ state->speed = SPEED_100;
2361
+ break;
2362
+ case LPA_SGMII_1000:
2363
+ state->speed = SPEED_1000;
2364
+ break;
2365
+ default:
2366
+ state->link = false;
2367
+ return;
2368
+ }
2369
+ if (config_reg & LPA_SGMII_FULL_DUPLEX)
2370
+ state->duplex = DUPLEX_FULL;
2371
+ else
2372
+ state->duplex = DUPLEX_HALF;
2373
+}
2374
+
2375
+/**
2376
+ * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
2377
+ * @state: a pointer to a struct phylink_link_state.
2378
+ * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
2379
+ *
2380
+ * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
2381
+ * code word. Decode the USXGMII code word and populate the corresponding fields
2382
+ * (speed, duplex) into the phylink_link_state structure.
2383
+ */
2384
+void phylink_decode_usxgmii_word(struct phylink_link_state *state,
2385
+ uint16_t lpa)
2386
+{
2387
+ switch (lpa & MDIO_USXGMII_SPD_MASK) {
2388
+ case MDIO_USXGMII_10:
2389
+ state->speed = SPEED_10;
2390
+ break;
2391
+ case MDIO_USXGMII_100:
2392
+ state->speed = SPEED_100;
2393
+ break;
2394
+ case MDIO_USXGMII_1000:
2395
+ state->speed = SPEED_1000;
2396
+ break;
2397
+ case MDIO_USXGMII_2500:
2398
+ state->speed = SPEED_2500;
2399
+ break;
2400
+ case MDIO_USXGMII_5000:
2401
+ state->speed = SPEED_5000;
2402
+ break;
2403
+ case MDIO_USXGMII_10G:
2404
+ state->speed = SPEED_10000;
2405
+ break;
2406
+ default:
2407
+ state->link = false;
2408
+ return;
2409
+ }
2410
+
2411
+ if (lpa & MDIO_USXGMII_FULL_DUPLEX)
2412
+ state->duplex = DUPLEX_FULL;
2413
+ else
2414
+ state->duplex = DUPLEX_HALF;
2415
+}
2416
+EXPORT_SYMBOL_GPL(phylink_decode_usxgmii_word);
2417
+
2418
+/**
2419
+ * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
2420
+ * @pcs: a pointer to a &struct mdio_device.
2421
+ * @state: a pointer to a &struct phylink_link_state.
2422
+ *
2423
+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2424
+ * clause 37 negotiation and/or SGMII control.
2425
+ *
2426
+ * Read the MAC PCS state from the MII device configured in @config and
2427
+ * parse the Clause 37 or Cisco SGMII link partner negotiation word into
2428
+ * the phylink @state structure. This is suitable to be directly plugged
2429
+ * into the mac_pcs_get_state() member of the struct phylink_mac_ops
2430
+ * structure.
2431
+ */
2432
+void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
2433
+ struct phylink_link_state *state)
2434
+{
2435
+ struct mii_bus *bus = pcs->bus;
2436
+ int addr = pcs->addr;
2437
+ int bmsr, lpa;
2438
+
2439
+ bmsr = mdiobus_read(bus, addr, MII_BMSR);
2440
+ lpa = mdiobus_read(bus, addr, MII_LPA);
2441
+ if (bmsr < 0 || lpa < 0) {
2442
+ state->link = false;
2443
+ return;
2444
+ }
2445
+
2446
+ state->link = !!(bmsr & BMSR_LSTATUS);
2447
+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
2448
+ if (!state->link)
2449
+ return;
2450
+
2451
+ switch (state->interface) {
2452
+ case PHY_INTERFACE_MODE_1000BASEX:
2453
+ phylink_decode_c37_word(state, lpa, SPEED_1000);
2454
+ break;
2455
+
2456
+ case PHY_INTERFACE_MODE_2500BASEX:
2457
+ phylink_decode_c37_word(state, lpa, SPEED_2500);
2458
+ break;
2459
+
2460
+ case PHY_INTERFACE_MODE_SGMII:
2461
+ case PHY_INTERFACE_MODE_QSGMII:
2462
+ phylink_decode_sgmii_word(state, lpa);
2463
+ break;
2464
+
2465
+ default:
2466
+ state->link = false;
2467
+ break;
2468
+ }
2469
+}
2470
+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
2471
+
2472
+/**
2473
+ * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
2474
+ * advertisement
2475
+ * @pcs: a pointer to a &struct mdio_device.
2476
+ * @interface: the PHY interface mode being configured
2477
+ * @advertising: the ethtool advertisement mask
2478
+ *
2479
+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2480
+ * clause 37 negotiation and/or SGMII control.
2481
+ *
2482
+ * Configure the clause 37 PCS advertisement as specified by @state. This
2483
+ * does not trigger a renegotiation; phylink will do that via the
2484
+ * mac_an_restart() method of the struct phylink_mac_ops structure.
2485
+ *
2486
+ * Returns negative error code on failure to configure the advertisement,
2487
+ * zero if no change has been made, or one if the advertisement has changed.
2488
+ */
2489
+int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
2490
+ phy_interface_t interface,
2491
+ const unsigned long *advertising)
2492
+{
2493
+ struct mii_bus *bus = pcs->bus;
2494
+ int addr = pcs->addr;
2495
+ int val, ret;
2496
+ u16 adv;
2497
+
2498
+ switch (interface) {
2499
+ case PHY_INTERFACE_MODE_1000BASEX:
2500
+ case PHY_INTERFACE_MODE_2500BASEX:
2501
+ adv = ADVERTISE_1000XFULL;
2502
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
2503
+ advertising))
2504
+ adv |= ADVERTISE_1000XPAUSE;
2505
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
2506
+ advertising))
2507
+ adv |= ADVERTISE_1000XPSE_ASYM;
2508
+
2509
+ val = mdiobus_read(bus, addr, MII_ADVERTISE);
2510
+ if (val < 0)
2511
+ return val;
2512
+
2513
+ if (val == adv)
2514
+ return 0;
2515
+
2516
+ ret = mdiobus_write(bus, addr, MII_ADVERTISE, adv);
2517
+ if (ret < 0)
2518
+ return ret;
2519
+
2520
+ return 1;
2521
+
2522
+ case PHY_INTERFACE_MODE_SGMII:
2523
+ val = mdiobus_read(bus, addr, MII_ADVERTISE);
2524
+ if (val < 0)
2525
+ return val;
2526
+
2527
+ if (val == 0x0001)
2528
+ return 0;
2529
+
2530
+ ret = mdiobus_write(bus, addr, MII_ADVERTISE, 0x0001);
2531
+ if (ret < 0)
2532
+ return ret;
2533
+
2534
+ return 1;
2535
+
2536
+ default:
2537
+ /* Nothing to do for other modes */
2538
+ return 0;
2539
+ }
2540
+}
2541
+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
2542
+
2543
+/**
2544
+ * phylink_mii_c22_pcs_config() - configure clause 22 PCS
2545
+ * @pcs: a pointer to a &struct mdio_device.
2546
+ * @mode: link autonegotiation mode
2547
+ * @interface: the PHY interface mode being configured
2548
+ * @advertising: the ethtool advertisement mask
2549
+ *
2550
+ * Configure a Clause 22 PCS PHY with the appropriate negotiation
2551
+ * parameters for the @mode, @interface and @advertising parameters.
2552
+ * Returns negative error number on failure, zero if the advertisement
2553
+ * has not changed, or positive if there is a change.
2554
+ */
2555
+int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode,
2556
+ phy_interface_t interface,
2557
+ const unsigned long *advertising)
2558
+{
2559
+ bool changed;
2560
+ u16 bmcr;
2561
+ int ret;
2562
+
2563
+ ret = phylink_mii_c22_pcs_set_advertisement(pcs, interface,
2564
+ advertising);
2565
+ if (ret < 0)
2566
+ return ret;
2567
+
2568
+ changed = ret > 0;
2569
+
2570
+ bmcr = mode == MLO_AN_INBAND ? BMCR_ANENABLE : 0;
2571
+ ret = mdiobus_modify(pcs->bus, pcs->addr, MII_BMCR,
2572
+ BMCR_ANENABLE, bmcr);
2573
+ if (ret < 0)
2574
+ return ret;
2575
+
2576
+ return changed ? 1 : 0;
2577
+}
2578
+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_config);
2579
+
2580
+/**
2581
+ * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
2582
+ * @pcs: a pointer to a &struct mdio_device.
2583
+ *
2584
+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2585
+ * clause 37 negotiation.
2586
+ *
2587
+ * Restart the clause 37 negotiation with the link partner. This is
2588
+ * suitable to be directly plugged into the mac_pcs_get_state() member
2589
+ * of the struct phylink_mac_ops structure.
2590
+ */
2591
+void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs)
2592
+{
2593
+ struct mii_bus *bus = pcs->bus;
2594
+ int val, addr = pcs->addr;
2595
+
2596
+ val = mdiobus_read(bus, addr, MII_BMCR);
2597
+ if (val >= 0) {
2598
+ val |= BMCR_ANRESTART;
2599
+
2600
+ mdiobus_write(bus, addr, MII_BMCR, val);
2601
+ }
2602
+}
2603
+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_an_restart);
2604
+
2605
+void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs,
2606
+ struct phylink_link_state *state)
2607
+{
2608
+ struct mii_bus *bus = pcs->bus;
2609
+ int addr = pcs->addr;
2610
+ int stat;
2611
+
2612
+ stat = mdiobus_c45_read(bus, addr, MDIO_MMD_PCS, MDIO_STAT1);
2613
+ if (stat < 0) {
2614
+ state->link = false;
2615
+ return;
2616
+ }
2617
+
2618
+ state->link = !!(stat & MDIO_STAT1_LSTATUS);
2619
+ if (!state->link)
2620
+ return;
2621
+
2622
+ switch (state->interface) {
2623
+ case PHY_INTERFACE_MODE_10GBASER:
2624
+ state->speed = SPEED_10000;
2625
+ state->duplex = DUPLEX_FULL;
2626
+ break;
2627
+
2628
+ default:
2629
+ break;
2630
+ }
2631
+}
2632
+EXPORT_SYMBOL_GPL(phylink_mii_c45_pcs_get_state);
2633
+
2634
+MODULE_LICENSE("GPL v2");