pcs-xpcs.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2020 Synopsys, Inc. and/or its affiliates.
  4. * Synopsys DesignWare XPCS helpers
  5. *
  6. * Author: Jose Abreu <Jose.Abreu@synopsys.com>
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/delay.h>
  10. #include <linux/pcs/pcs-xpcs.h>
  11. #include <linux/mdio.h>
  12. #include <linux/phy.h>
  13. #include <linux/phylink.h>
  14. #include <linux/property.h>
  15. #include "pcs-xpcs.h"
  16. #define phylink_pcs_to_xpcs(pl_pcs) \
  17. container_of((pl_pcs), struct dw_xpcs, pcs)
  18. static const int xpcs_usxgmii_features[] = {
  19. ETHTOOL_LINK_MODE_Pause_BIT,
  20. ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  21. ETHTOOL_LINK_MODE_Autoneg_BIT,
  22. ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
  23. ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
  24. ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
  25. ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
  26. __ETHTOOL_LINK_MODE_MASK_NBITS,
  27. };
  28. static const int xpcs_10gkr_features[] = {
  29. ETHTOOL_LINK_MODE_Pause_BIT,
  30. ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  31. ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
  32. __ETHTOOL_LINK_MODE_MASK_NBITS,
  33. };
  34. static const int xpcs_xlgmii_features[] = {
  35. ETHTOOL_LINK_MODE_Pause_BIT,
  36. ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  37. ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
  38. ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
  39. ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
  40. ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
  41. ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
  42. ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
  43. ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
  44. ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
  45. ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
  46. ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
  47. ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
  48. ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
  49. ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
  50. ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
  51. ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
  52. ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
  53. ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
  54. ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
  55. ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
  56. ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
  57. ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
  58. ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
  59. ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
  60. ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
  61. __ETHTOOL_LINK_MODE_MASK_NBITS,
  62. };
  63. static const int xpcs_10gbaser_features[] = {
  64. ETHTOOL_LINK_MODE_Pause_BIT,
  65. ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  66. ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
  67. ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
  68. ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
  69. ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
  70. __ETHTOOL_LINK_MODE_MASK_NBITS,
  71. };
  72. static const int xpcs_sgmii_features[] = {
  73. ETHTOOL_LINK_MODE_Pause_BIT,
  74. ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  75. ETHTOOL_LINK_MODE_Autoneg_BIT,
  76. ETHTOOL_LINK_MODE_10baseT_Half_BIT,
  77. ETHTOOL_LINK_MODE_10baseT_Full_BIT,
  78. ETHTOOL_LINK_MODE_100baseT_Half_BIT,
  79. ETHTOOL_LINK_MODE_100baseT_Full_BIT,
  80. ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
  81. ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
  82. __ETHTOOL_LINK_MODE_MASK_NBITS,
  83. };
  84. static const int xpcs_1000basex_features[] = {
  85. ETHTOOL_LINK_MODE_Pause_BIT,
  86. ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  87. ETHTOOL_LINK_MODE_Autoneg_BIT,
  88. ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
  89. __ETHTOOL_LINK_MODE_MASK_NBITS,
  90. };
  91. static const int xpcs_2500basex_features[] = {
  92. ETHTOOL_LINK_MODE_Pause_BIT,
  93. ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  94. ETHTOOL_LINK_MODE_Autoneg_BIT,
  95. ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
  96. ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
  97. __ETHTOOL_LINK_MODE_MASK_NBITS,
  98. };
  99. static const phy_interface_t xpcs_usxgmii_interfaces[] = {
  100. PHY_INTERFACE_MODE_USXGMII,
  101. };
  102. static const phy_interface_t xpcs_10gkr_interfaces[] = {
  103. PHY_INTERFACE_MODE_10GKR,
  104. };
  105. static const phy_interface_t xpcs_xlgmii_interfaces[] = {
  106. PHY_INTERFACE_MODE_XLGMII,
  107. };
  108. static const phy_interface_t xpcs_10gbaser_interfaces[] = {
  109. PHY_INTERFACE_MODE_10GBASER,
  110. };
  111. static const phy_interface_t xpcs_sgmii_interfaces[] = {
  112. PHY_INTERFACE_MODE_SGMII,
  113. };
  114. static const phy_interface_t xpcs_1000basex_interfaces[] = {
  115. PHY_INTERFACE_MODE_1000BASEX,
  116. };
  117. static const phy_interface_t xpcs_2500basex_interfaces[] = {
  118. PHY_INTERFACE_MODE_2500BASEX,
  119. };
  120. enum {
  121. DW_XPCS_USXGMII,
  122. DW_XPCS_10GKR,
  123. DW_XPCS_XLGMII,
  124. DW_XPCS_10GBASER,
  125. DW_XPCS_SGMII,
  126. DW_XPCS_1000BASEX,
  127. DW_XPCS_2500BASEX,
  128. DW_XPCS_INTERFACE_MAX,
  129. };
  130. struct dw_xpcs_compat {
  131. const int *supported;
  132. const phy_interface_t *interface;
  133. int num_interfaces;
  134. int an_mode;
  135. int (*pma_config)(struct dw_xpcs *xpcs);
  136. };
  137. struct dw_xpcs_desc {
  138. u32 id;
  139. u32 mask;
  140. const struct dw_xpcs_compat *compat;
  141. };
  142. static const struct dw_xpcs_compat *
  143. xpcs_find_compat(const struct dw_xpcs_desc *desc, phy_interface_t interface)
  144. {
  145. int i, j;
  146. for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
  147. const struct dw_xpcs_compat *compat = &desc->compat[i];
  148. for (j = 0; j < compat->num_interfaces; j++)
  149. if (compat->interface[j] == interface)
  150. return compat;
  151. }
  152. return NULL;
  153. }
  154. int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface)
  155. {
  156. const struct dw_xpcs_compat *compat;
  157. compat = xpcs_find_compat(xpcs->desc, interface);
  158. if (!compat)
  159. return -ENODEV;
  160. return compat->an_mode;
  161. }
  162. EXPORT_SYMBOL_GPL(xpcs_get_an_mode);
  163. static bool __xpcs_linkmode_supported(const struct dw_xpcs_compat *compat,
  164. enum ethtool_link_mode_bit_indices linkmode)
  165. {
  166. int i;
  167. for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
  168. if (compat->supported[i] == linkmode)
  169. return true;
  170. return false;
  171. }
  172. #define xpcs_linkmode_supported(compat, mode) \
  173. __xpcs_linkmode_supported(compat, ETHTOOL_LINK_MODE_ ## mode ## _BIT)
  174. int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg)
  175. {
  176. return mdiodev_c45_read(xpcs->mdiodev, dev, reg);
  177. }
  178. int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val)
  179. {
  180. return mdiodev_c45_write(xpcs->mdiodev, dev, reg, val);
  181. }
  182. static int xpcs_modify_changed(struct dw_xpcs *xpcs, int dev, u32 reg,
  183. u16 mask, u16 set)
  184. {
  185. return mdiodev_c45_modify_changed(xpcs->mdiodev, dev, reg, mask, set);
  186. }
  187. static int xpcs_read_vendor(struct dw_xpcs *xpcs, int dev, u32 reg)
  188. {
  189. return xpcs_read(xpcs, dev, DW_VENDOR | reg);
  190. }
  191. static int xpcs_write_vendor(struct dw_xpcs *xpcs, int dev, int reg,
  192. u16 val)
  193. {
  194. return xpcs_write(xpcs, dev, DW_VENDOR | reg, val);
  195. }
  196. int xpcs_read_vpcs(struct dw_xpcs *xpcs, int reg)
  197. {
  198. return xpcs_read_vendor(xpcs, MDIO_MMD_PCS, reg);
  199. }
  200. int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val)
  201. {
  202. return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val);
  203. }
  204. static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev)
  205. {
  206. /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
  207. unsigned int retries = 12;
  208. int ret;
  209. do {
  210. msleep(50);
  211. ret = xpcs_read(xpcs, dev, MDIO_CTRL1);
  212. if (ret < 0)
  213. return ret;
  214. } while (ret & MDIO_CTRL1_RESET && --retries);
  215. return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
  216. }
  217. static int xpcs_soft_reset(struct dw_xpcs *xpcs,
  218. const struct dw_xpcs_compat *compat)
  219. {
  220. int ret, dev;
  221. switch (compat->an_mode) {
  222. case DW_AN_C73:
  223. case DW_10GBASER:
  224. dev = MDIO_MMD_PCS;
  225. break;
  226. case DW_AN_C37_SGMII:
  227. case DW_2500BASEX:
  228. case DW_AN_C37_1000BASEX:
  229. dev = MDIO_MMD_VEND2;
  230. break;
  231. default:
  232. return -EINVAL;
  233. }
  234. ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET);
  235. if (ret < 0)
  236. return ret;
  237. return xpcs_poll_reset(xpcs, dev);
  238. }
  239. #define xpcs_warn(__xpcs, __state, __args...) \
  240. ({ \
  241. if ((__state)->link) \
  242. dev_warn(&(__xpcs)->mdiodev->dev, ##__args); \
  243. })
  244. static int xpcs_read_fault_c73(struct dw_xpcs *xpcs,
  245. struct phylink_link_state *state,
  246. u16 pcs_stat1)
  247. {
  248. int ret;
  249. if (pcs_stat1 & MDIO_STAT1_FAULT) {
  250. xpcs_warn(xpcs, state, "Link fault condition detected!\n");
  251. return -EFAULT;
  252. }
  253. ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT2);
  254. if (ret < 0)
  255. return ret;
  256. if (ret & MDIO_STAT2_RXFAULT)
  257. xpcs_warn(xpcs, state, "Receiver fault detected!\n");
  258. if (ret & MDIO_STAT2_TXFAULT)
  259. xpcs_warn(xpcs, state, "Transmitter fault detected!\n");
  260. ret = xpcs_read_vendor(xpcs, MDIO_MMD_PCS, DW_VR_XS_PCS_DIG_STS);
  261. if (ret < 0)
  262. return ret;
  263. if (ret & DW_RXFIFO_ERR) {
  264. xpcs_warn(xpcs, state, "FIFO fault condition detected!\n");
  265. return -EFAULT;
  266. }
  267. ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
  268. if (ret < 0)
  269. return ret;
  270. if (!(ret & MDIO_PCS_10GBRT_STAT1_BLKLK))
  271. xpcs_warn(xpcs, state, "Link is not locked!\n");
  272. ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT2);
  273. if (ret < 0)
  274. return ret;
  275. if (ret & MDIO_PCS_10GBRT_STAT2_ERR) {
  276. xpcs_warn(xpcs, state, "Link has errors!\n");
  277. return -EFAULT;
  278. }
  279. return 0;
  280. }
  281. static void xpcs_config_usxgmii(struct dw_xpcs *xpcs, int speed)
  282. {
  283. int ret, speed_sel;
  284. switch (speed) {
  285. case SPEED_10:
  286. speed_sel = DW_USXGMII_10;
  287. break;
  288. case SPEED_100:
  289. speed_sel = DW_USXGMII_100;
  290. break;
  291. case SPEED_1000:
  292. speed_sel = DW_USXGMII_1000;
  293. break;
  294. case SPEED_2500:
  295. speed_sel = DW_USXGMII_2500;
  296. break;
  297. case SPEED_5000:
  298. speed_sel = DW_USXGMII_5000;
  299. break;
  300. case SPEED_10000:
  301. speed_sel = DW_USXGMII_10000;
  302. break;
  303. default:
  304. /* Nothing to do here */
  305. return;
  306. }
  307. ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
  308. if (ret < 0)
  309. goto out;
  310. ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_EN);
  311. if (ret < 0)
  312. goto out;
  313. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
  314. if (ret < 0)
  315. goto out;
  316. ret &= ~DW_USXGMII_SS_MASK;
  317. ret |= speed_sel | DW_USXGMII_FULL;
  318. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
  319. if (ret < 0)
  320. goto out;
  321. ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
  322. if (ret < 0)
  323. goto out;
  324. ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST);
  325. if (ret < 0)
  326. goto out;
  327. return;
  328. out:
  329. pr_err("%s: XPCS access returned %pe\n", __func__, ERR_PTR(ret));
  330. }
  331. static int _xpcs_config_aneg_c73(struct dw_xpcs *xpcs,
  332. const struct dw_xpcs_compat *compat)
  333. {
  334. int ret, adv;
  335. /* By default, in USXGMII mode XPCS operates at 10G baud and
  336. * replicates data to achieve lower speeds. Hereby, in this
  337. * default configuration we need to advertise all supported
  338. * modes and not only the ones we want to use.
  339. */
  340. /* SR_AN_ADV3 */
  341. adv = 0;
  342. if (xpcs_linkmode_supported(compat, 2500baseX_Full))
  343. adv |= DW_C73_2500KX;
  344. /* TODO: 5000baseKR */
  345. ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV3, adv);
  346. if (ret < 0)
  347. return ret;
  348. /* SR_AN_ADV2 */
  349. adv = 0;
  350. if (xpcs_linkmode_supported(compat, 1000baseKX_Full))
  351. adv |= DW_C73_1000KX;
  352. if (xpcs_linkmode_supported(compat, 10000baseKX4_Full))
  353. adv |= DW_C73_10000KX4;
  354. if (xpcs_linkmode_supported(compat, 10000baseKR_Full))
  355. adv |= DW_C73_10000KR;
  356. ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV2, adv);
  357. if (ret < 0)
  358. return ret;
  359. /* SR_AN_ADV1 */
  360. adv = DW_C73_AN_ADV_SF;
  361. if (xpcs_linkmode_supported(compat, Pause))
  362. adv |= DW_C73_PAUSE;
  363. if (xpcs_linkmode_supported(compat, Asym_Pause))
  364. adv |= DW_C73_ASYM_PAUSE;
  365. return xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV1, adv);
  366. }
  367. static int xpcs_config_aneg_c73(struct dw_xpcs *xpcs,
  368. const struct dw_xpcs_compat *compat)
  369. {
  370. int ret;
  371. ret = _xpcs_config_aneg_c73(xpcs, compat);
  372. if (ret < 0)
  373. return ret;
  374. ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_CTRL1);
  375. if (ret < 0)
  376. return ret;
  377. ret |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;
  378. return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret);
  379. }
  380. static int xpcs_aneg_done_c73(struct dw_xpcs *xpcs,
  381. struct phylink_link_state *state,
  382. const struct dw_xpcs_compat *compat, u16 an_stat1)
  383. {
  384. int ret;
  385. if (an_stat1 & MDIO_AN_STAT1_COMPLETE) {
  386. ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_AN_LPA);
  387. if (ret < 0)
  388. return ret;
  389. /* Check if Aneg outcome is valid */
  390. if (!(ret & DW_C73_AN_ADV_SF)) {
  391. xpcs_config_aneg_c73(xpcs, compat);
  392. return 0;
  393. }
  394. return 1;
  395. }
  396. return 0;
  397. }
  398. static int xpcs_read_lpa_c73(struct dw_xpcs *xpcs,
  399. struct phylink_link_state *state, u16 an_stat1)
  400. {
  401. u16 lpa[3];
  402. int i, ret;
  403. if (!(an_stat1 & MDIO_AN_STAT1_LPABLE)) {
  404. phylink_clear(state->lp_advertising, Autoneg);
  405. return 0;
  406. }
  407. phylink_set(state->lp_advertising, Autoneg);
  408. /* Read Clause 73 link partner advertisement */
  409. for (i = ARRAY_SIZE(lpa); --i >= 0; ) {
  410. ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_AN_LPA + i);
  411. if (ret < 0)
  412. return ret;
  413. lpa[i] = ret;
  414. }
  415. mii_c73_mod_linkmode(state->lp_advertising, lpa);
  416. return 0;
  417. }
  418. static int xpcs_get_max_xlgmii_speed(struct dw_xpcs *xpcs,
  419. struct phylink_link_state *state)
  420. {
  421. unsigned long *adv = state->advertising;
  422. int speed = SPEED_UNKNOWN;
  423. int bit;
  424. for_each_set_bit(bit, adv, __ETHTOOL_LINK_MODE_MASK_NBITS) {
  425. int new_speed = SPEED_UNKNOWN;
  426. switch (bit) {
  427. case ETHTOOL_LINK_MODE_25000baseCR_Full_BIT:
  428. case ETHTOOL_LINK_MODE_25000baseKR_Full_BIT:
  429. case ETHTOOL_LINK_MODE_25000baseSR_Full_BIT:
  430. new_speed = SPEED_25000;
  431. break;
  432. case ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT:
  433. case ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT:
  434. case ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT:
  435. case ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT:
  436. new_speed = SPEED_40000;
  437. break;
  438. case ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT:
  439. case ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT:
  440. case ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT:
  441. case ETHTOOL_LINK_MODE_50000baseKR_Full_BIT:
  442. case ETHTOOL_LINK_MODE_50000baseSR_Full_BIT:
  443. case ETHTOOL_LINK_MODE_50000baseCR_Full_BIT:
  444. case ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT:
  445. case ETHTOOL_LINK_MODE_50000baseDR_Full_BIT:
  446. new_speed = SPEED_50000;
  447. break;
  448. case ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT:
  449. case ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT:
  450. case ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT:
  451. case ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT:
  452. case ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT:
  453. case ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT:
  454. case ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT:
  455. case ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT:
  456. case ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT:
  457. new_speed = SPEED_100000;
  458. break;
  459. default:
  460. continue;
  461. }
  462. if (new_speed > speed)
  463. speed = new_speed;
  464. }
  465. return speed;
  466. }
  467. static void xpcs_resolve_pma(struct dw_xpcs *xpcs,
  468. struct phylink_link_state *state)
  469. {
  470. state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
  471. state->duplex = DUPLEX_FULL;
  472. switch (state->interface) {
  473. case PHY_INTERFACE_MODE_10GKR:
  474. state->speed = SPEED_10000;
  475. break;
  476. case PHY_INTERFACE_MODE_XLGMII:
  477. state->speed = xpcs_get_max_xlgmii_speed(xpcs, state);
  478. break;
  479. default:
  480. state->speed = SPEED_UNKNOWN;
  481. break;
  482. }
  483. }
  484. static int xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
  485. const struct phylink_link_state *state)
  486. {
  487. __ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported) = { 0, };
  488. const struct dw_xpcs_compat *compat;
  489. struct dw_xpcs *xpcs;
  490. int i;
  491. xpcs = phylink_pcs_to_xpcs(pcs);
  492. compat = xpcs_find_compat(xpcs->desc, state->interface);
  493. if (!compat)
  494. return -EINVAL;
  495. /* Populate the supported link modes for this PHY interface type.
  496. * FIXME: what about the port modes and autoneg bit? This masks
  497. * all those away.
  498. */
  499. for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
  500. set_bit(compat->supported[i], xpcs_supported);
  501. linkmode_and(supported, supported, xpcs_supported);
  502. return 0;
  503. }
  504. void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
  505. {
  506. int i, j;
  507. for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
  508. const struct dw_xpcs_compat *compat = &xpcs->desc->compat[i];
  509. for (j = 0; j < compat->num_interfaces; j++)
  510. __set_bit(compat->interface[j], interfaces);
  511. }
  512. }
  513. EXPORT_SYMBOL_GPL(xpcs_get_interfaces);
  514. int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
  515. {
  516. int ret;
  517. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0);
  518. if (ret < 0)
  519. return ret;
  520. if (enable) {
  521. /* Enable EEE */
  522. ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
  523. DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN |
  524. DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
  525. mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT;
  526. } else {
  527. ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
  528. DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN |
  529. DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
  530. DW_VR_MII_EEE_MULT_FACT_100NS);
  531. }
  532. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0, ret);
  533. if (ret < 0)
  534. return ret;
  535. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1);
  536. if (ret < 0)
  537. return ret;
  538. if (enable)
  539. ret |= DW_VR_MII_EEE_TRN_LPI;
  540. else
  541. ret &= ~DW_VR_MII_EEE_TRN_LPI;
  542. return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret);
  543. }
  544. EXPORT_SYMBOL_GPL(xpcs_config_eee);
  545. static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
  546. unsigned int neg_mode)
  547. {
  548. int ret, mdio_ctrl, tx_conf;
  549. if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
  550. xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1);
  551. /* For AN for C37 SGMII mode, the settings are :-
  552. * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case
  553. it is already enabled)
  554. * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
  555. * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
  556. * DW xPCS used with DW EQoS MAC is always MAC side SGMII.
  557. * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
  558. * speed/duplex mode change by HW after SGMII AN complete)
  559. * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN)
  560. *
  561. * Note: Since it is MAC side SGMII, there is no need to set
  562. * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from
  563. * PHY about the link state change after C28 AN is completed
  564. * between PHY and Link Partner. There is also no need to
  565. * trigger AN restart for MAC-side SGMII.
  566. */
  567. mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
  568. if (mdio_ctrl < 0)
  569. return mdio_ctrl;
  570. if (mdio_ctrl & AN_CL37_EN) {
  571. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
  572. mdio_ctrl & ~AN_CL37_EN);
  573. if (ret < 0)
  574. return ret;
  575. }
  576. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
  577. if (ret < 0)
  578. return ret;
  579. ret &= ~(DW_VR_MII_PCS_MODE_MASK | DW_VR_MII_TX_CONFIG_MASK);
  580. ret |= (DW_VR_MII_PCS_MODE_C37_SGMII <<
  581. DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT &
  582. DW_VR_MII_PCS_MODE_MASK);
  583. if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
  584. ret |= DW_VR_MII_AN_CTRL_8BIT;
  585. /* Hardware requires it to be PHY side SGMII */
  586. tx_conf = DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII;
  587. } else {
  588. tx_conf = DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII;
  589. }
  590. ret |= tx_conf << DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
  591. DW_VR_MII_TX_CONFIG_MASK;
  592. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
  593. if (ret < 0)
  594. return ret;
  595. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
  596. if (ret < 0)
  597. return ret;
  598. if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
  599. ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
  600. else
  601. ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
  602. if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
  603. ret |= DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL;
  604. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
  605. if (ret < 0)
  606. return ret;
  607. if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
  608. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
  609. mdio_ctrl | AN_CL37_EN);
  610. return ret;
  611. }
  612. static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs,
  613. unsigned int neg_mode,
  614. const unsigned long *advertising)
  615. {
  616. phy_interface_t interface = PHY_INTERFACE_MODE_1000BASEX;
  617. int ret, mdio_ctrl, adv;
  618. bool changed = 0;
  619. if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
  620. xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1);
  621. /* According to Chap 7.12, to set 1000BASE-X C37 AN, AN must
  622. * be disabled first:-
  623. * 1) VR_MII_MMD_CTRL Bit(12)[AN_ENABLE] = 0b
  624. * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37)
  625. */
  626. mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
  627. if (mdio_ctrl < 0)
  628. return mdio_ctrl;
  629. if (mdio_ctrl & AN_CL37_EN) {
  630. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
  631. mdio_ctrl & ~AN_CL37_EN);
  632. if (ret < 0)
  633. return ret;
  634. }
  635. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
  636. if (ret < 0)
  637. return ret;
  638. ret &= ~DW_VR_MII_PCS_MODE_MASK;
  639. if (!xpcs->pcs.poll)
  640. ret |= DW_VR_MII_AN_INTR_EN;
  641. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
  642. if (ret < 0)
  643. return ret;
  644. /* Check for advertising changes and update the C45 MII ADV
  645. * register accordingly.
  646. */
  647. adv = phylink_mii_c22_pcs_encode_advertisement(interface,
  648. advertising);
  649. if (adv >= 0) {
  650. ret = xpcs_modify_changed(xpcs, MDIO_MMD_VEND2,
  651. MII_ADVERTISE, 0xffff, adv);
  652. if (ret < 0)
  653. return ret;
  654. changed = ret;
  655. }
  656. /* Clear CL37 AN complete status */
  657. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
  658. if (ret < 0)
  659. return ret;
  660. if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
  661. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
  662. mdio_ctrl | AN_CL37_EN);
  663. if (ret < 0)
  664. return ret;
  665. }
  666. return changed;
  667. }
  668. static int xpcs_config_2500basex(struct dw_xpcs *xpcs)
  669. {
  670. int ret;
  671. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
  672. if (ret < 0)
  673. return ret;
  674. ret |= DW_VR_MII_DIG_CTRL1_2G5_EN;
  675. ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
  676. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
  677. if (ret < 0)
  678. return ret;
  679. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
  680. if (ret < 0)
  681. return ret;
  682. ret &= ~AN_CL37_EN;
  683. ret |= SGMII_SPEED_SS6;
  684. ret &= ~SGMII_SPEED_SS13;
  685. return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret);
  686. }
  687. int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
  688. const unsigned long *advertising, unsigned int neg_mode)
  689. {
  690. const struct dw_xpcs_compat *compat;
  691. int ret;
  692. compat = xpcs_find_compat(xpcs->desc, interface);
  693. if (!compat)
  694. return -ENODEV;
  695. if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
  696. ret = txgbe_xpcs_switch_mode(xpcs, interface);
  697. if (ret)
  698. return ret;
  699. }
  700. switch (compat->an_mode) {
  701. case DW_10GBASER:
  702. break;
  703. case DW_AN_C73:
  704. if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
  705. ret = xpcs_config_aneg_c73(xpcs, compat);
  706. if (ret)
  707. return ret;
  708. }
  709. break;
  710. case DW_AN_C37_SGMII:
  711. ret = xpcs_config_aneg_c37_sgmii(xpcs, neg_mode);
  712. if (ret)
  713. return ret;
  714. break;
  715. case DW_AN_C37_1000BASEX:
  716. ret = xpcs_config_aneg_c37_1000basex(xpcs, neg_mode,
  717. advertising);
  718. if (ret)
  719. return ret;
  720. break;
  721. case DW_2500BASEX:
  722. ret = xpcs_config_2500basex(xpcs);
  723. if (ret)
  724. return ret;
  725. break;
  726. default:
  727. return -EINVAL;
  728. }
  729. if (compat->pma_config) {
  730. ret = compat->pma_config(xpcs);
  731. if (ret)
  732. return ret;
  733. }
  734. return 0;
  735. }
  736. EXPORT_SYMBOL_GPL(xpcs_do_config);
  737. static int xpcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
  738. phy_interface_t interface,
  739. const unsigned long *advertising,
  740. bool permit_pause_to_mac)
  741. {
  742. struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
  743. return xpcs_do_config(xpcs, interface, advertising, neg_mode);
  744. }
  745. static int xpcs_get_state_c73(struct dw_xpcs *xpcs,
  746. struct phylink_link_state *state,
  747. const struct dw_xpcs_compat *compat)
  748. {
  749. bool an_enabled;
  750. int pcs_stat1;
  751. int an_stat1;
  752. int ret;
  753. /* The link status bit is latching-low, so it is important to
  754. * avoid unnecessary re-reads of this register to avoid missing
  755. * a link-down event.
  756. */
  757. pcs_stat1 = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1);
  758. if (pcs_stat1 < 0) {
  759. state->link = false;
  760. return pcs_stat1;
  761. }
  762. /* Link needs to be read first ... */
  763. state->link = !!(pcs_stat1 & MDIO_STAT1_LSTATUS);
  764. /* ... and then we check the faults. */
  765. ret = xpcs_read_fault_c73(xpcs, state, pcs_stat1);
  766. if (ret) {
  767. ret = xpcs_soft_reset(xpcs, compat);
  768. if (ret)
  769. return ret;
  770. state->link = 0;
  771. return xpcs_do_config(xpcs, state->interface, NULL,
  772. PHYLINK_PCS_NEG_INBAND_ENABLED);
  773. }
  774. /* There is no point doing anything else if the link is down. */
  775. if (!state->link)
  776. return 0;
  777. an_enabled = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
  778. state->advertising);
  779. if (an_enabled) {
  780. /* The link status bit is latching-low, so it is important to
  781. * avoid unnecessary re-reads of this register to avoid missing
  782. * a link-down event.
  783. */
  784. an_stat1 = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
  785. if (an_stat1 < 0) {
  786. state->link = false;
  787. return an_stat1;
  788. }
  789. state->an_complete = xpcs_aneg_done_c73(xpcs, state, compat,
  790. an_stat1);
  791. if (!state->an_complete) {
  792. state->link = false;
  793. return 0;
  794. }
  795. ret = xpcs_read_lpa_c73(xpcs, state, an_stat1);
  796. if (ret < 0) {
  797. state->link = false;
  798. return ret;
  799. }
  800. phylink_resolve_c73(state);
  801. } else {
  802. xpcs_resolve_pma(xpcs, state);
  803. }
  804. return 0;
  805. }
  806. static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,
  807. struct phylink_link_state *state)
  808. {
  809. int ret;
  810. /* Reset link_state */
  811. state->link = false;
  812. state->speed = SPEED_UNKNOWN;
  813. state->duplex = DUPLEX_UNKNOWN;
  814. state->pause = 0;
  815. /* For C37 SGMII mode, we check DW_VR_MII_AN_INTR_STS for link
  816. * status, speed and duplex.
  817. */
  818. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS);
  819. if (ret < 0)
  820. return ret;
  821. if (ret & DW_VR_MII_C37_ANSGM_SP_LNKSTS) {
  822. int speed_value;
  823. state->link = true;
  824. speed_value = (ret & DW_VR_MII_AN_STS_C37_ANSGM_SP) >>
  825. DW_VR_MII_AN_STS_C37_ANSGM_SP_SHIFT;
  826. if (speed_value == DW_VR_MII_C37_ANSGM_SP_1000)
  827. state->speed = SPEED_1000;
  828. else if (speed_value == DW_VR_MII_C37_ANSGM_SP_100)
  829. state->speed = SPEED_100;
  830. else
  831. state->speed = SPEED_10;
  832. if (ret & DW_VR_MII_AN_STS_C37_ANSGM_FD)
  833. state->duplex = DUPLEX_FULL;
  834. else
  835. state->duplex = DUPLEX_HALF;
  836. } else if (ret == DW_VR_MII_AN_STS_C37_ANCMPLT_INTR) {
  837. int speed, duplex;
  838. state->link = true;
  839. speed = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
  840. if (speed < 0)
  841. return speed;
  842. speed &= SGMII_SPEED_SS13 | SGMII_SPEED_SS6;
  843. if (speed == SGMII_SPEED_SS6)
  844. state->speed = SPEED_1000;
  845. else if (speed == SGMII_SPEED_SS13)
  846. state->speed = SPEED_100;
  847. else if (speed == 0)
  848. state->speed = SPEED_10;
  849. duplex = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
  850. if (duplex < 0)
  851. return duplex;
  852. if (duplex & DW_FULL_DUPLEX)
  853. state->duplex = DUPLEX_FULL;
  854. else if (duplex & DW_HALF_DUPLEX)
  855. state->duplex = DUPLEX_HALF;
  856. xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
  857. }
  858. return 0;
  859. }
  860. static int xpcs_get_state_c37_1000basex(struct dw_xpcs *xpcs,
  861. struct phylink_link_state *state)
  862. {
  863. int lpa, bmsr;
  864. if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
  865. state->advertising)) {
  866. /* Reset link state */
  867. state->link = false;
  868. lpa = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_LPA);
  869. if (lpa < 0 || lpa & LPA_RFAULT)
  870. return lpa;
  871. bmsr = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_BMSR);
  872. if (bmsr < 0)
  873. return bmsr;
  874. /* Clear AN complete interrupt */
  875. if (!xpcs->pcs.poll) {
  876. int an_intr;
  877. an_intr = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS);
  878. if (an_intr & DW_VR_MII_AN_STS_C37_ANCMPLT_INTR) {
  879. an_intr &= ~DW_VR_MII_AN_STS_C37_ANCMPLT_INTR;
  880. xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, an_intr);
  881. }
  882. }
  883. phylink_mii_c22_pcs_decode_state(state, bmsr, lpa);
  884. }
  885. return 0;
  886. }
  887. static int xpcs_get_state_2500basex(struct dw_xpcs *xpcs,
  888. struct phylink_link_state *state)
  889. {
  890. int ret;
  891. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_STS);
  892. if (ret < 0) {
  893. state->link = 0;
  894. return ret;
  895. }
  896. state->link = !!(ret & DW_VR_MII_MMD_STS_LINK_STS);
  897. if (!state->link)
  898. return 0;
  899. state->speed = SPEED_2500;
  900. state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX;
  901. state->duplex = DUPLEX_FULL;
  902. return 0;
  903. }
  904. static void xpcs_get_state(struct phylink_pcs *pcs,
  905. struct phylink_link_state *state)
  906. {
  907. struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
  908. const struct dw_xpcs_compat *compat;
  909. int ret;
  910. compat = xpcs_find_compat(xpcs->desc, state->interface);
  911. if (!compat)
  912. return;
  913. switch (compat->an_mode) {
  914. case DW_10GBASER:
  915. phylink_mii_c45_pcs_get_state(xpcs->mdiodev, state);
  916. break;
  917. case DW_AN_C73:
  918. ret = xpcs_get_state_c73(xpcs, state, compat);
  919. if (ret) {
  920. pr_err("xpcs_get_state_c73 returned %pe\n",
  921. ERR_PTR(ret));
  922. return;
  923. }
  924. break;
  925. case DW_AN_C37_SGMII:
  926. ret = xpcs_get_state_c37_sgmii(xpcs, state);
  927. if (ret) {
  928. pr_err("xpcs_get_state_c37_sgmii returned %pe\n",
  929. ERR_PTR(ret));
  930. }
  931. break;
  932. case DW_AN_C37_1000BASEX:
  933. ret = xpcs_get_state_c37_1000basex(xpcs, state);
  934. if (ret) {
  935. pr_err("xpcs_get_state_c37_1000basex returned %pe\n",
  936. ERR_PTR(ret));
  937. }
  938. break;
  939. case DW_2500BASEX:
  940. ret = xpcs_get_state_2500basex(xpcs, state);
  941. if (ret) {
  942. pr_err("xpcs_get_state_2500basex returned %pe\n",
  943. ERR_PTR(ret));
  944. }
  945. break;
  946. default:
  947. return;
  948. }
  949. }
  950. static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int neg_mode,
  951. int speed, int duplex)
  952. {
  953. int val, ret;
  954. if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
  955. return;
  956. val = mii_bmcr_encode_fixed(speed, duplex);
  957. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val);
  958. if (ret)
  959. pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
  960. }
  961. static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int neg_mode,
  962. int speed, int duplex)
  963. {
  964. int val, ret;
  965. if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
  966. return;
  967. switch (speed) {
  968. case SPEED_1000:
  969. val = BMCR_SPEED1000;
  970. break;
  971. case SPEED_100:
  972. case SPEED_10:
  973. default:
  974. pr_err("%s: speed = %d\n", __func__, speed);
  975. return;
  976. }
  977. if (duplex == DUPLEX_FULL)
  978. val |= BMCR_FULLDPLX;
  979. else
  980. pr_err("%s: half duplex not supported\n", __func__);
  981. ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val);
  982. if (ret)
  983. pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
  984. }
  985. void xpcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
  986. phy_interface_t interface, int speed, int duplex)
  987. {
  988. struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
  989. if (interface == PHY_INTERFACE_MODE_USXGMII)
  990. return xpcs_config_usxgmii(xpcs, speed);
  991. if (interface == PHY_INTERFACE_MODE_SGMII)
  992. return xpcs_link_up_sgmii(xpcs, neg_mode, speed, duplex);
  993. if (interface == PHY_INTERFACE_MODE_1000BASEX)
  994. return xpcs_link_up_1000basex(xpcs, neg_mode, speed, duplex);
  995. }
  996. EXPORT_SYMBOL_GPL(xpcs_link_up);
  997. static void xpcs_an_restart(struct phylink_pcs *pcs)
  998. {
  999. struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
  1000. int ret;
  1001. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
  1002. if (ret >= 0) {
  1003. ret |= BMCR_ANRESTART;
  1004. xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
  1005. }
  1006. }
  1007. static int xpcs_get_id(struct dw_xpcs *xpcs)
  1008. {
  1009. int ret;
  1010. u32 id;
  1011. /* First, search C73 PCS using PCS MMD 3. Return ENODEV if communication
  1012. * failed indicating that device couldn't be reached.
  1013. */
  1014. ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID1);
  1015. if (ret < 0)
  1016. return -ENODEV;
  1017. id = ret << 16;
  1018. ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID2);
  1019. if (ret < 0)
  1020. return ret;
  1021. id |= ret;
  1022. /* If Device IDs are not all zeros or ones, then 10GBase-X/R or C73
  1023. * KR/KX4 PCS found. Otherwise fallback to detecting 1000Base-X or C37
  1024. * PCS in MII MMD 31.
  1025. */
  1026. if (!id || id == 0xffffffff) {
  1027. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1);
  1028. if (ret < 0)
  1029. return ret;
  1030. id = ret << 16;
  1031. ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2);
  1032. if (ret < 0)
  1033. return ret;
  1034. id |= ret;
  1035. }
  1036. /* Set the PCS ID if it hasn't been pre-initialized */
  1037. if (xpcs->info.pcs == DW_XPCS_ID_NATIVE)
  1038. xpcs->info.pcs = id;
  1039. /* Find out PMA/PMD ID from MMD 1 device ID registers */
  1040. ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID1);
  1041. if (ret < 0)
  1042. return ret;
  1043. id = ret;
  1044. ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID2);
  1045. if (ret < 0)
  1046. return ret;
  1047. /* Note the inverted dword order and masked out Model/Revision numbers
  1048. * with respect to what is done with the PCS ID...
  1049. */
  1050. ret = (ret >> 10) & 0x3F;
  1051. id |= ret << 16;
  1052. /* Set the PMA ID if it hasn't been pre-initialized */
  1053. if (xpcs->info.pma == DW_XPCS_PMA_ID_NATIVE)
  1054. xpcs->info.pma = id;
  1055. return 0;
  1056. }
  1057. static const struct dw_xpcs_compat synopsys_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
  1058. [DW_XPCS_USXGMII] = {
  1059. .supported = xpcs_usxgmii_features,
  1060. .interface = xpcs_usxgmii_interfaces,
  1061. .num_interfaces = ARRAY_SIZE(xpcs_usxgmii_interfaces),
  1062. .an_mode = DW_AN_C73,
  1063. },
  1064. [DW_XPCS_10GKR] = {
  1065. .supported = xpcs_10gkr_features,
  1066. .interface = xpcs_10gkr_interfaces,
  1067. .num_interfaces = ARRAY_SIZE(xpcs_10gkr_interfaces),
  1068. .an_mode = DW_AN_C73,
  1069. },
  1070. [DW_XPCS_XLGMII] = {
  1071. .supported = xpcs_xlgmii_features,
  1072. .interface = xpcs_xlgmii_interfaces,
  1073. .num_interfaces = ARRAY_SIZE(xpcs_xlgmii_interfaces),
  1074. .an_mode = DW_AN_C73,
  1075. },
  1076. [DW_XPCS_10GBASER] = {
  1077. .supported = xpcs_10gbaser_features,
  1078. .interface = xpcs_10gbaser_interfaces,
  1079. .num_interfaces = ARRAY_SIZE(xpcs_10gbaser_interfaces),
  1080. .an_mode = DW_10GBASER,
  1081. },
  1082. [DW_XPCS_SGMII] = {
  1083. .supported = xpcs_sgmii_features,
  1084. .interface = xpcs_sgmii_interfaces,
  1085. .num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
  1086. .an_mode = DW_AN_C37_SGMII,
  1087. },
  1088. [DW_XPCS_1000BASEX] = {
  1089. .supported = xpcs_1000basex_features,
  1090. .interface = xpcs_1000basex_interfaces,
  1091. .num_interfaces = ARRAY_SIZE(xpcs_1000basex_interfaces),
  1092. .an_mode = DW_AN_C37_1000BASEX,
  1093. },
  1094. [DW_XPCS_2500BASEX] = {
  1095. .supported = xpcs_2500basex_features,
  1096. .interface = xpcs_2500basex_interfaces,
  1097. .num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces),
  1098. .an_mode = DW_2500BASEX,
  1099. },
  1100. };
  1101. static const struct dw_xpcs_compat nxp_sja1105_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
  1102. [DW_XPCS_SGMII] = {
  1103. .supported = xpcs_sgmii_features,
  1104. .interface = xpcs_sgmii_interfaces,
  1105. .num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
  1106. .an_mode = DW_AN_C37_SGMII,
  1107. .pma_config = nxp_sja1105_sgmii_pma_config,
  1108. },
  1109. };
  1110. static const struct dw_xpcs_compat nxp_sja1110_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
  1111. [DW_XPCS_SGMII] = {
  1112. .supported = xpcs_sgmii_features,
  1113. .interface = xpcs_sgmii_interfaces,
  1114. .num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
  1115. .an_mode = DW_AN_C37_SGMII,
  1116. .pma_config = nxp_sja1110_sgmii_pma_config,
  1117. },
  1118. [DW_XPCS_2500BASEX] = {
  1119. .supported = xpcs_2500basex_features,
  1120. .interface = xpcs_2500basex_interfaces,
  1121. .num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces),
  1122. .an_mode = DW_2500BASEX,
  1123. .pma_config = nxp_sja1110_2500basex_pma_config,
  1124. },
  1125. };
  1126. static const struct dw_xpcs_desc xpcs_desc_list[] = {
  1127. {
  1128. .id = DW_XPCS_ID,
  1129. .mask = DW_XPCS_ID_MASK,
  1130. .compat = synopsys_xpcs_compat,
  1131. }, {
  1132. .id = NXP_SJA1105_XPCS_ID,
  1133. .mask = DW_XPCS_ID_MASK,
  1134. .compat = nxp_sja1105_xpcs_compat,
  1135. }, {
  1136. .id = NXP_SJA1110_XPCS_ID,
  1137. .mask = DW_XPCS_ID_MASK,
  1138. .compat = nxp_sja1110_xpcs_compat,
  1139. },
  1140. };
  1141. static const struct phylink_pcs_ops xpcs_phylink_ops = {
  1142. .pcs_validate = xpcs_validate,
  1143. .pcs_config = xpcs_config,
  1144. .pcs_get_state = xpcs_get_state,
  1145. .pcs_an_restart = xpcs_an_restart,
  1146. .pcs_link_up = xpcs_link_up,
  1147. };
  1148. static struct dw_xpcs *xpcs_create_data(struct mdio_device *mdiodev)
  1149. {
  1150. struct dw_xpcs *xpcs;
  1151. xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
  1152. if (!xpcs)
  1153. return ERR_PTR(-ENOMEM);
  1154. mdio_device_get(mdiodev);
  1155. xpcs->mdiodev = mdiodev;
  1156. xpcs->pcs.ops = &xpcs_phylink_ops;
  1157. xpcs->pcs.neg_mode = true;
  1158. xpcs->pcs.poll = true;
  1159. return xpcs;
  1160. }
  1161. static void xpcs_free_data(struct dw_xpcs *xpcs)
  1162. {
  1163. mdio_device_put(xpcs->mdiodev);
  1164. kfree(xpcs);
  1165. }
  1166. static int xpcs_init_clks(struct dw_xpcs *xpcs)
  1167. {
  1168. static const char *ids[DW_XPCS_NUM_CLKS] = {
  1169. [DW_XPCS_CORE_CLK] = "core",
  1170. [DW_XPCS_PAD_CLK] = "pad",
  1171. };
  1172. struct device *dev = &xpcs->mdiodev->dev;
  1173. int ret, i;
  1174. for (i = 0; i < DW_XPCS_NUM_CLKS; ++i)
  1175. xpcs->clks[i].id = ids[i];
  1176. ret = clk_bulk_get_optional(dev, DW_XPCS_NUM_CLKS, xpcs->clks);
  1177. if (ret)
  1178. return dev_err_probe(dev, ret, "Failed to get clocks\n");
  1179. ret = clk_bulk_prepare_enable(DW_XPCS_NUM_CLKS, xpcs->clks);
  1180. if (ret)
  1181. return dev_err_probe(dev, ret, "Failed to enable clocks\n");
  1182. return 0;
  1183. }
  1184. static void xpcs_clear_clks(struct dw_xpcs *xpcs)
  1185. {
  1186. clk_bulk_disable_unprepare(DW_XPCS_NUM_CLKS, xpcs->clks);
  1187. clk_bulk_put(DW_XPCS_NUM_CLKS, xpcs->clks);
  1188. }
  1189. static int xpcs_init_id(struct dw_xpcs *xpcs)
  1190. {
  1191. const struct dw_xpcs_info *info;
  1192. int i, ret;
  1193. info = dev_get_platdata(&xpcs->mdiodev->dev);
  1194. if (!info) {
  1195. xpcs->info.pcs = DW_XPCS_ID_NATIVE;
  1196. xpcs->info.pma = DW_XPCS_PMA_ID_NATIVE;
  1197. } else {
  1198. xpcs->info = *info;
  1199. }
  1200. ret = xpcs_get_id(xpcs);
  1201. if (ret < 0)
  1202. return ret;
  1203. for (i = 0; i < ARRAY_SIZE(xpcs_desc_list); i++) {
  1204. const struct dw_xpcs_desc *desc = &xpcs_desc_list[i];
  1205. if ((xpcs->info.pcs & desc->mask) != desc->id)
  1206. continue;
  1207. xpcs->desc = desc;
  1208. break;
  1209. }
  1210. if (!xpcs->desc)
  1211. return -ENODEV;
  1212. return 0;
  1213. }
  1214. static int xpcs_init_iface(struct dw_xpcs *xpcs, phy_interface_t interface)
  1215. {
  1216. const struct dw_xpcs_compat *compat;
  1217. compat = xpcs_find_compat(xpcs->desc, interface);
  1218. if (!compat)
  1219. return -EINVAL;
  1220. if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
  1221. xpcs->pcs.poll = false;
  1222. return 0;
  1223. }
  1224. return xpcs_soft_reset(xpcs, compat);
  1225. }
  1226. static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
  1227. phy_interface_t interface)
  1228. {
  1229. struct dw_xpcs *xpcs;
  1230. int ret;
  1231. xpcs = xpcs_create_data(mdiodev);
  1232. if (IS_ERR(xpcs))
  1233. return xpcs;
  1234. ret = xpcs_init_clks(xpcs);
  1235. if (ret)
  1236. goto out_free_data;
  1237. ret = xpcs_init_id(xpcs);
  1238. if (ret)
  1239. goto out_clear_clks;
  1240. ret = xpcs_init_iface(xpcs, interface);
  1241. if (ret)
  1242. goto out_clear_clks;
  1243. return xpcs;
  1244. out_clear_clks:
  1245. xpcs_clear_clks(xpcs);
  1246. out_free_data:
  1247. xpcs_free_data(xpcs);
  1248. return ERR_PTR(ret);
  1249. }
  1250. /**
  1251. * xpcs_create_mdiodev() - create a DW xPCS instance with the MDIO @addr
  1252. * @bus: pointer to the MDIO-bus descriptor for the device to be looked at
  1253. * @addr: device MDIO-bus ID
  1254. * @interface: requested PHY interface
  1255. *
  1256. * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if
  1257. * the PCS device couldn't be found on the bus and other negative errno related
  1258. * to the data allocation and MDIO-bus communications.
  1259. */
  1260. struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
  1261. phy_interface_t interface)
  1262. {
  1263. struct mdio_device *mdiodev;
  1264. struct dw_xpcs *xpcs;
  1265. mdiodev = mdio_device_create(bus, addr);
  1266. if (IS_ERR(mdiodev))
  1267. return ERR_CAST(mdiodev);
  1268. xpcs = xpcs_create(mdiodev, interface);
  1269. /* xpcs_create() has taken a refcount on the mdiodev if it was
  1270. * successful. If xpcs_create() fails, this will free the mdio
  1271. * device here. In any case, we don't need to hold our reference
  1272. * anymore, and putting it here will allow mdio_device_put() in
  1273. * xpcs_destroy() to automatically free the mdio device.
  1274. */
  1275. mdio_device_put(mdiodev);
  1276. return xpcs;
  1277. }
  1278. EXPORT_SYMBOL_GPL(xpcs_create_mdiodev);
  1279. /**
  1280. * xpcs_create_fwnode() - Create a DW xPCS instance from @fwnode
  1281. * @fwnode: fwnode handle poining to the DW XPCS device
  1282. * @interface: requested PHY interface
  1283. *
  1284. * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if
  1285. * the fwnode device is unavailable or the PCS device couldn't be found on the
  1286. * bus, -EPROBE_DEFER if the respective MDIO-device instance couldn't be found,
  1287. * other negative errno related to the data allocations and MDIO-bus
  1288. * communications.
  1289. */
  1290. struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode,
  1291. phy_interface_t interface)
  1292. {
  1293. struct mdio_device *mdiodev;
  1294. struct dw_xpcs *xpcs;
  1295. if (!fwnode_device_is_available(fwnode))
  1296. return ERR_PTR(-ENODEV);
  1297. mdiodev = fwnode_mdio_find_device(fwnode);
  1298. if (!mdiodev)
  1299. return ERR_PTR(-EPROBE_DEFER);
  1300. xpcs = xpcs_create(mdiodev, interface);
  1301. /* xpcs_create() has taken a refcount on the mdiodev if it was
  1302. * successful. If xpcs_create() fails, this will free the mdio
  1303. * device here. In any case, we don't need to hold our reference
  1304. * anymore, and putting it here will allow mdio_device_put() in
  1305. * xpcs_destroy() to automatically free the mdio device.
  1306. */
  1307. mdio_device_put(mdiodev);
  1308. return xpcs;
  1309. }
  1310. EXPORT_SYMBOL_GPL(xpcs_create_fwnode);
  1311. void xpcs_destroy(struct dw_xpcs *xpcs)
  1312. {
  1313. if (!xpcs)
  1314. return;
  1315. xpcs_clear_clks(xpcs);
  1316. xpcs_free_data(xpcs);
  1317. }
  1318. EXPORT_SYMBOL_GPL(xpcs_destroy);
  1319. MODULE_DESCRIPTION("Synopsys DesignWare XPCS library");
  1320. MODULE_LICENSE("GPL v2");