mii.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  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. #include <linux/if.h>
  11. #include <linux/linkmode.h>
  12. #include <uapi/linux/mii.h>
  13. struct ethtool_cmd;
  14. struct mii_if_info {
  15. int phy_id;
  16. int advertising;
  17. int phy_id_mask;
  18. int reg_num_mask;
  19. unsigned int full_duplex : 1; /* is full duplex? */
  20. unsigned int force_media : 1; /* is autoneg. disabled? */
  21. unsigned int supports_gmii : 1; /* are GMII registers supported? */
  22. struct net_device *dev;
  23. int (*mdio_read) (struct net_device *dev, int phy_id, int location);
  24. void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);
  25. };
  26. extern int mii_link_ok (struct mii_if_info *mii);
  27. extern int mii_nway_restart (struct mii_if_info *mii);
  28. extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
  29. extern void mii_ethtool_get_link_ksettings(
  30. struct mii_if_info *mii, struct ethtool_link_ksettings *cmd);
  31. extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
  32. extern int mii_ethtool_set_link_ksettings(
  33. struct mii_if_info *mii, const struct ethtool_link_ksettings *cmd);
  34. extern int mii_check_gmii_support(struct mii_if_info *mii);
  35. extern void mii_check_link (struct mii_if_info *mii);
  36. extern unsigned int mii_check_media (struct mii_if_info *mii,
  37. unsigned int ok_to_print,
  38. unsigned int init_media);
  39. extern int generic_mii_ioctl(struct mii_if_info *mii_if,
  40. struct mii_ioctl_data *mii_data, int cmd,
  41. unsigned int *duplex_changed);
  42. static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
  43. {
  44. return (struct mii_ioctl_data *) &rq->ifr_ifru;
  45. }
  46. /**
  47. * mii_nway_result
  48. * @negotiated: value of MII ANAR and'd with ANLPAR
  49. *
  50. * Given a set of MII abilities, check each bit and returns the
  51. * currently supported media, in the priority order defined by
  52. * IEEE 802.3u. We use LPA_xxx constants but note this is not the
  53. * value of LPA solely, as described above.
  54. *
  55. * The one exception to IEEE 802.3u is that 100baseT4 is placed
  56. * between 100T-full and 100T-half. If your phy does not support
  57. * 100T4 this is fine. If your phy places 100T4 elsewhere in the
  58. * priority order, you will need to roll your own function.
  59. */
  60. static inline unsigned int mii_nway_result (unsigned int negotiated)
  61. {
  62. unsigned int ret;
  63. if (negotiated & LPA_100FULL)
  64. ret = LPA_100FULL;
  65. else if (negotiated & LPA_100BASE4)
  66. ret = LPA_100BASE4;
  67. else if (negotiated & LPA_100HALF)
  68. ret = LPA_100HALF;
  69. else if (negotiated & LPA_10FULL)
  70. ret = LPA_10FULL;
  71. else
  72. ret = LPA_10HALF;
  73. return ret;
  74. }
  75. /**
  76. * mii_duplex
  77. * @duplex_lock: Non-zero if duplex is locked at full
  78. * @negotiated: value of MII ANAR and'd with ANLPAR
  79. *
  80. * A small helper function for a common case. Returns one
  81. * if the media is operating or locked at full duplex, and
  82. * returns zero otherwise.
  83. */
  84. static inline unsigned int mii_duplex (unsigned int duplex_lock,
  85. unsigned int negotiated)
  86. {
  87. if (duplex_lock)
  88. return 1;
  89. if (mii_nway_result(negotiated) & LPA_DUPLEX)
  90. return 1;
  91. return 0;
  92. }
  93. /**
  94. * ethtool_adv_to_mii_adv_t
  95. * @ethadv: the ethtool advertisement settings
  96. *
  97. * A small helper function that translates ethtool advertisement
  98. * settings to phy autonegotiation advertisements for the
  99. * MII_ADVERTISE register.
  100. */
  101. static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
  102. {
  103. u32 result = 0;
  104. if (ethadv & ADVERTISED_10baseT_Half)
  105. result |= ADVERTISE_10HALF;
  106. if (ethadv & ADVERTISED_10baseT_Full)
  107. result |= ADVERTISE_10FULL;
  108. if (ethadv & ADVERTISED_100baseT_Half)
  109. result |= ADVERTISE_100HALF;
  110. if (ethadv & ADVERTISED_100baseT_Full)
  111. result |= ADVERTISE_100FULL;
  112. if (ethadv & ADVERTISED_Pause)
  113. result |= ADVERTISE_PAUSE_CAP;
  114. if (ethadv & ADVERTISED_Asym_Pause)
  115. result |= ADVERTISE_PAUSE_ASYM;
  116. return result;
  117. }
  118. /**
  119. * linkmode_adv_to_mii_adv_t
  120. * @advertising: the linkmode advertisement settings
  121. *
  122. * A small helper function that translates linkmode advertisement
  123. * settings to phy autonegotiation advertisements for the
  124. * MII_ADVERTISE register.
  125. */
  126. static inline u32 linkmode_adv_to_mii_adv_t(unsigned long *advertising)
  127. {
  128. u32 result = 0;
  129. if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, advertising))
  130. result |= ADVERTISE_10HALF;
  131. if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, advertising))
  132. result |= ADVERTISE_10FULL;
  133. if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, advertising))
  134. result |= ADVERTISE_100HALF;
  135. if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, advertising))
  136. result |= ADVERTISE_100FULL;
  137. if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising))
  138. result |= ADVERTISE_PAUSE_CAP;
  139. if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising))
  140. result |= ADVERTISE_PAUSE_ASYM;
  141. return result;
  142. }
  143. /**
  144. * mii_adv_to_ethtool_adv_t
  145. * @adv: value of the MII_ADVERTISE register
  146. *
  147. * A small helper function that translates MII_ADVERTISE bits
  148. * to ethtool advertisement settings.
  149. */
  150. static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
  151. {
  152. u32 result = 0;
  153. if (adv & ADVERTISE_10HALF)
  154. result |= ADVERTISED_10baseT_Half;
  155. if (adv & ADVERTISE_10FULL)
  156. result |= ADVERTISED_10baseT_Full;
  157. if (adv & ADVERTISE_100HALF)
  158. result |= ADVERTISED_100baseT_Half;
  159. if (adv & ADVERTISE_100FULL)
  160. result |= ADVERTISED_100baseT_Full;
  161. if (adv & ADVERTISE_PAUSE_CAP)
  162. result |= ADVERTISED_Pause;
  163. if (adv & ADVERTISE_PAUSE_ASYM)
  164. result |= ADVERTISED_Asym_Pause;
  165. return result;
  166. }
  167. /**
  168. * ethtool_adv_to_mii_ctrl1000_t
  169. * @ethadv: the ethtool advertisement settings
  170. *
  171. * A small helper function that translates ethtool advertisement
  172. * settings to phy autonegotiation advertisements for the
  173. * MII_CTRL1000 register when in 1000T mode.
  174. */
  175. static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
  176. {
  177. u32 result = 0;
  178. if (ethadv & ADVERTISED_1000baseT_Half)
  179. result |= ADVERTISE_1000HALF;
  180. if (ethadv & ADVERTISED_1000baseT_Full)
  181. result |= ADVERTISE_1000FULL;
  182. return result;
  183. }
  184. /**
  185. * linkmode_adv_to_mii_ctrl1000_t
  186. * @advertising: the linkmode advertisement settings
  187. *
  188. * A small helper function that translates linkmode advertisement
  189. * settings to phy autonegotiation advertisements for the
  190. * MII_CTRL1000 register when in 1000T mode.
  191. */
  192. static inline u32 linkmode_adv_to_mii_ctrl1000_t(unsigned long *advertising)
  193. {
  194. u32 result = 0;
  195. if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
  196. advertising))
  197. result |= ADVERTISE_1000HALF;
  198. if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
  199. advertising))
  200. result |= ADVERTISE_1000FULL;
  201. return result;
  202. }
  203. /**
  204. * mii_ctrl1000_to_ethtool_adv_t
  205. * @adv: value of the MII_CTRL1000 register
  206. *
  207. * A small helper function that translates MII_CTRL1000
  208. * bits, when in 1000Base-T mode, to ethtool
  209. * advertisement settings.
  210. */
  211. static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
  212. {
  213. u32 result = 0;
  214. if (adv & ADVERTISE_1000HALF)
  215. result |= ADVERTISED_1000baseT_Half;
  216. if (adv & ADVERTISE_1000FULL)
  217. result |= ADVERTISED_1000baseT_Full;
  218. return result;
  219. }
  220. /**
  221. * mii_lpa_to_ethtool_lpa_t
  222. * @adv: value of the MII_LPA register
  223. *
  224. * A small helper function that translates MII_LPA
  225. * bits, when in 1000Base-T mode, to ethtool
  226. * LP advertisement settings.
  227. */
  228. static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
  229. {
  230. u32 result = 0;
  231. if (lpa & LPA_LPACK)
  232. result |= ADVERTISED_Autoneg;
  233. return result | mii_adv_to_ethtool_adv_t(lpa);
  234. }
  235. /**
  236. * mii_stat1000_to_ethtool_lpa_t
  237. * @adv: value of the MII_STAT1000 register
  238. *
  239. * A small helper function that translates MII_STAT1000
  240. * bits, when in 1000Base-T mode, to ethtool
  241. * advertisement settings.
  242. */
  243. static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
  244. {
  245. u32 result = 0;
  246. if (lpa & LPA_1000HALF)
  247. result |= ADVERTISED_1000baseT_Half;
  248. if (lpa & LPA_1000FULL)
  249. result |= ADVERTISED_1000baseT_Full;
  250. return result;
  251. }
  252. /**
  253. * mii_stat1000_mod_linkmode_lpa_t
  254. * @advertising: target the linkmode advertisement settings
  255. * @adv: value of the MII_STAT1000 register
  256. *
  257. * A small helper function that translates MII_STAT1000 bits, when in
  258. * 1000Base-T mode, to linkmode advertisement settings. Other bits in
  259. * advertising are not changes.
  260. */
  261. static inline void mii_stat1000_mod_linkmode_lpa_t(unsigned long *advertising,
  262. u32 lpa)
  263. {
  264. linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
  265. advertising, lpa & LPA_1000HALF);
  266. linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
  267. advertising, lpa & LPA_1000FULL);
  268. }
  269. /**
  270. * ethtool_adv_to_mii_adv_x
  271. * @ethadv: the ethtool advertisement settings
  272. *
  273. * A small helper function that translates ethtool advertisement
  274. * settings to phy autonegotiation advertisements for the
  275. * MII_CTRL1000 register when in 1000Base-X mode.
  276. */
  277. static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
  278. {
  279. u32 result = 0;
  280. if (ethadv & ADVERTISED_1000baseT_Half)
  281. result |= ADVERTISE_1000XHALF;
  282. if (ethadv & ADVERTISED_1000baseT_Full)
  283. result |= ADVERTISE_1000XFULL;
  284. if (ethadv & ADVERTISED_Pause)
  285. result |= ADVERTISE_1000XPAUSE;
  286. if (ethadv & ADVERTISED_Asym_Pause)
  287. result |= ADVERTISE_1000XPSE_ASYM;
  288. return result;
  289. }
  290. /**
  291. * mii_adv_to_ethtool_adv_x
  292. * @adv: value of the MII_CTRL1000 register
  293. *
  294. * A small helper function that translates MII_CTRL1000
  295. * bits, when in 1000Base-X mode, to ethtool
  296. * advertisement settings.
  297. */
  298. static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
  299. {
  300. u32 result = 0;
  301. if (adv & ADVERTISE_1000XHALF)
  302. result |= ADVERTISED_1000baseT_Half;
  303. if (adv & ADVERTISE_1000XFULL)
  304. result |= ADVERTISED_1000baseT_Full;
  305. if (adv & ADVERTISE_1000XPAUSE)
  306. result |= ADVERTISED_Pause;
  307. if (adv & ADVERTISE_1000XPSE_ASYM)
  308. result |= ADVERTISED_Asym_Pause;
  309. return result;
  310. }
  311. /**
  312. * mii_lpa_mod_linkmode_adv_sgmii
  313. * @lp_advertising: pointer to destination link mode.
  314. * @lpa: value of the MII_LPA register
  315. *
  316. * A small helper function that translates MII_LPA bits to
  317. * linkmode advertisement settings for SGMII.
  318. * Leaves other bits unchanged.
  319. */
  320. static inline void
  321. mii_lpa_mod_linkmode_lpa_sgmii(unsigned long *lp_advertising, u32 lpa)
  322. {
  323. u32 speed_duplex = lpa & LPA_SGMII_DPX_SPD_MASK;
  324. linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, lp_advertising,
  325. speed_duplex == LPA_SGMII_1000HALF);
  326. linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, lp_advertising,
  327. speed_duplex == LPA_SGMII_1000FULL);
  328. linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, lp_advertising,
  329. speed_duplex == LPA_SGMII_100HALF);
  330. linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, lp_advertising,
  331. speed_duplex == LPA_SGMII_100FULL);
  332. linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, lp_advertising,
  333. speed_duplex == LPA_SGMII_10HALF);
  334. linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, lp_advertising,
  335. speed_duplex == LPA_SGMII_10FULL);
  336. }
  337. /**
  338. * mii_lpa_to_linkmode_adv_sgmii
  339. * @advertising: pointer to destination link mode.
  340. * @lpa: value of the MII_LPA register
  341. *
  342. * A small helper function that translates MII_ADVERTISE bits
  343. * to linkmode advertisement settings when in SGMII mode.
  344. * Clears the old value of advertising.
  345. */
  346. static inline void mii_lpa_to_linkmode_lpa_sgmii(unsigned long *lp_advertising,
  347. u32 lpa)
  348. {
  349. linkmode_zero(lp_advertising);
  350. mii_lpa_mod_linkmode_lpa_sgmii(lp_advertising, lpa);
  351. }
  352. /**
  353. * mii_adv_mod_linkmode_adv_t
  354. * @advertising:pointer to destination link mode.
  355. * @adv: value of the MII_ADVERTISE register
  356. *
  357. * A small helper function that translates MII_ADVERTISE bits to
  358. * linkmode advertisement settings. Leaves other bits unchanged.
  359. */
  360. static inline void mii_adv_mod_linkmode_adv_t(unsigned long *advertising,
  361. u32 adv)
  362. {
  363. linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
  364. advertising, adv & ADVERTISE_10HALF);
  365. linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
  366. advertising, adv & ADVERTISE_10FULL);
  367. linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
  368. advertising, adv & ADVERTISE_100HALF);
  369. linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
  370. advertising, adv & ADVERTISE_100FULL);
  371. linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising,
  372. adv & ADVERTISE_PAUSE_CAP);
  373. linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  374. advertising, adv & ADVERTISE_PAUSE_ASYM);
  375. }
  376. /**
  377. * mii_adv_to_linkmode_adv_t
  378. * @advertising:pointer to destination link mode.
  379. * @adv: value of the MII_ADVERTISE register
  380. *
  381. * A small helper function that translates MII_ADVERTISE bits
  382. * to linkmode advertisement settings. Clears the old value
  383. * of advertising.
  384. */
  385. static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
  386. u32 adv)
  387. {
  388. linkmode_zero(advertising);
  389. mii_adv_mod_linkmode_adv_t(advertising, adv);
  390. }
  391. /**
  392. * mii_lpa_to_linkmode_lpa_t
  393. * @adv: value of the MII_LPA register
  394. *
  395. * A small helper function that translates MII_LPA bits, when in
  396. * 1000Base-T mode, to linkmode LP advertisement settings. Clears the
  397. * old value of advertising
  398. */
  399. static inline void mii_lpa_to_linkmode_lpa_t(unsigned long *lp_advertising,
  400. u32 lpa)
  401. {
  402. mii_adv_to_linkmode_adv_t(lp_advertising, lpa);
  403. if (lpa & LPA_LPACK)
  404. linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
  405. lp_advertising);
  406. }
  407. /**
  408. * mii_lpa_mod_linkmode_lpa_t
  409. * @adv: value of the MII_LPA register
  410. *
  411. * A small helper function that translates MII_LPA bits, when in
  412. * 1000Base-T mode, to linkmode LP advertisement settings. Leaves
  413. * other bits unchanged.
  414. */
  415. static inline void mii_lpa_mod_linkmode_lpa_t(unsigned long *lp_advertising,
  416. u32 lpa)
  417. {
  418. mii_adv_mod_linkmode_adv_t(lp_advertising, lpa);
  419. linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
  420. lp_advertising, lpa & LPA_LPACK);
  421. }
  422. static inline void mii_ctrl1000_mod_linkmode_adv_t(unsigned long *advertising,
  423. u32 ctrl1000)
  424. {
  425. linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertising,
  426. ctrl1000 & ADVERTISE_1000HALF);
  427. linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising,
  428. ctrl1000 & ADVERTISE_1000FULL);
  429. }
  430. /**
  431. * linkmode_adv_to_lcl_adv_t
  432. * @advertising:pointer to linkmode advertising
  433. *
  434. * A small helper function that translates linkmode advertising to LVL
  435. * pause capabilities.
  436. */
  437. static inline u32 linkmode_adv_to_lcl_adv_t(unsigned long *advertising)
  438. {
  439. u32 lcl_adv = 0;
  440. if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
  441. advertising))
  442. lcl_adv |= ADVERTISE_PAUSE_CAP;
  443. if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  444. advertising))
  445. lcl_adv |= ADVERTISE_PAUSE_ASYM;
  446. return lcl_adv;
  447. }
  448. /**
  449. * mii_lpa_mod_linkmode_x - decode the link partner's config_reg to linkmodes
  450. * @linkmodes: link modes array
  451. * @lpa: config_reg word from link partner
  452. * @fd_bit: link mode for 1000XFULL bit
  453. */
  454. static inline void mii_lpa_mod_linkmode_x(unsigned long *linkmodes, u16 lpa,
  455. int fd_bit)
  456. {
  457. linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, linkmodes,
  458. lpa & LPA_LPACK);
  459. linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes,
  460. lpa & LPA_1000XPAUSE);
  461. linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes,
  462. lpa & LPA_1000XPAUSE_ASYM);
  463. linkmode_mod_bit(fd_bit, linkmodes,
  464. lpa & LPA_1000XFULL);
  465. }
  466. /**
  467. * linkmode_adv_to_mii_adv_x - encode a linkmode to config_reg
  468. * @linkmodes: linkmodes
  469. * @fd_bit: full duplex bit
  470. */
  471. static inline u16 linkmode_adv_to_mii_adv_x(const unsigned long *linkmodes,
  472. int fd_bit)
  473. {
  474. u16 adv = 0;
  475. if (linkmode_test_bit(fd_bit, linkmodes))
  476. adv |= ADVERTISE_1000XFULL;
  477. if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes))
  478. adv |= ADVERTISE_1000XPAUSE;
  479. if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes))
  480. adv |= ADVERTISE_1000XPSE_ASYM;
  481. return adv;
  482. }
  483. /**
  484. * mii_advertise_flowctrl - get flow control advertisement flags
  485. * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
  486. */
  487. static inline u16 mii_advertise_flowctrl(int cap)
  488. {
  489. u16 adv = 0;
  490. if (cap & FLOW_CTRL_RX)
  491. adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
  492. if (cap & FLOW_CTRL_TX)
  493. adv ^= ADVERTISE_PAUSE_ASYM;
  494. return adv;
  495. }
  496. /**
  497. * mii_resolve_flowctrl_fdx
  498. * @lcladv: value of MII ADVERTISE register
  499. * @rmtadv: value of MII LPA register
  500. *
  501. * Resolve full duplex flow control as per IEEE 802.3-2005 table 28B-3
  502. */
  503. static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
  504. {
  505. u8 cap = 0;
  506. if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
  507. cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
  508. } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
  509. if (lcladv & ADVERTISE_PAUSE_CAP)
  510. cap = FLOW_CTRL_RX;
  511. else if (rmtadv & ADVERTISE_PAUSE_CAP)
  512. cap = FLOW_CTRL_TX;
  513. }
  514. return cap;
  515. }
  516. #endif /* __LINUX_MII_H__ */