]> Git Repo - J-linux.git/blob - include/linux/mii.h
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / include / linux / mii.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * linux/mii.h: definitions for MII-compatible transceivers
4  * Originally drivers/net/sunhme.h.
5  *
6  * Copyright (C) 1996, 1999, 2001 David S. Miller ([email protected])
7  */
8 #ifndef __LINUX_MII_H__
9 #define __LINUX_MII_H__
10
11
12 #include <linux/if.h>
13 #include <linux/linkmode.h>
14 #include <uapi/linux/mii.h>
15
16 struct ethtool_cmd;
17
18 struct mii_if_info {
19         int phy_id;
20         int advertising;
21         int phy_id_mask;
22         int reg_num_mask;
23
24         unsigned int full_duplex : 1;   /* is full duplex? */
25         unsigned int force_media : 1;   /* is autoneg. disabled? */
26         unsigned int supports_gmii : 1; /* are GMII registers supported? */
27
28         struct net_device *dev;
29         int (*mdio_read) (struct net_device *dev, int phy_id, int location);
30         void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);
31 };
32
33 extern int mii_link_ok (struct mii_if_info *mii);
34 extern int mii_nway_restart (struct mii_if_info *mii);
35 extern void mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
36 extern void mii_ethtool_get_link_ksettings(
37         struct mii_if_info *mii, struct ethtool_link_ksettings *cmd);
38 extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
39 extern int mii_ethtool_set_link_ksettings(
40         struct mii_if_info *mii, const struct ethtool_link_ksettings *cmd);
41 extern int mii_check_gmii_support(struct mii_if_info *mii);
42 extern void mii_check_link (struct mii_if_info *mii);
43 extern unsigned int mii_check_media (struct mii_if_info *mii,
44                                      unsigned int ok_to_print,
45                                      unsigned int init_media);
46 extern int generic_mii_ioctl(struct mii_if_info *mii_if,
47                              struct mii_ioctl_data *mii_data, int cmd,
48                              unsigned int *duplex_changed);
49
50
51 static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
52 {
53         return (struct mii_ioctl_data *) &rq->ifr_ifru;
54 }
55
56 /**
57  * mii_nway_result
58  * @negotiated: value of MII ANAR and'd with ANLPAR
59  *
60  * Given a set of MII abilities, check each bit and returns the
61  * currently supported media, in the priority order defined by
62  * IEEE 802.3u.  We use LPA_xxx constants but note this is not the
63  * value of LPA solely, as described above.
64  *
65  * The one exception to IEEE 802.3u is that 100baseT4 is placed
66  * between 100T-full and 100T-half.  If your phy does not support
67  * 100T4 this is fine.  If your phy places 100T4 elsewhere in the
68  * priority order, you will need to roll your own function.
69  */
70 static inline unsigned int mii_nway_result (unsigned int negotiated)
71 {
72         unsigned int ret;
73
74         if (negotiated & LPA_100FULL)
75                 ret = LPA_100FULL;
76         else if (negotiated & LPA_100BASE4)
77                 ret = LPA_100BASE4;
78         else if (negotiated & LPA_100HALF)
79                 ret = LPA_100HALF;
80         else if (negotiated & LPA_10FULL)
81                 ret = LPA_10FULL;
82         else
83                 ret = LPA_10HALF;
84
85         return ret;
86 }
87
88 /**
89  * mii_duplex
90  * @duplex_lock: Non-zero if duplex is locked at full
91  * @negotiated: value of MII ANAR and'd with ANLPAR
92  *
93  * A small helper function for a common case.  Returns one
94  * if the media is operating or locked at full duplex, and
95  * returns zero otherwise.
96  */
97 static inline unsigned int mii_duplex (unsigned int duplex_lock,
98                                        unsigned int negotiated)
99 {
100         if (duplex_lock)
101                 return 1;
102         if (mii_nway_result(negotiated) & LPA_DUPLEX)
103                 return 1;
104         return 0;
105 }
106
107 /**
108  * ethtool_adv_to_mii_adv_t
109  * @ethadv: the ethtool advertisement settings
110  *
111  * A small helper function that translates ethtool advertisement
112  * settings to phy autonegotiation advertisements for the
113  * MII_ADVERTISE register.
114  */
115 static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
116 {
117         u32 result = 0;
118
119         if (ethadv & ADVERTISED_10baseT_Half)
120                 result |= ADVERTISE_10HALF;
121         if (ethadv & ADVERTISED_10baseT_Full)
122                 result |= ADVERTISE_10FULL;
123         if (ethadv & ADVERTISED_100baseT_Half)
124                 result |= ADVERTISE_100HALF;
125         if (ethadv & ADVERTISED_100baseT_Full)
126                 result |= ADVERTISE_100FULL;
127         if (ethadv & ADVERTISED_Pause)
128                 result |= ADVERTISE_PAUSE_CAP;
129         if (ethadv & ADVERTISED_Asym_Pause)
130                 result |= ADVERTISE_PAUSE_ASYM;
131
132         return result;
133 }
134
135 /**
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(const 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 /**
164  * mii_adv_to_ethtool_adv_t
165  * @adv: value of the MII_ADVERTISE register
166  *
167  * A small helper function that translates MII_ADVERTISE bits
168  * to ethtool advertisement settings.
169  */
170 static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
171 {
172         u32 result = 0;
173
174         if (adv & ADVERTISE_10HALF)
175                 result |= ADVERTISED_10baseT_Half;
176         if (adv & ADVERTISE_10FULL)
177                 result |= ADVERTISED_10baseT_Full;
178         if (adv & ADVERTISE_100HALF)
179                 result |= ADVERTISED_100baseT_Half;
180         if (adv & ADVERTISE_100FULL)
181                 result |= ADVERTISED_100baseT_Full;
182         if (adv & ADVERTISE_PAUSE_CAP)
183                 result |= ADVERTISED_Pause;
184         if (adv & ADVERTISE_PAUSE_ASYM)
185                 result |= ADVERTISED_Asym_Pause;
186
187         return result;
188 }
189
190 /**
191  * ethtool_adv_to_mii_ctrl1000_t
192  * @ethadv: the ethtool advertisement settings
193  *
194  * A small helper function that translates ethtool advertisement
195  * settings to phy autonegotiation advertisements for the
196  * MII_CTRL1000 register when in 1000T mode.
197  */
198 static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
199 {
200         u32 result = 0;
201
202         if (ethadv & ADVERTISED_1000baseT_Half)
203                 result |= ADVERTISE_1000HALF;
204         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
219 linkmode_adv_to_mii_ctrl1000_t(const unsigned long *advertising)
220 {
221         u32 result = 0;
222
223         if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
224                               advertising))
225                 result |= ADVERTISE_1000HALF;
226         if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
227                               advertising))
228                 result |= ADVERTISE_1000FULL;
229
230         return result;
231 }
232
233 /**
234  * mii_ctrl1000_to_ethtool_adv_t
235  * @adv: value of the MII_CTRL1000 register
236  *
237  * A small helper function that translates MII_CTRL1000
238  * bits, when in 1000Base-T mode, to ethtool
239  * advertisement settings.
240  */
241 static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
242 {
243         u32 result = 0;
244
245         if (adv & ADVERTISE_1000HALF)
246                 result |= ADVERTISED_1000baseT_Half;
247         if (adv & ADVERTISE_1000FULL)
248                 result |= ADVERTISED_1000baseT_Full;
249
250         return result;
251 }
252
253 /**
254  * mii_lpa_to_ethtool_lpa_t
255  * @adv: value of the MII_LPA register
256  *
257  * A small helper function that translates MII_LPA
258  * bits, when in 1000Base-T mode, to ethtool
259  * LP advertisement settings.
260  */
261 static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
262 {
263         u32 result = 0;
264
265         if (lpa & LPA_LPACK)
266                 result |= ADVERTISED_Autoneg;
267
268         return result | mii_adv_to_ethtool_adv_t(lpa);
269 }
270
271 /**
272  * mii_stat1000_to_ethtool_lpa_t
273  * @adv: value of the MII_STAT1000 register
274  *
275  * A small helper function that translates MII_STAT1000
276  * bits, when in 1000Base-T mode, to ethtool
277  * advertisement settings.
278  */
279 static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
280 {
281         u32 result = 0;
282
283         if (lpa & LPA_1000HALF)
284                 result |= ADVERTISED_1000baseT_Half;
285         if (lpa & LPA_1000FULL)
286                 result |= ADVERTISED_1000baseT_Full;
287
288         return result;
289 }
290
291 /**
292  * mii_stat1000_mod_linkmode_lpa_t
293  * @advertising: target the linkmode advertisement settings
294  * @adv: value of the MII_STAT1000 register
295  *
296  * A small helper function that translates MII_STAT1000 bits, when in
297  * 1000Base-T mode, to linkmode advertisement settings. Other bits in
298  * advertising are not changes.
299  */
300 static inline void mii_stat1000_mod_linkmode_lpa_t(unsigned long *advertising,
301                                                    u32 lpa)
302 {
303         linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
304                          advertising, lpa & LPA_1000HALF);
305
306         linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
307                          advertising, lpa & LPA_1000FULL);
308 }
309
310 /**
311  * ethtool_adv_to_mii_adv_x
312  * @ethadv: the ethtool advertisement settings
313  *
314  * A small helper function that translates ethtool advertisement
315  * settings to phy autonegotiation advertisements for the
316  * MII_CTRL1000 register when in 1000Base-X mode.
317  */
318 static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
319 {
320         u32 result = 0;
321
322         if (ethadv & ADVERTISED_1000baseT_Half)
323                 result |= ADVERTISE_1000XHALF;
324         if (ethadv & ADVERTISED_1000baseT_Full)
325                 result |= ADVERTISE_1000XFULL;
326         if (ethadv & ADVERTISED_Pause)
327                 result |= ADVERTISE_1000XPAUSE;
328         if (ethadv & ADVERTISED_Asym_Pause)
329                 result |= ADVERTISE_1000XPSE_ASYM;
330
331         return result;
332 }
333
334 /**
335  * mii_adv_to_ethtool_adv_x
336  * @adv: value of the MII_CTRL1000 register
337  *
338  * A small helper function that translates MII_CTRL1000
339  * bits, when in 1000Base-X mode, to ethtool
340  * advertisement settings.
341  */
342 static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
343 {
344         u32 result = 0;
345
346         if (adv & ADVERTISE_1000XHALF)
347                 result |= ADVERTISED_1000baseT_Half;
348         if (adv & ADVERTISE_1000XFULL)
349                 result |= ADVERTISED_1000baseT_Full;
350         if (adv & ADVERTISE_1000XPAUSE)
351                 result |= ADVERTISED_Pause;
352         if (adv & ADVERTISE_1000XPSE_ASYM)
353                 result |= ADVERTISED_Asym_Pause;
354
355         return result;
356 }
357
358 /**
359  * mii_adv_mod_linkmode_adv_t
360  * @advertising:pointer to destination link mode.
361  * @adv: value of the MII_ADVERTISE register
362  *
363  * A small helper function that translates MII_ADVERTISE bits to
364  * linkmode advertisement settings. Leaves other bits unchanged.
365  */
366 static inline void mii_adv_mod_linkmode_adv_t(unsigned long *advertising,
367                                               u32 adv)
368 {
369         linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
370                          advertising, adv & ADVERTISE_10HALF);
371
372         linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
373                          advertising, adv & ADVERTISE_10FULL);
374
375         linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
376                          advertising, adv & ADVERTISE_100HALF);
377
378         linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
379                          advertising, adv & ADVERTISE_100FULL);
380
381         linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising,
382                          adv & ADVERTISE_PAUSE_CAP);
383
384         linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
385                          advertising, adv & ADVERTISE_PAUSE_ASYM);
386 }
387
388 /**
389  * mii_adv_to_linkmode_adv_t
390  * @advertising:pointer to destination link mode.
391  * @adv: value of the MII_ADVERTISE register
392  *
393  * A small helper function that translates MII_ADVERTISE bits
394  * to linkmode advertisement settings. Clears the old value
395  * of advertising.
396  */
397 static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
398                                              u32 adv)
399 {
400         linkmode_zero(advertising);
401
402         mii_adv_mod_linkmode_adv_t(advertising, adv);
403 }
404
405 /**
406  * mii_lpa_to_linkmode_lpa_t
407  * @adv: value of the MII_LPA register
408  *
409  * A small helper function that translates MII_LPA bits, when in
410  * 1000Base-T mode, to linkmode LP advertisement settings. Clears the
411  * old value of advertising
412  */
413 static inline void mii_lpa_to_linkmode_lpa_t(unsigned long *lp_advertising,
414                                              u32 lpa)
415 {
416         mii_adv_to_linkmode_adv_t(lp_advertising, lpa);
417
418         if (lpa & LPA_LPACK)
419                 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
420                                  lp_advertising);
421
422 }
423
424 /**
425  * mii_lpa_mod_linkmode_lpa_t
426  * @adv: value of the MII_LPA register
427  *
428  * A small helper function that translates MII_LPA bits, when in
429  * 1000Base-T mode, to linkmode LP advertisement settings. Leaves
430  * other bits unchanged.
431  */
432 static inline void mii_lpa_mod_linkmode_lpa_t(unsigned long *lp_advertising,
433                                               u32 lpa)
434 {
435         mii_adv_mod_linkmode_adv_t(lp_advertising, lpa);
436
437         linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
438                          lp_advertising, lpa & LPA_LPACK);
439 }
440
441 static inline void mii_ctrl1000_mod_linkmode_adv_t(unsigned long *advertising,
442                                                    u32 ctrl1000)
443 {
444         linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertising,
445                          ctrl1000 & ADVERTISE_1000HALF);
446         linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising,
447                          ctrl1000 & ADVERTISE_1000FULL);
448 }
449
450 /**
451  * linkmode_adv_to_lcl_adv_t
452  * @advertising:pointer to linkmode advertising
453  *
454  * A small helper function that translates linkmode advertising to LVL
455  * pause capabilities.
456  */
457 static inline u32 linkmode_adv_to_lcl_adv_t(const unsigned long *advertising)
458 {
459         u32 lcl_adv = 0;
460
461         if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
462                               advertising))
463                 lcl_adv |= ADVERTISE_PAUSE_CAP;
464         if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
465                               advertising))
466                 lcl_adv |= ADVERTISE_PAUSE_ASYM;
467
468         return lcl_adv;
469 }
470
471 /**
472  * mii_lpa_mod_linkmode_x - decode the link partner's config_reg to linkmodes
473  * @linkmodes: link modes array
474  * @lpa: config_reg word from link partner
475  * @fd_bit: link mode for 1000XFULL bit
476  */
477 static inline void mii_lpa_mod_linkmode_x(unsigned long *linkmodes, u16 lpa,
478                                          int fd_bit)
479 {
480         linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, linkmodes,
481                          lpa & LPA_LPACK);
482         linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes,
483                          lpa & LPA_1000XPAUSE);
484         linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes,
485                          lpa & LPA_1000XPAUSE_ASYM);
486         linkmode_mod_bit(fd_bit, linkmodes,
487                          lpa & LPA_1000XFULL);
488 }
489
490 /**
491  * linkmode_adv_to_mii_adv_x - encode a linkmode to config_reg
492  * @linkmodes: linkmodes
493  * @fd_bit: full duplex bit
494  */
495 static inline u16 linkmode_adv_to_mii_adv_x(const unsigned long *linkmodes,
496                                             int fd_bit)
497 {
498         u16 adv = 0;
499
500         if (linkmode_test_bit(fd_bit, linkmodes))
501                 adv |= ADVERTISE_1000XFULL;
502         if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes))
503                 adv |= ADVERTISE_1000XPAUSE;
504         if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes))
505                 adv |= ADVERTISE_1000XPSE_ASYM;
506
507         return adv;
508 }
509
510 /**
511  * mii_advertise_flowctrl - get flow control advertisement flags
512  * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
513  */
514 static inline u16 mii_advertise_flowctrl(int cap)
515 {
516         u16 adv = 0;
517
518         if (cap & FLOW_CTRL_RX)
519                 adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
520         if (cap & FLOW_CTRL_TX)
521                 adv ^= ADVERTISE_PAUSE_ASYM;
522
523         return adv;
524 }
525
526 /**
527  * mii_resolve_flowctrl_fdx
528  * @lcladv: value of MII ADVERTISE register
529  * @rmtadv: value of MII LPA register
530  *
531  * Resolve full duplex flow control as per IEEE 802.3-2005 table 28B-3
532  */
533 static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
534 {
535         u8 cap = 0;
536
537         if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
538                 cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
539         } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
540                 if (lcladv & ADVERTISE_PAUSE_CAP)
541                         cap = FLOW_CTRL_RX;
542                 else if (rmtadv & ADVERTISE_PAUSE_CAP)
543                         cap = FLOW_CTRL_TX;
544         }
545
546         return cap;
547 }
548
549 /**
550  * mii_bmcr_encode_fixed - encode fixed speed/duplex settings to a BMCR value
551  * @speed: a SPEED_* value
552  * @duplex: a DUPLEX_* value
553  *
554  * Encode the speed and duplex to a BMCR value. 2500, 1000, 100 and 10 Mbps are
555  * supported. 2500Mbps is encoded to 1000Mbps. Other speeds are encoded as 10
556  * Mbps. Unknown duplex values are encoded to half-duplex.
557  */
558 static inline u16 mii_bmcr_encode_fixed(int speed, int duplex)
559 {
560         u16 bmcr;
561
562         switch (speed) {
563         case SPEED_2500:
564         case SPEED_1000:
565                 bmcr = BMCR_SPEED1000;
566                 break;
567
568         case SPEED_100:
569                 bmcr = BMCR_SPEED100;
570                 break;
571
572         case SPEED_10:
573         default:
574                 bmcr = BMCR_SPEED10;
575                 break;
576         }
577
578         if (duplex == DUPLEX_FULL)
579                 bmcr |= BMCR_FULLDPLX;
580
581         return bmcr;
582 }
583
584 #endif /* __LINUX_MII_H__ */
This page took 0.059286 seconds and 4 git commands to generate.