407-net-phy-add-802.3-clause-45-support-to-phylib.patch 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. From: Russell King <[email protected]>
  2. Date: Thu, 29 Dec 2016 11:03:09 +0000
  3. Subject: [PATCH] net: phy: add 802.3 clause 45 support to phylib
  4. Add generic helpers for 802.3 clause 45 PHYs for >= 10Gbps support.
  5. Signed-off-by: Russell King <[email protected]>
  6. ---
  7. create mode 100644 drivers/net/phy/phy-c45.c
  8. --- a/drivers/net/phy/Makefile
  9. +++ b/drivers/net/phy/Makefile
  10. @@ -1,7 +1,7 @@
  11. # Makefile for Linux PHY drivers and MDIO bus drivers
  12. libphy-y := phy.o phy_device.o mdio_bus.o mdio_device.o \
  13. - phy-core.o
  14. + phy-c45.o phy-core.o
  15. libphy-$(CONFIG_SWPHY) += swphy.o
  16. obj-$(CONFIG_MDIO_BOARDINFO) += mdio-boardinfo.o
  17. --- /dev/null
  18. +++ b/drivers/net/phy/phy-c45.c
  19. @@ -0,0 +1,234 @@
  20. +/*
  21. + * Clause 45 PHY support
  22. + */
  23. +#include <linux/ethtool.h>
  24. +#include <linux/export.h>
  25. +#include <linux/mdio.h>
  26. +#include <linux/mii.h>
  27. +#include <linux/phy.h>
  28. +
  29. +/**
  30. + * genphy_c45_setup_forced - configures a forced speed
  31. + * @phydev: target phy_device struct
  32. + */
  33. +int genphy_c45_pma_setup_forced(struct phy_device *phydev)
  34. +{
  35. + int ctrl1, ctrl2, ret;
  36. +
  37. + /* Half duplex is not supported */
  38. + if (phydev->duplex != DUPLEX_FULL)
  39. + return -EINVAL;
  40. +
  41. + ctrl1 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
  42. + if (ctrl1 < 0)
  43. + return ctrl1;
  44. +
  45. + ctrl2 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2);
  46. + if (ctrl2 < 0)
  47. + return ctrl2;
  48. +
  49. + ctrl1 &= ~MDIO_CTRL1_SPEEDSEL;
  50. + /* PMA/PMD type selection is 1.7.5:0 not 1.7.3:0. See 45.2.1.6.1. */
  51. + ctrl2 &= ~(MDIO_PMA_CTRL2_TYPE | 0x30);
  52. +
  53. + switch (phydev->speed) {
  54. + case SPEED_10:
  55. + ctrl2 |= MDIO_PMA_CTRL2_10BT;
  56. + break;
  57. + case SPEED_100:
  58. + ctrl1 |= MDIO_PMA_CTRL1_SPEED100;
  59. + ctrl2 |= MDIO_PMA_CTRL2_100BTX;
  60. + break;
  61. + case SPEED_1000:
  62. + ctrl1 |= MDIO_PMA_CTRL1_SPEED1000;
  63. + /* Assume 1000base-T */
  64. + ctrl2 |= MDIO_PMA_CTRL2_1000BT;
  65. + break;
  66. + case SPEED_10000:
  67. + ctrl1 |= MDIO_CTRL1_SPEED10G;
  68. + /* Assume 10Gbase-T */
  69. + ctrl2 |= MDIO_PMA_CTRL2_10GBT;
  70. + break;
  71. + default:
  72. + return -EINVAL;
  73. + }
  74. +
  75. + ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, ctrl1);
  76. + if (ret < 0)
  77. + return ret;
  78. +
  79. + return phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2, ctrl2);
  80. +}
  81. +EXPORT_SYMBOL_GPL(genphy_c45_pma_setup_forced);
  82. +
  83. +/**
  84. + * genphy_c45_an_disable_aneg - disable auto-negotiation
  85. + * @phydev: target phy_device struct
  86. + *
  87. + * Disable auto-negotiation in the Clause 45 PHY. The link parameters
  88. + * parameters are controlled through the PMA/PMD MMD registers.
  89. + *
  90. + * Returns zero on success, negative errno code on failure.
  91. + */
  92. +int genphy_c45_an_disable_aneg(struct phy_device *phydev)
  93. +{
  94. + int val;
  95. +
  96. + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
  97. + if (val < 0)
  98. + return val;
  99. +
  100. + val &= ~(MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
  101. +
  102. + return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, val);
  103. +}
  104. +EXPORT_SYMBOL_GPL(genphy_c45_an_disable_aneg);
  105. +
  106. +/**
  107. + * genphy_c45_restart_aneg - Enable and restart auto-negotiation
  108. + * @phydev: target phy_device struct
  109. + *
  110. + * This assumes that the auto-negotiation MMD is present.
  111. + *
  112. + * Enable and restart auto-negotiation.
  113. + */
  114. +int genphy_c45_restart_aneg(struct phy_device *phydev)
  115. +{
  116. + int val;
  117. +
  118. + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
  119. + if (val < 0)
  120. + return val;
  121. +
  122. + val |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;
  123. +
  124. + return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, val);
  125. +}
  126. +EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg);
  127. +
  128. +/**
  129. + * genphy_c45_aneg_done - return auto-negotiation complete status
  130. + * @phydev: target phy_device struct
  131. + *
  132. + * This assumes that the auto-negotiation MMD is present.
  133. + *
  134. + * Reads the status register from the auto-negotiation MMD, returning:
  135. + * - positive if auto-negotiation is complete
  136. + * - negative errno code on error
  137. + * - zero otherwise
  138. + */
  139. +int genphy_c45_aneg_done(struct phy_device *phydev)
  140. +{
  141. + int val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
  142. +
  143. + return val < 0 ? val : val & MDIO_AN_STAT1_COMPLETE ? 1 : 0;
  144. +}
  145. +EXPORT_SYMBOL_GPL(genphy_c45_aneg_done);
  146. +
  147. +/**
  148. + * genphy_c45_read_link - read the overall link status from the MMDs
  149. + * @phydev: target phy_device struct
  150. + * @mmd_mask: MMDs to read status from
  151. + *
  152. + * Read the link status from the specified MMDs, and if they all indicate
  153. + * that the link is up, return positive. If an error is encountered,
  154. + * a negative errno will be returned, otherwise zero.
  155. + */
  156. +int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask)
  157. +{
  158. + int val, devad;
  159. + bool link = true;
  160. +
  161. + while (mmd_mask) {
  162. + devad = __ffs(mmd_mask);
  163. + mmd_mask &= ~BIT(devad);
  164. +
  165. + val = phy_read_mmd(phydev, devad, MDIO_STAT1);
  166. + if (val < 0)
  167. + return val;
  168. +
  169. + /* Read twice because link state is latched and a
  170. + * read moves the current state into the register
  171. + */
  172. + val = phy_read_mmd(phydev, devad, MDIO_STAT1);
  173. + if (val < 0)
  174. + return val;
  175. +
  176. + if (!(val & MDIO_STAT1_LSTATUS))
  177. + link = false;
  178. + }
  179. +
  180. + return link;
  181. +}
  182. +EXPORT_SYMBOL_GPL(genphy_c45_read_link);
  183. +
  184. +/**
  185. + * genphy_c45_read_lpa - read the link partner advertisment and pause
  186. + * @phydev: target phy_device struct
  187. + *
  188. + * Read the Clause 45 defined base (7.19) and 10G (7.33) status registers,
  189. + * filling in the link partner advertisment, pause and asym_pause members
  190. + * in @phydev. This assumes that the auto-negotiation MMD is present, and
  191. + * the backplane bit (7.48.0) is clear. Clause 45 PHY drivers are expected
  192. + * to fill in the remainder of the link partner advert from vendor registers.
  193. + */
  194. +int genphy_c45_read_lpa(struct phy_device *phydev)
  195. +{
  196. + int val;
  197. +
  198. + /* Read the link partner's base page advertisment */
  199. + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA);
  200. + if (val < 0)
  201. + return val;
  202. +
  203. + phydev->lp_advertising = mii_lpa_to_ethtool_lpa_t(val);
  204. + phydev->pause = val & LPA_PAUSE_CAP ? 1 : 0;
  205. + phydev->asym_pause = val & LPA_PAUSE_ASYM ? 1 : 0;
  206. +
  207. + /* Read the link partner's 10G advertisment */
  208. + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
  209. + if (val < 0)
  210. + return val;
  211. +
  212. + if (val & MDIO_AN_10GBT_STAT_LP10G)
  213. + phydev->lp_advertising |= ADVERTISED_10000baseT_Full;
  214. +
  215. + return 0;
  216. +}
  217. +EXPORT_SYMBOL_GPL(genphy_c45_read_lpa);
  218. +
  219. +/**
  220. + * genphy_c45_read_pma - read link speed etc from PMA
  221. + * @phydev: target phy_device struct
  222. + */
  223. +int genphy_c45_read_pma(struct phy_device *phydev)
  224. +{
  225. + int val;
  226. +
  227. + val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
  228. + if (val < 0)
  229. + return val;
  230. +
  231. + switch (val & MDIO_CTRL1_SPEEDSEL) {
  232. + case 0:
  233. + phydev->speed = SPEED_10;
  234. + break;
  235. + case MDIO_PMA_CTRL1_SPEED100:
  236. + phydev->speed = SPEED_100;
  237. + break;
  238. + case MDIO_PMA_CTRL1_SPEED1000:
  239. + phydev->speed = SPEED_1000;
  240. + break;
  241. + case MDIO_CTRL1_SPEED10G:
  242. + phydev->speed = SPEED_10000;
  243. + break;
  244. + default:
  245. + phydev->speed = SPEED_UNKNOWN;
  246. + break;
  247. + }
  248. +
  249. + phydev->duplex = DUPLEX_FULL;
  250. +
  251. + return 0;
  252. +}
  253. +EXPORT_SYMBOL_GPL(genphy_c45_read_pma);
  254. --- a/drivers/net/phy/phy_device.c
  255. +++ b/drivers/net/phy/phy_device.c
  256. @@ -1390,27 +1390,19 @@ EXPORT_SYMBOL(genphy_read_status);
  257. static int gen10g_read_status(struct phy_device *phydev)
  258. {
  259. - int devad, reg;
  260. u32 mmd_mask = phydev->c45_ids.devices_in_package;
  261. -
  262. - phydev->link = 1;
  263. + int ret;
  264. /* For now just lie and say it's 10G all the time */
  265. phydev->speed = SPEED_10000;
  266. phydev->duplex = DUPLEX_FULL;
  267. - for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) {
  268. - if (!(mmd_mask & 1))
  269. - continue;
  270. -
  271. - /* Read twice because link state is latched and a
  272. - * read moves the current state into the register
  273. - */
  274. - phy_read_mmd(phydev, devad, MDIO_STAT1);
  275. - reg = phy_read_mmd(phydev, devad, MDIO_STAT1);
  276. - if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
  277. - phydev->link = 0;
  278. - }
  279. + /* Avoid reading the vendor MMDs */
  280. + mmd_mask &= ~(BIT(MDIO_MMD_VEND1) | BIT(MDIO_MMD_VEND2));
  281. +
  282. + ret = genphy_c45_read_link(phydev, mmd_mask);
  283. +
  284. + phydev->link = ret > 0 ? 1 : 0;
  285. return 0;
  286. }
  287. --- a/include/linux/phy.h
  288. +++ b/include/linux/phy.h
  289. @@ -807,6 +807,8 @@ static inline const char *phydev_name(co
  290. void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
  291. __printf(2, 3);
  292. void phy_attached_info(struct phy_device *phydev);
  293. +
  294. +/* Clause 22 PHY */
  295. int genphy_config_init(struct phy_device *phydev);
  296. int genphy_setup_forced(struct phy_device *phydev);
  297. int genphy_restart_aneg(struct phy_device *phydev);
  298. @@ -817,6 +819,16 @@ int genphy_read_status(struct phy_device
  299. int genphy_suspend(struct phy_device *phydev);
  300. int genphy_resume(struct phy_device *phydev);
  301. int genphy_soft_reset(struct phy_device *phydev);
  302. +
  303. +/* Clause 45 PHY */
  304. +int genphy_c45_restart_aneg(struct phy_device *phydev);
  305. +int genphy_c45_aneg_done(struct phy_device *phydev);
  306. +int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask);
  307. +int genphy_c45_read_lpa(struct phy_device *phydev);
  308. +int genphy_c45_read_pma(struct phy_device *phydev);
  309. +int genphy_c45_pma_setup_forced(struct phy_device *phydev);
  310. +int genphy_c45_an_disable_aneg(struct phy_device *phydev);
  311. +
  312. void phy_driver_unregister(struct phy_driver *drv);
  313. void phy_drivers_unregister(struct phy_driver *drv, int n);
  314. int phy_driver_register(struct phy_driver *new_driver, struct module *owner);