2 * linux/mii.h: definitions for MII-compatible transceivers
3 * Originally drivers/net/sunhme.h.
5 * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
7 #ifndef __LINUX_MII_H__
8 #define __LINUX_MII_H__
12 #include <uapi/linux/mii.h>
22 unsigned int full_duplex
: 1; /* is full duplex? */
23 unsigned int force_media
: 1; /* is autoneg. disabled? */
24 unsigned int supports_gmii
: 1; /* are GMII registers supported? */
26 struct net_device
*dev
;
27 int (*mdio_read
) (struct net_device
*dev
, int phy_id
, int location
);
28 void (*mdio_write
) (struct net_device
*dev
, int phy_id
, int location
, int val
);
31 extern int mii_link_ok (struct mii_if_info
*mii
);
32 extern int mii_nway_restart (struct mii_if_info
*mii
);
33 extern int mii_ethtool_gset(struct mii_if_info
*mii
, struct ethtool_cmd
*ecmd
);
34 extern int mii_ethtool_sset(struct mii_if_info
*mii
, struct ethtool_cmd
*ecmd
);
35 extern int mii_check_gmii_support(struct mii_if_info
*mii
);
36 extern void mii_check_link (struct mii_if_info
*mii
);
37 extern unsigned int mii_check_media (struct mii_if_info
*mii
,
38 unsigned int ok_to_print
,
39 unsigned int init_media
);
40 extern int generic_mii_ioctl(struct mii_if_info
*mii_if
,
41 struct mii_ioctl_data
*mii_data
, int cmd
,
42 unsigned int *duplex_changed
);
45 static inline struct mii_ioctl_data
*if_mii(struct ifreq
*rq
)
47 return (struct mii_ioctl_data
*) &rq
->ifr_ifru
;
52 * @negotiated: value of MII ANAR and'd with ANLPAR
54 * Given a set of MII abilities, check each bit and returns the
55 * currently supported media, in the priority order defined by
56 * IEEE 802.3u. We use LPA_xxx constants but note this is not the
57 * value of LPA solely, as described above.
59 * The one exception to IEEE 802.3u is that 100baseT4 is placed
60 * between 100T-full and 100T-half. If your phy does not support
61 * 100T4 this is fine. If your phy places 100T4 elsewhere in the
62 * priority order, you will need to roll your own function.
64 static inline unsigned int mii_nway_result (unsigned int negotiated
)
68 if (negotiated
& LPA_100FULL
)
70 else if (negotiated
& LPA_100BASE4
)
72 else if (negotiated
& LPA_100HALF
)
74 else if (negotiated
& LPA_10FULL
)
84 * @duplex_lock: Non-zero if duplex is locked at full
85 * @negotiated: value of MII ANAR and'd with ANLPAR
87 * A small helper function for a common case. Returns one
88 * if the media is operating or locked at full duplex, and
89 * returns zero otherwise.
91 static inline unsigned int mii_duplex (unsigned int duplex_lock
,
92 unsigned int negotiated
)
96 if (mii_nway_result(negotiated
) & LPA_DUPLEX
)
102 * ethtool_adv_to_mii_adv_t
103 * @ethadv: the ethtool advertisement settings
105 * A small helper function that translates ethtool advertisement
106 * settings to phy autonegotiation advertisements for the
107 * MII_ADVERTISE register.
109 static inline u32
ethtool_adv_to_mii_adv_t(u32 ethadv
)
113 if (ethadv
& ADVERTISED_10baseT_Half
)
114 result
|= ADVERTISE_10HALF
;
115 if (ethadv
& ADVERTISED_10baseT_Full
)
116 result
|= ADVERTISE_10FULL
;
117 if (ethadv
& ADVERTISED_100baseT_Half
)
118 result
|= ADVERTISE_100HALF
;
119 if (ethadv
& ADVERTISED_100baseT_Full
)
120 result
|= ADVERTISE_100FULL
;
121 if (ethadv
& ADVERTISED_Pause
)
122 result
|= ADVERTISE_PAUSE_CAP
;
123 if (ethadv
& ADVERTISED_Asym_Pause
)
124 result
|= ADVERTISE_PAUSE_ASYM
;
130 * mii_adv_to_ethtool_adv_t
131 * @adv: value of the MII_ADVERTISE register
133 * A small helper function that translates MII_ADVERTISE bits
134 * to ethtool advertisement settings.
136 static inline u32
mii_adv_to_ethtool_adv_t(u32 adv
)
140 if (adv
& ADVERTISE_10HALF
)
141 result
|= ADVERTISED_10baseT_Half
;
142 if (adv
& ADVERTISE_10FULL
)
143 result
|= ADVERTISED_10baseT_Full
;
144 if (adv
& ADVERTISE_100HALF
)
145 result
|= ADVERTISED_100baseT_Half
;
146 if (adv
& ADVERTISE_100FULL
)
147 result
|= ADVERTISED_100baseT_Full
;
148 if (adv
& ADVERTISE_PAUSE_CAP
)
149 result
|= ADVERTISED_Pause
;
150 if (adv
& ADVERTISE_PAUSE_ASYM
)
151 result
|= ADVERTISED_Asym_Pause
;
157 * ethtool_adv_to_mii_ctrl1000_t
158 * @ethadv: the ethtool advertisement settings
160 * A small helper function that translates ethtool advertisement
161 * settings to phy autonegotiation advertisements for the
162 * MII_CTRL1000 register when in 1000T mode.
164 static inline u32
ethtool_adv_to_mii_ctrl1000_t(u32 ethadv
)
168 if (ethadv
& ADVERTISED_1000baseT_Half
)
169 result
|= ADVERTISE_1000HALF
;
170 if (ethadv
& ADVERTISED_1000baseT_Full
)
171 result
|= ADVERTISE_1000FULL
;
177 * mii_ctrl1000_to_ethtool_adv_t
178 * @adv: value of the MII_CTRL1000 register
180 * A small helper function that translates MII_CTRL1000
181 * bits, when in 1000Base-T mode, to ethtool
182 * advertisement settings.
184 static inline u32
mii_ctrl1000_to_ethtool_adv_t(u32 adv
)
188 if (adv
& ADVERTISE_1000HALF
)
189 result
|= ADVERTISED_1000baseT_Half
;
190 if (adv
& ADVERTISE_1000FULL
)
191 result
|= ADVERTISED_1000baseT_Full
;
197 * mii_lpa_to_ethtool_lpa_t
198 * @adv: value of the MII_LPA register
200 * A small helper function that translates MII_LPA
201 * bits, when in 1000Base-T mode, to ethtool
202 * LP advertisement settings.
204 static inline u32
mii_lpa_to_ethtool_lpa_t(u32 lpa
)
209 result
|= ADVERTISED_Autoneg
;
211 return result
| mii_adv_to_ethtool_adv_t(lpa
);
215 * mii_stat1000_to_ethtool_lpa_t
216 * @adv: value of the MII_STAT1000 register
218 * A small helper function that translates MII_STAT1000
219 * bits, when in 1000Base-T mode, to ethtool
220 * advertisement settings.
222 static inline u32
mii_stat1000_to_ethtool_lpa_t(u32 lpa
)
226 if (lpa
& LPA_1000HALF
)
227 result
|= ADVERTISED_1000baseT_Half
;
228 if (lpa
& LPA_1000FULL
)
229 result
|= ADVERTISED_1000baseT_Full
;
235 * ethtool_adv_to_mii_adv_x
236 * @ethadv: the ethtool advertisement settings
238 * A small helper function that translates ethtool advertisement
239 * settings to phy autonegotiation advertisements for the
240 * MII_CTRL1000 register when in 1000Base-X mode.
242 static inline u32
ethtool_adv_to_mii_adv_x(u32 ethadv
)
246 if (ethadv
& ADVERTISED_1000baseT_Half
)
247 result
|= ADVERTISE_1000XHALF
;
248 if (ethadv
& ADVERTISED_1000baseT_Full
)
249 result
|= ADVERTISE_1000XFULL
;
250 if (ethadv
& ADVERTISED_Pause
)
251 result
|= ADVERTISE_1000XPAUSE
;
252 if (ethadv
& ADVERTISED_Asym_Pause
)
253 result
|= ADVERTISE_1000XPSE_ASYM
;
259 * mii_adv_to_ethtool_adv_x
260 * @adv: value of the MII_CTRL1000 register
262 * A small helper function that translates MII_CTRL1000
263 * bits, when in 1000Base-X mode, to ethtool
264 * advertisement settings.
266 static inline u32
mii_adv_to_ethtool_adv_x(u32 adv
)
270 if (adv
& ADVERTISE_1000XHALF
)
271 result
|= ADVERTISED_1000baseT_Half
;
272 if (adv
& ADVERTISE_1000XFULL
)
273 result
|= ADVERTISED_1000baseT_Full
;
274 if (adv
& ADVERTISE_1000XPAUSE
)
275 result
|= ADVERTISED_Pause
;
276 if (adv
& ADVERTISE_1000XPSE_ASYM
)
277 result
|= ADVERTISED_Asym_Pause
;
283 * mii_lpa_to_ethtool_lpa_x
284 * @adv: value of the MII_LPA register
286 * A small helper function that translates MII_LPA
287 * bits, when in 1000Base-X mode, to ethtool
288 * LP advertisement settings.
290 static inline u32
mii_lpa_to_ethtool_lpa_x(u32 lpa
)
295 result
|= ADVERTISED_Autoneg
;
297 return result
| mii_adv_to_ethtool_adv_x(lpa
);
301 * mii_advertise_flowctrl - get flow control advertisement flags
302 * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
304 static inline u16
mii_advertise_flowctrl(int cap
)
308 if (cap
& FLOW_CTRL_RX
)
309 adv
= ADVERTISE_PAUSE_CAP
| ADVERTISE_PAUSE_ASYM
;
310 if (cap
& FLOW_CTRL_TX
)
311 adv
^= ADVERTISE_PAUSE_ASYM
;
317 * mii_resolve_flowctrl_fdx
318 * @lcladv: value of MII ADVERTISE register
319 * @rmtadv: value of MII LPA register
321 * Resolve full duplex flow control as per IEEE 802.3-2005 table 28B-3
323 static inline u8
mii_resolve_flowctrl_fdx(u16 lcladv
, u16 rmtadv
)
327 if (lcladv
& rmtadv
& ADVERTISE_PAUSE_CAP
) {
328 cap
= FLOW_CTRL_TX
| FLOW_CTRL_RX
;
329 } else if (lcladv
& rmtadv
& ADVERTISE_PAUSE_ASYM
) {
330 if (lcladv
& ADVERTISE_PAUSE_CAP
)
332 else if (rmtadv
& ADVERTISE_PAUSE_CAP
)
339 #endif /* __LINUX_MII_H__ */