mii.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * linux/mii.h: definitions for MII-compatible transceivers
  3. * Originally drivers/net/sunhme.h.
  4. *
  5. * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
  6. */
  7. #ifndef __LINUX_MII_H__
  8. #define __LINUX_MII_H__
  9. #include <linux/if.h>
  10. #include <uapi/linux/mii.h>
  11. struct ethtool_cmd;
  12. struct mii_if_info {
  13. int phy_id;
  14. int advertising;
  15. int phy_id_mask;
  16. int reg_num_mask;
  17. unsigned int full_duplex : 1; /* is full duplex? */
  18. unsigned int force_media : 1; /* is autoneg. disabled? */
  19. unsigned int supports_gmii : 1; /* are GMII registers supported? */
  20. struct net_device *dev;
  21. int (*mdio_read) (struct net_device *dev, int phy_id, int location);
  22. void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);
  23. };
  24. extern int mii_link_ok (struct mii_if_info *mii);
  25. extern int mii_nway_restart (struct mii_if_info *mii);
  26. extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
  27. extern int mii_ethtool_get_link_ksettings(
  28. struct mii_if_info *mii, struct ethtool_link_ksettings *cmd);
  29. extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
  30. extern int mii_ethtool_set_link_ksettings(
  31. struct mii_if_info *mii, const struct ethtool_link_ksettings *cmd);
  32. extern int mii_check_gmii_support(struct mii_if_info *mii);
  33. extern void mii_check_link (struct mii_if_info *mii);
  34. extern unsigned int mii_check_media (struct mii_if_info *mii,
  35. unsigned int ok_to_print,
  36. unsigned int init_media);
  37. extern int generic_mii_ioctl(struct mii_if_info *mii_if,
  38. struct mii_ioctl_data *mii_data, int cmd,
  39. unsigned int *duplex_changed);
  40. static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
  41. {
  42. return (struct mii_ioctl_data *) &rq->ifr_ifru;
  43. }
  44. /**
  45. * mii_nway_result
  46. * @negotiated: value of MII ANAR and'd with ANLPAR
  47. *
  48. * Given a set of MII abilities, check each bit and returns the
  49. * currently supported media, in the priority order defined by
  50. * IEEE 802.3u. We use LPA_xxx constants but note this is not the
  51. * value of LPA solely, as described above.
  52. *
  53. * The one exception to IEEE 802.3u is that 100baseT4 is placed
  54. * between 100T-full and 100T-half. If your phy does not support
  55. * 100T4 this is fine. If your phy places 100T4 elsewhere in the
  56. * priority order, you will need to roll your own function.
  57. */
  58. static inline unsigned int mii_nway_result (unsigned int negotiated)
  59. {
  60. unsigned int ret;
  61. if (negotiated & LPA_100FULL)
  62. ret = LPA_100FULL;
  63. else if (negotiated & LPA_100BASE4)
  64. ret = LPA_100BASE4;
  65. else if (negotiated & LPA_100HALF)
  66. ret = LPA_100HALF;
  67. else if (negotiated & LPA_10FULL)
  68. ret = LPA_10FULL;
  69. else
  70. ret = LPA_10HALF;
  71. return ret;
  72. }
  73. /**
  74. * mii_duplex
  75. * @duplex_lock: Non-zero if duplex is locked at full
  76. * @negotiated: value of MII ANAR and'd with ANLPAR
  77. *
  78. * A small helper function for a common case. Returns one
  79. * if the media is operating or locked at full duplex, and
  80. * returns zero otherwise.
  81. */
  82. static inline unsigned int mii_duplex (unsigned int duplex_lock,
  83. unsigned int negotiated)
  84. {
  85. if (duplex_lock)
  86. return 1;
  87. if (mii_nway_result(negotiated) & LPA_DUPLEX)
  88. return 1;
  89. return 0;
  90. }
  91. /**
  92. * ethtool_adv_to_mii_adv_t
  93. * @ethadv: the ethtool advertisement settings
  94. *
  95. * A small helper function that translates ethtool advertisement
  96. * settings to phy autonegotiation advertisements for the
  97. * MII_ADVERTISE register.
  98. */
  99. static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
  100. {
  101. u32 result = 0;
  102. if (ethadv & ADVERTISED_10baseT_Half)
  103. result |= ADVERTISE_10HALF;
  104. if (ethadv & ADVERTISED_10baseT_Full)
  105. result |= ADVERTISE_10FULL;
  106. if (ethadv & ADVERTISED_100baseT_Half)
  107. result |= ADVERTISE_100HALF;
  108. if (ethadv & ADVERTISED_100baseT_Full)
  109. result |= ADVERTISE_100FULL;
  110. if (ethadv & ADVERTISED_Pause)
  111. result |= ADVERTISE_PAUSE_CAP;
  112. if (ethadv & ADVERTISED_Asym_Pause)
  113. result |= ADVERTISE_PAUSE_ASYM;
  114. return result;
  115. }
  116. /**
  117. * mii_adv_to_ethtool_adv_t
  118. * @adv: value of the MII_ADVERTISE register
  119. *
  120. * A small helper function that translates MII_ADVERTISE bits
  121. * to ethtool advertisement settings.
  122. */
  123. static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
  124. {
  125. u32 result = 0;
  126. if (adv & ADVERTISE_10HALF)
  127. result |= ADVERTISED_10baseT_Half;
  128. if (adv & ADVERTISE_10FULL)
  129. result |= ADVERTISED_10baseT_Full;
  130. if (adv & ADVERTISE_100HALF)
  131. result |= ADVERTISED_100baseT_Half;
  132. if (adv & ADVERTISE_100FULL)
  133. result |= ADVERTISED_100baseT_Full;
  134. if (adv & ADVERTISE_PAUSE_CAP)
  135. result |= ADVERTISED_Pause;
  136. if (adv & ADVERTISE_PAUSE_ASYM)
  137. result |= ADVERTISED_Asym_Pause;
  138. return result;
  139. }
  140. /**
  141. * ethtool_adv_to_mii_ctrl1000_t
  142. * @ethadv: the ethtool advertisement settings
  143. *
  144. * A small helper function that translates ethtool advertisement
  145. * settings to phy autonegotiation advertisements for the
  146. * MII_CTRL1000 register when in 1000T mode.
  147. */
  148. static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
  149. {
  150. u32 result = 0;
  151. if (ethadv & ADVERTISED_1000baseT_Half)
  152. result |= ADVERTISE_1000HALF;
  153. if (ethadv & ADVERTISED_1000baseT_Full)
  154. result |= ADVERTISE_1000FULL;
  155. return result;
  156. }
  157. /**
  158. * mii_ctrl1000_to_ethtool_adv_t
  159. * @adv: value of the MII_CTRL1000 register
  160. *
  161. * A small helper function that translates MII_CTRL1000
  162. * bits, when in 1000Base-T mode, to ethtool
  163. * advertisement settings.
  164. */
  165. static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
  166. {
  167. u32 result = 0;
  168. if (adv & ADVERTISE_1000HALF)
  169. result |= ADVERTISED_1000baseT_Half;
  170. if (adv & ADVERTISE_1000FULL)
  171. result |= ADVERTISED_1000baseT_Full;
  172. return result;
  173. }
  174. /**
  175. * mii_lpa_to_ethtool_lpa_t
  176. * @adv: value of the MII_LPA register
  177. *
  178. * A small helper function that translates MII_LPA
  179. * bits, when in 1000Base-T mode, to ethtool
  180. * LP advertisement settings.
  181. */
  182. static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
  183. {
  184. u32 result = 0;
  185. if (lpa & LPA_LPACK)
  186. result |= ADVERTISED_Autoneg;
  187. return result | mii_adv_to_ethtool_adv_t(lpa);
  188. }
  189. /**
  190. * mii_stat1000_to_ethtool_lpa_t
  191. * @adv: value of the MII_STAT1000 register
  192. *
  193. * A small helper function that translates MII_STAT1000
  194. * bits, when in 1000Base-T mode, to ethtool
  195. * advertisement settings.
  196. */
  197. static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
  198. {
  199. u32 result = 0;
  200. if (lpa & LPA_1000HALF)
  201. result |= ADVERTISED_1000baseT_Half;
  202. if (lpa & LPA_1000FULL)
  203. result |= ADVERTISED_1000baseT_Full;
  204. return result;
  205. }
  206. /**
  207. * ethtool_adv_to_mii_adv_x
  208. * @ethadv: the ethtool advertisement settings
  209. *
  210. * A small helper function that translates ethtool advertisement
  211. * settings to phy autonegotiation advertisements for the
  212. * MII_CTRL1000 register when in 1000Base-X mode.
  213. */
  214. static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
  215. {
  216. u32 result = 0;
  217. if (ethadv & ADVERTISED_1000baseT_Half)
  218. result |= ADVERTISE_1000XHALF;
  219. if (ethadv & ADVERTISED_1000baseT_Full)
  220. result |= ADVERTISE_1000XFULL;
  221. if (ethadv & ADVERTISED_Pause)
  222. result |= ADVERTISE_1000XPAUSE;
  223. if (ethadv & ADVERTISED_Asym_Pause)
  224. result |= ADVERTISE_1000XPSE_ASYM;
  225. return result;
  226. }
  227. /**
  228. * mii_adv_to_ethtool_adv_x
  229. * @adv: value of the MII_CTRL1000 register
  230. *
  231. * A small helper function that translates MII_CTRL1000
  232. * bits, when in 1000Base-X mode, to ethtool
  233. * advertisement settings.
  234. */
  235. static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
  236. {
  237. u32 result = 0;
  238. if (adv & ADVERTISE_1000XHALF)
  239. result |= ADVERTISED_1000baseT_Half;
  240. if (adv & ADVERTISE_1000XFULL)
  241. result |= ADVERTISED_1000baseT_Full;
  242. if (adv & ADVERTISE_1000XPAUSE)
  243. result |= ADVERTISED_Pause;
  244. if (adv & ADVERTISE_1000XPSE_ASYM)
  245. result |= ADVERTISED_Asym_Pause;
  246. return result;
  247. }
  248. /**
  249. * mii_lpa_to_ethtool_lpa_x
  250. * @adv: value of the MII_LPA register
  251. *
  252. * A small helper function that translates MII_LPA
  253. * bits, when in 1000Base-X mode, to ethtool
  254. * LP advertisement settings.
  255. */
  256. static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa)
  257. {
  258. u32 result = 0;
  259. if (lpa & LPA_LPACK)
  260. result |= ADVERTISED_Autoneg;
  261. return result | mii_adv_to_ethtool_adv_x(lpa);
  262. }
  263. /**
  264. * mii_advertise_flowctrl - get flow control advertisement flags
  265. * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
  266. */
  267. static inline u16 mii_advertise_flowctrl(int cap)
  268. {
  269. u16 adv = 0;
  270. if (cap & FLOW_CTRL_RX)
  271. adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
  272. if (cap & FLOW_CTRL_TX)
  273. adv ^= ADVERTISE_PAUSE_ASYM;
  274. return adv;
  275. }
  276. /**
  277. * mii_resolve_flowctrl_fdx
  278. * @lcladv: value of MII ADVERTISE register
  279. * @rmtadv: value of MII LPA register
  280. *
  281. * Resolve full duplex flow control as per IEEE 802.3-2005 table 28B-3
  282. */
  283. static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
  284. {
  285. u8 cap = 0;
  286. if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
  287. cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
  288. } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
  289. if (lcladv & ADVERTISE_PAUSE_CAP)
  290. cap = FLOW_CTRL_RX;
  291. else if (rmtadv & ADVERTISE_PAUSE_CAP)
  292. cap = FLOW_CTRL_TX;
  293. }
  294. return cap;
  295. }
  296. #endif /* __LINUX_MII_H__ */