Branch data Line data Source code
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 (davem@redhat.com)
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 int 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 : 0 : static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
52 : : {
53 [ # # # # : 0 : 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 : 0 : static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
116 : : {
117 : 0 : u32 result = 0;
118 : :
119 [ # # ]: 0 : if (ethadv & ADVERTISED_10baseT_Half)
120 : 0 : result |= ADVERTISE_10HALF;
121 [ # # ]: 0 : if (ethadv & ADVERTISED_10baseT_Full)
122 : 0 : result |= ADVERTISE_10FULL;
123 [ # # ]: 0 : if (ethadv & ADVERTISED_100baseT_Half)
124 : 0 : result |= ADVERTISE_100HALF;
125 [ # # ]: 0 : if (ethadv & ADVERTISED_100baseT_Full)
126 : 0 : result |= ADVERTISE_100FULL;
127 [ # # ]: 0 : if (ethadv & ADVERTISED_Pause)
128 : 0 : result |= ADVERTISE_PAUSE_CAP;
129 [ # # ]: 0 : if (ethadv & ADVERTISED_Asym_Pause)
130 : 0 : result |= ADVERTISE_PAUSE_ASYM;
131 : :
132 : 0 : 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 : 0 : static inline u32 linkmode_adv_to_mii_adv_t(unsigned long *advertising)
144 : : {
145 : 0 : u32 result = 0;
146 : :
147 [ # # ]: 0 : if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, advertising))
148 : 0 : result |= ADVERTISE_10HALF;
149 [ # # ]: 0 : if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, advertising))
150 : 0 : result |= ADVERTISE_10FULL;
151 [ # # ]: 0 : if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, advertising))
152 : 0 : result |= ADVERTISE_100HALF;
153 [ # # ]: 0 : if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, advertising))
154 : 0 : result |= ADVERTISE_100FULL;
155 [ # # ]: 0 : if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising))
156 : 0 : result |= ADVERTISE_PAUSE_CAP;
157 [ # # ]: 0 : if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising))
158 : 0 : result |= ADVERTISE_PAUSE_ASYM;
159 : :
160 : 0 : 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 : 0 : static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
171 : : {
172 : 0 : u32 result = 0;
173 : :
174 [ # # ]: 0 : if (adv & ADVERTISE_10HALF)
175 : 0 : result |= ADVERTISED_10baseT_Half;
176 [ # # ]: 0 : if (adv & ADVERTISE_10FULL)
177 : 0 : result |= ADVERTISED_10baseT_Full;
178 [ # # ]: 0 : if (adv & ADVERTISE_100HALF)
179 : 0 : result |= ADVERTISED_100baseT_Half;
180 [ # # ]: 0 : if (adv & ADVERTISE_100FULL)
181 : 0 : result |= ADVERTISED_100baseT_Full;
182 [ # # ]: 0 : if (adv & ADVERTISE_PAUSE_CAP)
183 : 0 : result |= ADVERTISED_Pause;
184 [ # # ]: 0 : if (adv & ADVERTISE_PAUSE_ASYM)
185 : 0 : result |= ADVERTISED_Asym_Pause;
186 : :
187 : 0 : 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 : 0 : static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
199 : : {
200 : 0 : u32 result = 0;
201 : :
202 [ # # # # ]: 0 : if (ethadv & ADVERTISED_1000baseT_Half)
203 : 0 : result |= ADVERTISE_1000HALF;
204 [ # # # # ]: 0 : if (ethadv & ADVERTISED_1000baseT_Full)
205 : 0 : result |= ADVERTISE_1000FULL;
206 : :
207 [ # # ]: 0 : 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 : 0 : static inline u32 linkmode_adv_to_mii_ctrl1000_t(unsigned long *advertising)
219 : : {
220 : 0 : u32 result = 0;
221 : :
222 [ # # ]: 0 : if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
223 : : advertising))
224 : 0 : result |= ADVERTISE_1000HALF;
225 [ # # ]: 0 : if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
226 : : advertising))
227 : 0 : result |= ADVERTISE_1000FULL;
228 : :
229 : 0 : return result;
230 : : }
231 : :
232 : : /**
233 : : * mii_ctrl1000_to_ethtool_adv_t
234 : : * @adv: value of the MII_CTRL1000 register
235 : : *
236 : : * A small helper function that translates MII_CTRL1000
237 : : * bits, when in 1000Base-T mode, to ethtool
238 : : * advertisement settings.
239 : : */
240 : 0 : static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
241 : : {
242 : 0 : u32 result = 0;
243 : :
244 [ # # ]: 0 : if (adv & ADVERTISE_1000HALF)
245 : 0 : result |= ADVERTISED_1000baseT_Half;
246 [ # # ]: 0 : if (adv & ADVERTISE_1000FULL)
247 : 0 : result |= ADVERTISED_1000baseT_Full;
248 : :
249 : : return result;
250 : : }
251 : :
252 : : /**
253 : : * mii_lpa_to_ethtool_lpa_t
254 : : * @adv: value of the MII_LPA register
255 : : *
256 : : * A small helper function that translates MII_LPA
257 : : * bits, when in 1000Base-T mode, to ethtool
258 : : * LP advertisement settings.
259 : : */
260 : 0 : static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
261 : : {
262 : 0 : u32 result = 0;
263 : :
264 [ # # ]: 0 : if (lpa & LPA_LPACK)
265 : 0 : result |= ADVERTISED_Autoneg;
266 : :
267 : 0 : return result | mii_adv_to_ethtool_adv_t(lpa);
268 : : }
269 : :
270 : : /**
271 : : * mii_stat1000_to_ethtool_lpa_t
272 : : * @adv: value of the MII_STAT1000 register
273 : : *
274 : : * A small helper function that translates MII_STAT1000
275 : : * bits, when in 1000Base-T mode, to ethtool
276 : : * advertisement settings.
277 : : */
278 : 0 : static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
279 : : {
280 : 0 : u32 result = 0;
281 : :
282 [ # # ]: 0 : if (lpa & LPA_1000HALF)
283 : 0 : result |= ADVERTISED_1000baseT_Half;
284 [ # # ]: 0 : if (lpa & LPA_1000FULL)
285 : 0 : result |= ADVERTISED_1000baseT_Full;
286 : :
287 : 0 : return result;
288 : : }
289 : :
290 : : /**
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 : 0 : static inline void mii_stat1000_mod_linkmode_lpa_t(unsigned long *advertising,
300 : : u32 lpa)
301 : : {
302 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
303 : 0 : advertising, lpa & LPA_1000HALF);
304 : :
305 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
306 : : advertising, lpa & LPA_1000FULL);
307 : 0 : }
308 : :
309 : : /**
310 : : * ethtool_adv_to_mii_adv_x
311 : : * @ethadv: the ethtool advertisement settings
312 : : *
313 : : * A small helper function that translates ethtool advertisement
314 : : * settings to phy autonegotiation advertisements for the
315 : : * MII_CTRL1000 register when in 1000Base-X mode.
316 : : */
317 : 0 : static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
318 : : {
319 : 0 : u32 result = 0;
320 : :
321 [ # # ]: 0 : if (ethadv & ADVERTISED_1000baseT_Half)
322 : 0 : result |= ADVERTISE_1000XHALF;
323 [ # # ]: 0 : if (ethadv & ADVERTISED_1000baseT_Full)
324 : 0 : result |= ADVERTISE_1000XFULL;
325 [ # # ]: 0 : if (ethadv & ADVERTISED_Pause)
326 : 0 : result |= ADVERTISE_1000XPAUSE;
327 [ # # ]: 0 : if (ethadv & ADVERTISED_Asym_Pause)
328 : 0 : result |= ADVERTISE_1000XPSE_ASYM;
329 : :
330 [ # # ]: 0 : return result;
331 : : }
332 : :
333 : : /**
334 : : * mii_adv_to_ethtool_adv_x
335 : : * @adv: value of the MII_CTRL1000 register
336 : : *
337 : : * A small helper function that translates MII_CTRL1000
338 : : * bits, when in 1000Base-X mode, to ethtool
339 : : * advertisement settings.
340 : : */
341 : 0 : static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
342 : : {
343 : 0 : u32 result = 0;
344 : :
345 [ # # # # ]: 0 : if (adv & ADVERTISE_1000XHALF)
346 : 0 : result |= ADVERTISED_1000baseT_Half;
347 [ # # # # ]: 0 : if (adv & ADVERTISE_1000XFULL)
348 : 0 : result |= ADVERTISED_1000baseT_Full;
349 [ # # # # : 0 : if (adv & ADVERTISE_1000XPAUSE)
# # ]
350 : 0 : result |= ADVERTISED_Pause;
351 [ # # # # : 0 : if (adv & ADVERTISE_1000XPSE_ASYM)
# # ]
352 : 0 : result |= ADVERTISED_Asym_Pause;
353 : :
354 : 0 : return result;
355 : : }
356 : :
357 : : /**
358 : : * mii_lpa_to_ethtool_lpa_x
359 : : * @adv: value of the MII_LPA register
360 : : *
361 : : * A small helper function that translates MII_LPA
362 : : * bits, when in 1000Base-X mode, to ethtool
363 : : * LP advertisement settings.
364 : : */
365 : : static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa)
366 : : {
367 : : u32 result = 0;
368 : :
369 : : if (lpa & LPA_LPACK)
370 : : result |= ADVERTISED_Autoneg;
371 : :
372 : : return result | mii_adv_to_ethtool_adv_x(lpa);
373 : : }
374 : :
375 : : /**
376 : : * mii_lpa_mod_linkmode_adv_sgmii
377 : : * @lp_advertising: pointer to destination link mode.
378 : : * @lpa: value of the MII_LPA register
379 : : *
380 : : * A small helper function that translates MII_LPA bits to
381 : : * linkmode advertisement settings for SGMII.
382 : : * Leaves other bits unchanged.
383 : : */
384 : : static inline void
385 : : mii_lpa_mod_linkmode_lpa_sgmii(unsigned long *lp_advertising, u32 lpa)
386 : : {
387 : : u32 speed_duplex = lpa & LPA_SGMII_DPX_SPD_MASK;
388 : :
389 : : linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, lp_advertising,
390 : : speed_duplex == LPA_SGMII_1000HALF);
391 : :
392 : : linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, lp_advertising,
393 : : speed_duplex == LPA_SGMII_1000FULL);
394 : :
395 : : linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, lp_advertising,
396 : : speed_duplex == LPA_SGMII_100HALF);
397 : :
398 : : linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, lp_advertising,
399 : : speed_duplex == LPA_SGMII_100FULL);
400 : :
401 : : linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, lp_advertising,
402 : : speed_duplex == LPA_SGMII_10HALF);
403 : :
404 : : linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, lp_advertising,
405 : : speed_duplex == LPA_SGMII_10FULL);
406 : : }
407 : :
408 : : /**
409 : : * mii_lpa_to_linkmode_adv_sgmii
410 : : * @advertising: pointer to destination link mode.
411 : : * @lpa: value of the MII_LPA register
412 : : *
413 : : * A small helper function that translates MII_ADVERTISE bits
414 : : * to linkmode advertisement settings when in SGMII mode.
415 : : * Clears the old value of advertising.
416 : : */
417 : : static inline void mii_lpa_to_linkmode_lpa_sgmii(unsigned long *lp_advertising,
418 : : u32 lpa)
419 : : {
420 : : linkmode_zero(lp_advertising);
421 : :
422 : : mii_lpa_mod_linkmode_lpa_sgmii(lp_advertising, lpa);
423 : : }
424 : :
425 : : /**
426 : : * mii_adv_mod_linkmode_adv_t
427 : : * @advertising:pointer to destination link mode.
428 : : * @adv: value of the MII_ADVERTISE register
429 : : *
430 : : * A small helper function that translates MII_ADVERTISE bits to
431 : : * linkmode advertisement settings. Leaves other bits unchanged.
432 : : */
433 : 0 : static inline void mii_adv_mod_linkmode_adv_t(unsigned long *advertising,
434 : : u32 adv)
435 : : {
436 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
437 : 0 : advertising, adv & ADVERTISE_10HALF);
438 : :
439 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
440 : : advertising, adv & ADVERTISE_10FULL);
441 : :
442 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
443 : : advertising, adv & ADVERTISE_100HALF);
444 : :
445 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
446 : : advertising, adv & ADVERTISE_100FULL);
447 : :
448 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising,
449 : : adv & ADVERTISE_PAUSE_CAP);
450 : :
451 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
452 : : advertising, adv & ADVERTISE_PAUSE_ASYM);
453 : 0 : }
454 : :
455 : : /**
456 : : * mii_adv_to_linkmode_adv_t
457 : : * @advertising:pointer to destination link mode.
458 : : * @adv: value of the MII_ADVERTISE register
459 : : *
460 : : * A small helper function that translates MII_ADVERTISE bits
461 : : * to linkmode advertisement settings. Clears the old value
462 : : * of advertising.
463 : : */
464 : : static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
465 : : u32 adv)
466 : : {
467 : : linkmode_zero(advertising);
468 : :
469 : : mii_adv_mod_linkmode_adv_t(advertising, adv);
470 : : }
471 : :
472 : : /**
473 : : * mii_lpa_to_linkmode_lpa_t
474 : : * @adv: value of the MII_LPA register
475 : : *
476 : : * A small helper function that translates MII_LPA bits, when in
477 : : * 1000Base-T mode, to linkmode LP advertisement settings. Clears the
478 : : * old value of advertising
479 : : */
480 : : static inline void mii_lpa_to_linkmode_lpa_t(unsigned long *lp_advertising,
481 : : u32 lpa)
482 : : {
483 : : mii_adv_to_linkmode_adv_t(lp_advertising, lpa);
484 : :
485 : : if (lpa & LPA_LPACK)
486 : : linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
487 : : lp_advertising);
488 : :
489 : : }
490 : :
491 : : /**
492 : : * mii_lpa_mod_linkmode_lpa_t
493 : : * @adv: value of the MII_LPA register
494 : : *
495 : : * A small helper function that translates MII_LPA bits, when in
496 : : * 1000Base-T mode, to linkmode LP advertisement settings. Leaves
497 : : * other bits unchanged.
498 : : */
499 : 0 : static inline void mii_lpa_mod_linkmode_lpa_t(unsigned long *lp_advertising,
500 : : u32 lpa)
501 : : {
502 : 0 : mii_adv_mod_linkmode_adv_t(lp_advertising, lpa);
503 : :
504 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
505 : 0 : lp_advertising, lpa & LPA_LPACK);
506 : 0 : }
507 : :
508 : 0 : static inline void mii_ctrl1000_mod_linkmode_adv_t(unsigned long *advertising,
509 : : u32 ctrl1000)
510 : : {
511 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertising,
512 : 0 : ctrl1000 & ADVERTISE_1000HALF);
513 : 0 : linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising,
514 : : ctrl1000 & ADVERTISE_1000FULL);
515 : 0 : }
516 : :
517 : : /**
518 : : * linkmode_adv_to_lcl_adv_t
519 : : * @advertising:pointer to linkmode advertising
520 : : *
521 : : * A small helper function that translates linkmode advertising to LVL
522 : : * pause capabilities.
523 : : */
524 : : static inline u32 linkmode_adv_to_lcl_adv_t(unsigned long *advertising)
525 : : {
526 : : u32 lcl_adv = 0;
527 : :
528 : : if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
529 : : advertising))
530 : : lcl_adv |= ADVERTISE_PAUSE_CAP;
531 : : if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
532 : : advertising))
533 : : lcl_adv |= ADVERTISE_PAUSE_ASYM;
534 : :
535 : : return lcl_adv;
536 : : }
537 : :
538 : : /**
539 : : * mii_advertise_flowctrl - get flow control advertisement flags
540 : : * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
541 : : */
542 : 0 : static inline u16 mii_advertise_flowctrl(int cap)
543 : : {
544 : 0 : u16 adv = 0;
545 : :
546 [ # # # # : 0 : if (cap & FLOW_CTRL_RX)
# # ]
547 : 0 : adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
548 [ # # # # : 0 : if (cap & FLOW_CTRL_TX)
# # ]
549 : 0 : adv ^= ADVERTISE_PAUSE_ASYM;
550 : :
551 [ # # ]: 0 : return adv;
552 : : }
553 : :
554 : : /**
555 : : * mii_resolve_flowctrl_fdx
556 : : * @lcladv: value of MII ADVERTISE register
557 : : * @rmtadv: value of MII LPA register
558 : : *
559 : : * Resolve full duplex flow control as per IEEE 802.3-2005 table 28B-3
560 : : */
561 : 0 : static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
562 : : {
563 : 0 : u8 cap = 0;
564 : :
565 [ # # ]: 0 : if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
566 : : cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
567 [ # # ]: 0 : } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
568 [ # # ]: 0 : if (lcladv & ADVERTISE_PAUSE_CAP)
569 : : cap = FLOW_CTRL_RX;
570 [ # # ]: 0 : else if (rmtadv & ADVERTISE_PAUSE_CAP)
571 : 0 : cap = FLOW_CTRL_TX;
572 : : }
573 : :
574 : : return cap;
575 : : }
576 : :
577 : : #endif /* __LINUX_MII_H__ */
|