hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/include/linux/mii.h
....@@ -10,6 +10,7 @@
1010
1111
1212 #include <linux/if.h>
13
+#include <linux/linkmode.h>
1314 #include <uapi/linux/mii.h>
1415
1516 struct ethtool_cmd;
....@@ -132,6 +133,34 @@
132133 }
133134
134135 /**
136
+ * linkmode_adv_to_mii_adv_t
137
+ * @advertising: the linkmode advertisement settings
138
+ *
139
+ * A small helper function that translates linkmode advertisement
140
+ * settings to phy autonegotiation advertisements for the
141
+ * MII_ADVERTISE register.
142
+ */
143
+static inline u32 linkmode_adv_to_mii_adv_t(unsigned long *advertising)
144
+{
145
+ u32 result = 0;
146
+
147
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, advertising))
148
+ result |= ADVERTISE_10HALF;
149
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, advertising))
150
+ result |= ADVERTISE_10FULL;
151
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, advertising))
152
+ result |= ADVERTISE_100HALF;
153
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, advertising))
154
+ result |= ADVERTISE_100FULL;
155
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising))
156
+ result |= ADVERTISE_PAUSE_CAP;
157
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising))
158
+ result |= ADVERTISE_PAUSE_ASYM;
159
+
160
+ return result;
161
+}
162
+
163
+/**
135164 * mii_adv_to_ethtool_adv_t
136165 * @adv: value of the MII_ADVERTISE register
137166 *
....@@ -173,6 +202,28 @@
173202 if (ethadv & ADVERTISED_1000baseT_Half)
174203 result |= ADVERTISE_1000HALF;
175204 if (ethadv & ADVERTISED_1000baseT_Full)
205
+ result |= ADVERTISE_1000FULL;
206
+
207
+ return result;
208
+}
209
+
210
+/**
211
+ * linkmode_adv_to_mii_ctrl1000_t
212
+ * @advertising: the linkmode advertisement settings
213
+ *
214
+ * A small helper function that translates linkmode advertisement
215
+ * settings to phy autonegotiation advertisements for the
216
+ * MII_CTRL1000 register when in 1000T mode.
217
+ */
218
+static inline u32 linkmode_adv_to_mii_ctrl1000_t(unsigned long *advertising)
219
+{
220
+ u32 result = 0;
221
+
222
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
223
+ advertising))
224
+ result |= ADVERTISE_1000HALF;
225
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
226
+ advertising))
176227 result |= ADVERTISE_1000FULL;
177228
178229 return result;
....@@ -237,6 +288,25 @@
237288 }
238289
239290 /**
291
+ * mii_stat1000_mod_linkmode_lpa_t
292
+ * @advertising: target the linkmode advertisement settings
293
+ * @adv: value of the MII_STAT1000 register
294
+ *
295
+ * A small helper function that translates MII_STAT1000 bits, when in
296
+ * 1000Base-T mode, to linkmode advertisement settings. Other bits in
297
+ * advertising are not changes.
298
+ */
299
+static inline void mii_stat1000_mod_linkmode_lpa_t(unsigned long *advertising,
300
+ u32 lpa)
301
+{
302
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
303
+ advertising, lpa & LPA_1000HALF);
304
+
305
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
306
+ advertising, lpa & LPA_1000FULL);
307
+}
308
+
309
+/**
240310 * ethtool_adv_to_mii_adv_x
241311 * @ethadv: the ethtool advertisement settings
242312 *
....@@ -285,21 +355,205 @@
285355 }
286356
287357 /**
288
- * mii_lpa_to_ethtool_lpa_x
358
+ * mii_lpa_mod_linkmode_adv_sgmii
359
+ * @lp_advertising: pointer to destination link mode.
360
+ * @lpa: value of the MII_LPA register
361
+ *
362
+ * A small helper function that translates MII_LPA bits to
363
+ * linkmode advertisement settings for SGMII.
364
+ * Leaves other bits unchanged.
365
+ */
366
+static inline void
367
+mii_lpa_mod_linkmode_lpa_sgmii(unsigned long *lp_advertising, u32 lpa)
368
+{
369
+ u32 speed_duplex = lpa & LPA_SGMII_DPX_SPD_MASK;
370
+
371
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, lp_advertising,
372
+ speed_duplex == LPA_SGMII_1000HALF);
373
+
374
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, lp_advertising,
375
+ speed_duplex == LPA_SGMII_1000FULL);
376
+
377
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, lp_advertising,
378
+ speed_duplex == LPA_SGMII_100HALF);
379
+
380
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, lp_advertising,
381
+ speed_duplex == LPA_SGMII_100FULL);
382
+
383
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, lp_advertising,
384
+ speed_duplex == LPA_SGMII_10HALF);
385
+
386
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, lp_advertising,
387
+ speed_duplex == LPA_SGMII_10FULL);
388
+}
389
+
390
+/**
391
+ * mii_lpa_to_linkmode_adv_sgmii
392
+ * @advertising: pointer to destination link mode.
393
+ * @lpa: value of the MII_LPA register
394
+ *
395
+ * A small helper function that translates MII_ADVERTISE bits
396
+ * to linkmode advertisement settings when in SGMII mode.
397
+ * Clears the old value of advertising.
398
+ */
399
+static inline void mii_lpa_to_linkmode_lpa_sgmii(unsigned long *lp_advertising,
400
+ u32 lpa)
401
+{
402
+ linkmode_zero(lp_advertising);
403
+
404
+ mii_lpa_mod_linkmode_lpa_sgmii(lp_advertising, lpa);
405
+}
406
+
407
+/**
408
+ * mii_adv_mod_linkmode_adv_t
409
+ * @advertising:pointer to destination link mode.
410
+ * @adv: value of the MII_ADVERTISE register
411
+ *
412
+ * A small helper function that translates MII_ADVERTISE bits to
413
+ * linkmode advertisement settings. Leaves other bits unchanged.
414
+ */
415
+static inline void mii_adv_mod_linkmode_adv_t(unsigned long *advertising,
416
+ u32 adv)
417
+{
418
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
419
+ advertising, adv & ADVERTISE_10HALF);
420
+
421
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
422
+ advertising, adv & ADVERTISE_10FULL);
423
+
424
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
425
+ advertising, adv & ADVERTISE_100HALF);
426
+
427
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
428
+ advertising, adv & ADVERTISE_100FULL);
429
+
430
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising,
431
+ adv & ADVERTISE_PAUSE_CAP);
432
+
433
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
434
+ advertising, adv & ADVERTISE_PAUSE_ASYM);
435
+}
436
+
437
+/**
438
+ * mii_adv_to_linkmode_adv_t
439
+ * @advertising:pointer to destination link mode.
440
+ * @adv: value of the MII_ADVERTISE register
441
+ *
442
+ * A small helper function that translates MII_ADVERTISE bits
443
+ * to linkmode advertisement settings. Clears the old value
444
+ * of advertising.
445
+ */
446
+static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
447
+ u32 adv)
448
+{
449
+ linkmode_zero(advertising);
450
+
451
+ mii_adv_mod_linkmode_adv_t(advertising, adv);
452
+}
453
+
454
+/**
455
+ * mii_lpa_to_linkmode_lpa_t
289456 * @adv: value of the MII_LPA register
290457 *
291
- * A small helper function that translates MII_LPA
292
- * bits, when in 1000Base-X mode, to ethtool
293
- * LP advertisement settings.
458
+ * A small helper function that translates MII_LPA bits, when in
459
+ * 1000Base-T mode, to linkmode LP advertisement settings. Clears the
460
+ * old value of advertising
294461 */
295
-static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa)
462
+static inline void mii_lpa_to_linkmode_lpa_t(unsigned long *lp_advertising,
463
+ u32 lpa)
296464 {
297
- u32 result = 0;
465
+ mii_adv_to_linkmode_adv_t(lp_advertising, lpa);
298466
299467 if (lpa & LPA_LPACK)
300
- result |= ADVERTISED_Autoneg;
468
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
469
+ lp_advertising);
301470
302
- return result | mii_adv_to_ethtool_adv_x(lpa);
471
+}
472
+
473
+/**
474
+ * mii_lpa_mod_linkmode_lpa_t
475
+ * @adv: value of the MII_LPA register
476
+ *
477
+ * A small helper function that translates MII_LPA bits, when in
478
+ * 1000Base-T mode, to linkmode LP advertisement settings. Leaves
479
+ * other bits unchanged.
480
+ */
481
+static inline void mii_lpa_mod_linkmode_lpa_t(unsigned long *lp_advertising,
482
+ u32 lpa)
483
+{
484
+ mii_adv_mod_linkmode_adv_t(lp_advertising, lpa);
485
+
486
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
487
+ lp_advertising, lpa & LPA_LPACK);
488
+}
489
+
490
+static inline void mii_ctrl1000_mod_linkmode_adv_t(unsigned long *advertising,
491
+ u32 ctrl1000)
492
+{
493
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertising,
494
+ ctrl1000 & ADVERTISE_1000HALF);
495
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising,
496
+ ctrl1000 & ADVERTISE_1000FULL);
497
+}
498
+
499
+/**
500
+ * linkmode_adv_to_lcl_adv_t
501
+ * @advertising:pointer to linkmode advertising
502
+ *
503
+ * A small helper function that translates linkmode advertising to LVL
504
+ * pause capabilities.
505
+ */
506
+static inline u32 linkmode_adv_to_lcl_adv_t(unsigned long *advertising)
507
+{
508
+ u32 lcl_adv = 0;
509
+
510
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
511
+ advertising))
512
+ lcl_adv |= ADVERTISE_PAUSE_CAP;
513
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
514
+ advertising))
515
+ lcl_adv |= ADVERTISE_PAUSE_ASYM;
516
+
517
+ return lcl_adv;
518
+}
519
+
520
+/**
521
+ * mii_lpa_mod_linkmode_x - decode the link partner's config_reg to linkmodes
522
+ * @linkmodes: link modes array
523
+ * @lpa: config_reg word from link partner
524
+ * @fd_bit: link mode for 1000XFULL bit
525
+ */
526
+static inline void mii_lpa_mod_linkmode_x(unsigned long *linkmodes, u16 lpa,
527
+ int fd_bit)
528
+{
529
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, linkmodes,
530
+ lpa & LPA_LPACK);
531
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes,
532
+ lpa & LPA_1000XPAUSE);
533
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes,
534
+ lpa & LPA_1000XPAUSE_ASYM);
535
+ linkmode_mod_bit(fd_bit, linkmodes,
536
+ lpa & LPA_1000XFULL);
537
+}
538
+
539
+/**
540
+ * linkmode_adv_to_mii_adv_x - encode a linkmode to config_reg
541
+ * @linkmodes: linkmodes
542
+ * @fd_bit: full duplex bit
543
+ */
544
+static inline u16 linkmode_adv_to_mii_adv_x(const unsigned long *linkmodes,
545
+ int fd_bit)
546
+{
547
+ u16 adv = 0;
548
+
549
+ if (linkmode_test_bit(fd_bit, linkmodes))
550
+ adv |= ADVERTISE_1000XFULL;
551
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes))
552
+ adv |= ADVERTISE_1000XPAUSE;
553
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes))
554
+ adv |= ADVERTISE_1000XPSE_ASYM;
555
+
556
+ return adv;
303557 }
304558
305559 /**