mcdi_port.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. /****************************************************************************
  2. * Driver for Solarflare network controllers and boards
  3. * Copyright 2009-2013 Solarflare Communications Inc.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 as published
  7. * by the Free Software Foundation, incorporated herein by reference.
  8. */
  9. /*
  10. * Driver for PHY related operations via MCDI.
  11. */
  12. #include <linux/slab.h>
  13. #include "efx.h"
  14. #include "mcdi.h"
  15. #include "mcdi_pcol.h"
  16. #include "nic.h"
  17. #include "selftest.h"
  18. struct efx_mcdi_phy_data {
  19. u32 flags;
  20. u32 type;
  21. u32 supported_cap;
  22. u32 channel;
  23. u32 port;
  24. u32 stats_mask;
  25. u8 name[20];
  26. u32 media;
  27. u32 mmd_mask;
  28. u8 revision[20];
  29. u32 forced_cap;
  30. };
  31. static int
  32. efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
  33. {
  34. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN);
  35. size_t outlen;
  36. int rc;
  37. BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_IN_LEN != 0);
  38. BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_OUT_NAME_LEN != sizeof(cfg->name));
  39. rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0,
  40. outbuf, sizeof(outbuf), &outlen);
  41. if (rc)
  42. goto fail;
  43. if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) {
  44. rc = -EIO;
  45. goto fail;
  46. }
  47. cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS);
  48. cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE);
  49. cfg->supported_cap =
  50. MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
  51. cfg->channel = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_CHANNEL);
  52. cfg->port = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_PRT);
  53. cfg->stats_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_STATS_MASK);
  54. memcpy(cfg->name, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_NAME),
  55. sizeof(cfg->name));
  56. cfg->media = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MEDIA_TYPE);
  57. cfg->mmd_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MMD_MASK);
  58. memcpy(cfg->revision, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_REVISION),
  59. sizeof(cfg->revision));
  60. return 0;
  61. fail:
  62. netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
  63. return rc;
  64. }
  65. static int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
  66. u32 flags, u32 loopback_mode,
  67. u32 loopback_speed)
  68. {
  69. MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN);
  70. int rc;
  71. BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0);
  72. MCDI_SET_DWORD(inbuf, SET_LINK_IN_CAP, capabilities);
  73. MCDI_SET_DWORD(inbuf, SET_LINK_IN_FLAGS, flags);
  74. MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_MODE, loopback_mode);
  75. MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_SPEED, loopback_speed);
  76. rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
  77. NULL, 0, NULL);
  78. return rc;
  79. }
  80. static int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
  81. {
  82. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN);
  83. size_t outlen;
  84. int rc;
  85. rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0,
  86. outbuf, sizeof(outbuf), &outlen);
  87. if (rc)
  88. goto fail;
  89. if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
  90. MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) {
  91. rc = -EIO;
  92. goto fail;
  93. }
  94. *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED);
  95. return 0;
  96. fail:
  97. netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
  98. return rc;
  99. }
  100. static int efx_mcdi_mdio_read(struct net_device *net_dev,
  101. int prtad, int devad, u16 addr)
  102. {
  103. struct efx_nic *efx = netdev_priv(net_dev);
  104. MCDI_DECLARE_BUF(inbuf, MC_CMD_MDIO_READ_IN_LEN);
  105. MCDI_DECLARE_BUF(outbuf, MC_CMD_MDIO_READ_OUT_LEN);
  106. size_t outlen;
  107. int rc;
  108. MCDI_SET_DWORD(inbuf, MDIO_READ_IN_BUS, efx->mdio_bus);
  109. MCDI_SET_DWORD(inbuf, MDIO_READ_IN_PRTAD, prtad);
  110. MCDI_SET_DWORD(inbuf, MDIO_READ_IN_DEVAD, devad);
  111. MCDI_SET_DWORD(inbuf, MDIO_READ_IN_ADDR, addr);
  112. rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf),
  113. outbuf, sizeof(outbuf), &outlen);
  114. if (rc)
  115. return rc;
  116. if (MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS) !=
  117. MC_CMD_MDIO_STATUS_GOOD)
  118. return -EIO;
  119. return (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE);
  120. }
  121. static int efx_mcdi_mdio_write(struct net_device *net_dev,
  122. int prtad, int devad, u16 addr, u16 value)
  123. {
  124. struct efx_nic *efx = netdev_priv(net_dev);
  125. MCDI_DECLARE_BUF(inbuf, MC_CMD_MDIO_WRITE_IN_LEN);
  126. MCDI_DECLARE_BUF(outbuf, MC_CMD_MDIO_WRITE_OUT_LEN);
  127. size_t outlen;
  128. int rc;
  129. MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_BUS, efx->mdio_bus);
  130. MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_PRTAD, prtad);
  131. MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_DEVAD, devad);
  132. MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_ADDR, addr);
  133. MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_VALUE, value);
  134. rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf),
  135. outbuf, sizeof(outbuf), &outlen);
  136. if (rc)
  137. return rc;
  138. if (MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS) !=
  139. MC_CMD_MDIO_STATUS_GOOD)
  140. return -EIO;
  141. return 0;
  142. }
  143. static void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset)
  144. {
  145. #define SET_BIT(name) __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
  146. linkset)
  147. bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS);
  148. switch (media) {
  149. case MC_CMD_MEDIA_KX4:
  150. SET_BIT(Backplane);
  151. if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
  152. SET_BIT(1000baseKX_Full);
  153. if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
  154. SET_BIT(10000baseKX4_Full);
  155. if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
  156. SET_BIT(40000baseKR4_Full);
  157. break;
  158. case MC_CMD_MEDIA_XFP:
  159. case MC_CMD_MEDIA_SFP_PLUS:
  160. case MC_CMD_MEDIA_QSFP_PLUS:
  161. SET_BIT(FIBRE);
  162. if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
  163. SET_BIT(1000baseT_Full);
  164. if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
  165. SET_BIT(10000baseT_Full);
  166. if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
  167. SET_BIT(40000baseCR4_Full);
  168. if (cap & (1 << MC_CMD_PHY_CAP_100000FDX_LBN))
  169. SET_BIT(100000baseCR4_Full);
  170. if (cap & (1 << MC_CMD_PHY_CAP_25000FDX_LBN))
  171. SET_BIT(25000baseCR_Full);
  172. if (cap & (1 << MC_CMD_PHY_CAP_50000FDX_LBN))
  173. SET_BIT(50000baseCR2_Full);
  174. break;
  175. case MC_CMD_MEDIA_BASE_T:
  176. SET_BIT(TP);
  177. if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
  178. SET_BIT(10baseT_Half);
  179. if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
  180. SET_BIT(10baseT_Full);
  181. if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
  182. SET_BIT(100baseT_Half);
  183. if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
  184. SET_BIT(100baseT_Full);
  185. if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
  186. SET_BIT(1000baseT_Half);
  187. if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
  188. SET_BIT(1000baseT_Full);
  189. if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
  190. SET_BIT(10000baseT_Full);
  191. break;
  192. }
  193. if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
  194. SET_BIT(Pause);
  195. if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
  196. SET_BIT(Asym_Pause);
  197. if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
  198. SET_BIT(Autoneg);
  199. #undef SET_BIT
  200. }
  201. static u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset)
  202. {
  203. u32 result = 0;
  204. #define TEST_BIT(name) test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
  205. linkset)
  206. if (TEST_BIT(10baseT_Half))
  207. result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN);
  208. if (TEST_BIT(10baseT_Full))
  209. result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN);
  210. if (TEST_BIT(100baseT_Half))
  211. result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN);
  212. if (TEST_BIT(100baseT_Full))
  213. result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN);
  214. if (TEST_BIT(1000baseT_Half))
  215. result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN);
  216. if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full))
  217. result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
  218. if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full))
  219. result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
  220. if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full))
  221. result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN);
  222. if (TEST_BIT(100000baseCR4_Full))
  223. result |= (1 << MC_CMD_PHY_CAP_100000FDX_LBN);
  224. if (TEST_BIT(25000baseCR_Full))
  225. result |= (1 << MC_CMD_PHY_CAP_25000FDX_LBN);
  226. if (TEST_BIT(50000baseCR2_Full))
  227. result |= (1 << MC_CMD_PHY_CAP_50000FDX_LBN);
  228. if (TEST_BIT(Pause))
  229. result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
  230. if (TEST_BIT(Asym_Pause))
  231. result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN);
  232. if (TEST_BIT(Autoneg))
  233. result |= (1 << MC_CMD_PHY_CAP_AN_LBN);
  234. #undef TEST_BIT
  235. return result;
  236. }
  237. static u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
  238. {
  239. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  240. enum efx_phy_mode mode, supported;
  241. u32 flags;
  242. /* TODO: Advertise the capabilities supported by this PHY */
  243. supported = 0;
  244. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN))
  245. supported |= PHY_MODE_TX_DISABLED;
  246. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN))
  247. supported |= PHY_MODE_LOW_POWER;
  248. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN))
  249. supported |= PHY_MODE_OFF;
  250. mode = efx->phy_mode & supported;
  251. flags = 0;
  252. if (mode & PHY_MODE_TX_DISABLED)
  253. flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN);
  254. if (mode & PHY_MODE_LOW_POWER)
  255. flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN);
  256. if (mode & PHY_MODE_OFF)
  257. flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN);
  258. return flags;
  259. }
  260. static u8 mcdi_to_ethtool_media(u32 media)
  261. {
  262. switch (media) {
  263. case MC_CMD_MEDIA_XAUI:
  264. case MC_CMD_MEDIA_CX4:
  265. case MC_CMD_MEDIA_KX4:
  266. return PORT_OTHER;
  267. case MC_CMD_MEDIA_XFP:
  268. case MC_CMD_MEDIA_SFP_PLUS:
  269. case MC_CMD_MEDIA_QSFP_PLUS:
  270. return PORT_FIBRE;
  271. case MC_CMD_MEDIA_BASE_T:
  272. return PORT_TP;
  273. default:
  274. return PORT_OTHER;
  275. }
  276. }
  277. static void efx_mcdi_phy_decode_link(struct efx_nic *efx,
  278. struct efx_link_state *link_state,
  279. u32 speed, u32 flags, u32 fcntl)
  280. {
  281. switch (fcntl) {
  282. case MC_CMD_FCNTL_AUTO:
  283. WARN_ON(1); /* This is not a link mode */
  284. link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX;
  285. break;
  286. case MC_CMD_FCNTL_BIDIR:
  287. link_state->fc = EFX_FC_TX | EFX_FC_RX;
  288. break;
  289. case MC_CMD_FCNTL_RESPOND:
  290. link_state->fc = EFX_FC_RX;
  291. break;
  292. default:
  293. WARN_ON(1);
  294. case MC_CMD_FCNTL_OFF:
  295. link_state->fc = 0;
  296. break;
  297. }
  298. link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
  299. link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
  300. link_state->speed = speed;
  301. }
  302. /* The semantics of the ethtool FEC mode bitmask are not well defined,
  303. * particularly the meaning of combinations of bits. Which means we get to
  304. * define our own semantics, as follows:
  305. * OFF overrides any other bits, and means "disable all FEC" (with the
  306. * exception of 25G KR4/CR4, where it is not possible to reject it if AN
  307. * partner requests it).
  308. * AUTO on its own means use cable requirements and link partner autoneg with
  309. * fw-default preferences for the cable type.
  310. * AUTO and either RS or BASER means use the specified FEC type if cable and
  311. * link partner support it, otherwise autoneg/fw-default.
  312. * RS or BASER alone means use the specified FEC type if cable and link partner
  313. * support it and either requests it, otherwise no FEC.
  314. * Both RS and BASER (whether AUTO or not) means use FEC if cable and link
  315. * partner support it, preferring RS to BASER.
  316. */
  317. static u32 ethtool_fec_caps_to_mcdi(u32 ethtool_cap)
  318. {
  319. u32 ret = 0;
  320. if (ethtool_cap & ETHTOOL_FEC_OFF)
  321. return 0;
  322. if (ethtool_cap & ETHTOOL_FEC_AUTO)
  323. ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
  324. (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
  325. (1 << MC_CMD_PHY_CAP_RS_FEC_LBN);
  326. if (ethtool_cap & ETHTOOL_FEC_RS)
  327. ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) |
  328. (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN);
  329. if (ethtool_cap & ETHTOOL_FEC_BASER)
  330. ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
  331. (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
  332. (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN) |
  333. (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN);
  334. return ret;
  335. }
  336. /* Invert ethtool_fec_caps_to_mcdi. There are two combinations that function
  337. * can never produce, (baser xor rs) and neither req; the implementation below
  338. * maps both of those to AUTO. This should never matter, and it's not clear
  339. * what a better mapping would be anyway.
  340. */
  341. static u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g)
  342. {
  343. bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN),
  344. rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN),
  345. baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN)
  346. : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN),
  347. baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN)
  348. : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
  349. if (!baser && !rs)
  350. return ETHTOOL_FEC_OFF;
  351. return (rs_req ? ETHTOOL_FEC_RS : 0) |
  352. (baser_req ? ETHTOOL_FEC_BASER : 0) |
  353. (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO);
  354. }
  355. static int efx_mcdi_phy_probe(struct efx_nic *efx)
  356. {
  357. struct efx_mcdi_phy_data *phy_data;
  358. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
  359. u32 caps;
  360. int rc;
  361. /* Initialise and populate phy_data */
  362. phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
  363. if (phy_data == NULL)
  364. return -ENOMEM;
  365. rc = efx_mcdi_get_phy_cfg(efx, phy_data);
  366. if (rc != 0)
  367. goto fail;
  368. /* Read initial link advertisement */
  369. BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
  370. rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
  371. outbuf, sizeof(outbuf), NULL);
  372. if (rc)
  373. goto fail;
  374. /* Fill out nic state */
  375. efx->phy_data = phy_data;
  376. efx->phy_type = phy_data->type;
  377. efx->mdio_bus = phy_data->channel;
  378. efx->mdio.prtad = phy_data->port;
  379. efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
  380. efx->mdio.mode_support = 0;
  381. if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
  382. efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
  383. if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
  384. efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
  385. caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
  386. if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
  387. mcdi_to_ethtool_linkset(phy_data->media, caps,
  388. efx->link_advertising);
  389. else
  390. phy_data->forced_cap = caps;
  391. /* Assert that we can map efx -> mcdi loopback modes */
  392. BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE);
  393. BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA);
  394. BUILD_BUG_ON(LOOPBACK_GMAC != MC_CMD_LOOPBACK_GMAC);
  395. BUILD_BUG_ON(LOOPBACK_XGMII != MC_CMD_LOOPBACK_XGMII);
  396. BUILD_BUG_ON(LOOPBACK_XGXS != MC_CMD_LOOPBACK_XGXS);
  397. BUILD_BUG_ON(LOOPBACK_XAUI != MC_CMD_LOOPBACK_XAUI);
  398. BUILD_BUG_ON(LOOPBACK_GMII != MC_CMD_LOOPBACK_GMII);
  399. BUILD_BUG_ON(LOOPBACK_SGMII != MC_CMD_LOOPBACK_SGMII);
  400. BUILD_BUG_ON(LOOPBACK_XGBR != MC_CMD_LOOPBACK_XGBR);
  401. BUILD_BUG_ON(LOOPBACK_XFI != MC_CMD_LOOPBACK_XFI);
  402. BUILD_BUG_ON(LOOPBACK_XAUI_FAR != MC_CMD_LOOPBACK_XAUI_FAR);
  403. BUILD_BUG_ON(LOOPBACK_GMII_FAR != MC_CMD_LOOPBACK_GMII_FAR);
  404. BUILD_BUG_ON(LOOPBACK_SGMII_FAR != MC_CMD_LOOPBACK_SGMII_FAR);
  405. BUILD_BUG_ON(LOOPBACK_XFI_FAR != MC_CMD_LOOPBACK_XFI_FAR);
  406. BUILD_BUG_ON(LOOPBACK_GPHY != MC_CMD_LOOPBACK_GPHY);
  407. BUILD_BUG_ON(LOOPBACK_PHYXS != MC_CMD_LOOPBACK_PHYXS);
  408. BUILD_BUG_ON(LOOPBACK_PCS != MC_CMD_LOOPBACK_PCS);
  409. BUILD_BUG_ON(LOOPBACK_PMAPMD != MC_CMD_LOOPBACK_PMAPMD);
  410. BUILD_BUG_ON(LOOPBACK_XPORT != MC_CMD_LOOPBACK_XPORT);
  411. BUILD_BUG_ON(LOOPBACK_XGMII_WS != MC_CMD_LOOPBACK_XGMII_WS);
  412. BUILD_BUG_ON(LOOPBACK_XAUI_WS != MC_CMD_LOOPBACK_XAUI_WS);
  413. BUILD_BUG_ON(LOOPBACK_XAUI_WS_FAR != MC_CMD_LOOPBACK_XAUI_WS_FAR);
  414. BUILD_BUG_ON(LOOPBACK_XAUI_WS_NEAR != MC_CMD_LOOPBACK_XAUI_WS_NEAR);
  415. BUILD_BUG_ON(LOOPBACK_GMII_WS != MC_CMD_LOOPBACK_GMII_WS);
  416. BUILD_BUG_ON(LOOPBACK_XFI_WS != MC_CMD_LOOPBACK_XFI_WS);
  417. BUILD_BUG_ON(LOOPBACK_XFI_WS_FAR != MC_CMD_LOOPBACK_XFI_WS_FAR);
  418. BUILD_BUG_ON(LOOPBACK_PHYXS_WS != MC_CMD_LOOPBACK_PHYXS_WS);
  419. rc = efx_mcdi_loopback_modes(efx, &efx->loopback_modes);
  420. if (rc != 0)
  421. goto fail;
  422. /* The MC indicates that LOOPBACK_NONE is a valid loopback mode,
  423. * but by convention we don't */
  424. efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
  425. /* Set the initial link mode */
  426. efx_mcdi_phy_decode_link(
  427. efx, &efx->link_state,
  428. MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
  429. MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
  430. MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
  431. /* Record the initial FEC configuration (or nearest approximation
  432. * representable in the ethtool configuration space)
  433. */
  434. efx->fec_config = mcdi_fec_caps_to_ethtool(caps,
  435. efx->link_state.speed == 25000 ||
  436. efx->link_state.speed == 50000);
  437. /* Default to Autonegotiated flow control if the PHY supports it */
  438. efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
  439. if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
  440. efx->wanted_fc |= EFX_FC_AUTO;
  441. efx_link_set_wanted_fc(efx, efx->wanted_fc);
  442. return 0;
  443. fail:
  444. kfree(phy_data);
  445. return rc;
  446. }
  447. int efx_mcdi_port_reconfigure(struct efx_nic *efx)
  448. {
  449. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  450. u32 caps = (efx->link_advertising[0] ?
  451. ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
  452. phy_cfg->forced_cap);
  453. caps |= ethtool_fec_caps_to_mcdi(efx->fec_config);
  454. return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
  455. efx->loopback_mode, 0);
  456. }
  457. /* Verify that the forced flow control settings (!EFX_FC_AUTO) are
  458. * supported by the link partner. Warn the user if this isn't the case
  459. */
  460. static void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
  461. {
  462. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  463. u32 rmtadv;
  464. /* The link partner capabilities are only relevant if the
  465. * link supports flow control autonegotiation */
  466. if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
  467. return;
  468. /* If flow control autoneg is supported and enabled, then fine */
  469. if (efx->wanted_fc & EFX_FC_AUTO)
  470. return;
  471. rmtadv = 0;
  472. if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
  473. rmtadv |= ADVERTISED_Pause;
  474. if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
  475. rmtadv |= ADVERTISED_Asym_Pause;
  476. if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause)
  477. netif_err(efx, link, efx->net_dev,
  478. "warning: link partner doesn't support pause frames");
  479. }
  480. static bool efx_mcdi_phy_poll(struct efx_nic *efx)
  481. {
  482. struct efx_link_state old_state = efx->link_state;
  483. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
  484. int rc;
  485. WARN_ON(!mutex_is_locked(&efx->mac_lock));
  486. BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
  487. rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
  488. outbuf, sizeof(outbuf), NULL);
  489. if (rc)
  490. efx->link_state.up = false;
  491. else
  492. efx_mcdi_phy_decode_link(
  493. efx, &efx->link_state,
  494. MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
  495. MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
  496. MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
  497. return !efx_link_state_equal(&efx->link_state, &old_state);
  498. }
  499. static void efx_mcdi_phy_remove(struct efx_nic *efx)
  500. {
  501. struct efx_mcdi_phy_data *phy_data = efx->phy_data;
  502. efx->phy_data = NULL;
  503. kfree(phy_data);
  504. }
  505. static void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx,
  506. struct ethtool_link_ksettings *cmd)
  507. {
  508. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  509. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
  510. int rc;
  511. cmd->base.speed = efx->link_state.speed;
  512. cmd->base.duplex = efx->link_state.fd;
  513. cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
  514. cmd->base.phy_address = phy_cfg->port;
  515. cmd->base.autoneg = !!(efx->link_advertising[0] & ADVERTISED_Autoneg);
  516. cmd->base.mdio_support = (efx->mdio.mode_support &
  517. (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
  518. mcdi_to_ethtool_linkset(phy_cfg->media, phy_cfg->supported_cap,
  519. cmd->link_modes.supported);
  520. memcpy(cmd->link_modes.advertising, efx->link_advertising,
  521. sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
  522. BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
  523. rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
  524. outbuf, sizeof(outbuf), NULL);
  525. if (rc)
  526. return;
  527. mcdi_to_ethtool_linkset(phy_cfg->media,
  528. MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP),
  529. cmd->link_modes.lp_advertising);
  530. }
  531. static int
  532. efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx,
  533. const struct ethtool_link_ksettings *cmd)
  534. {
  535. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  536. u32 caps;
  537. int rc;
  538. if (cmd->base.autoneg) {
  539. caps = (ethtool_linkset_to_mcdi_cap(cmd->link_modes.advertising) |
  540. 1 << MC_CMD_PHY_CAP_AN_LBN);
  541. } else if (cmd->base.duplex) {
  542. switch (cmd->base.speed) {
  543. case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break;
  544. case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break;
  545. case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break;
  546. case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break;
  547. case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break;
  548. case 100000: caps = 1 << MC_CMD_PHY_CAP_100000FDX_LBN; break;
  549. case 25000: caps = 1 << MC_CMD_PHY_CAP_25000FDX_LBN; break;
  550. case 50000: caps = 1 << MC_CMD_PHY_CAP_50000FDX_LBN; break;
  551. default: return -EINVAL;
  552. }
  553. } else {
  554. switch (cmd->base.speed) {
  555. case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break;
  556. case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break;
  557. case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break;
  558. default: return -EINVAL;
  559. }
  560. }
  561. caps |= ethtool_fec_caps_to_mcdi(efx->fec_config);
  562. rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
  563. efx->loopback_mode, 0);
  564. if (rc)
  565. return rc;
  566. if (cmd->base.autoneg) {
  567. efx_link_set_advertising(efx, cmd->link_modes.advertising);
  568. phy_cfg->forced_cap = 0;
  569. } else {
  570. efx_link_clear_advertising(efx);
  571. phy_cfg->forced_cap = caps;
  572. }
  573. return 0;
  574. }
  575. static int efx_mcdi_phy_get_fecparam(struct efx_nic *efx,
  576. struct ethtool_fecparam *fec)
  577. {
  578. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN);
  579. u32 caps, active, speed; /* MCDI format */
  580. bool is_25g = false;
  581. size_t outlen;
  582. int rc;
  583. BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
  584. rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
  585. outbuf, sizeof(outbuf), &outlen);
  586. if (rc)
  587. return rc;
  588. if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN)
  589. return -EOPNOTSUPP;
  590. /* behaviour for 25G/50G links depends on 25G BASER bit */
  591. speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED);
  592. is_25g = speed == 25000 || speed == 50000;
  593. caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP);
  594. fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g);
  595. /* BASER is never supported on 100G */
  596. if (speed == 100000)
  597. fec->fec &= ~ETHTOOL_FEC_BASER;
  598. active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE);
  599. switch (active) {
  600. case MC_CMD_FEC_NONE:
  601. fec->active_fec = ETHTOOL_FEC_OFF;
  602. break;
  603. case MC_CMD_FEC_BASER:
  604. fec->active_fec = ETHTOOL_FEC_BASER;
  605. break;
  606. case MC_CMD_FEC_RS:
  607. fec->active_fec = ETHTOOL_FEC_RS;
  608. break;
  609. default:
  610. netif_warn(efx, hw, efx->net_dev,
  611. "Firmware reports unrecognised FEC_TYPE %u\n",
  612. active);
  613. /* We don't know what firmware has picked. AUTO is as good a
  614. * "can't happen" value as any other.
  615. */
  616. fec->active_fec = ETHTOOL_FEC_AUTO;
  617. break;
  618. }
  619. return 0;
  620. }
  621. static int efx_mcdi_phy_set_fecparam(struct efx_nic *efx,
  622. const struct ethtool_fecparam *fec)
  623. {
  624. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  625. u32 caps;
  626. int rc;
  627. /* Work out what efx_mcdi_phy_set_link_ksettings() would produce from
  628. * saved advertising bits
  629. */
  630. if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, efx->link_advertising))
  631. caps = (ethtool_linkset_to_mcdi_cap(efx->link_advertising) |
  632. 1 << MC_CMD_PHY_CAP_AN_LBN);
  633. else
  634. caps = phy_cfg->forced_cap;
  635. caps |= ethtool_fec_caps_to_mcdi(fec->fec);
  636. rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
  637. efx->loopback_mode, 0);
  638. if (rc)
  639. return rc;
  640. /* Record the new FEC setting for subsequent set_link calls */
  641. efx->fec_config = fec->fec;
  642. return 0;
  643. }
  644. static int efx_mcdi_phy_test_alive(struct efx_nic *efx)
  645. {
  646. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
  647. size_t outlen;
  648. int rc;
  649. BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
  650. rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
  651. outbuf, sizeof(outbuf), &outlen);
  652. if (rc)
  653. return rc;
  654. if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
  655. return -EIO;
  656. if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK)
  657. return -EINVAL;
  658. return 0;
  659. }
  660. static const char *const mcdi_sft9001_cable_diag_names[] = {
  661. "cable.pairA.length",
  662. "cable.pairB.length",
  663. "cable.pairC.length",
  664. "cable.pairD.length",
  665. "cable.pairA.status",
  666. "cable.pairB.status",
  667. "cable.pairC.status",
  668. "cable.pairD.status",
  669. };
  670. static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
  671. int *results)
  672. {
  673. unsigned int retry, i, count = 0;
  674. size_t outlen;
  675. u32 status;
  676. MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
  677. MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_SFT9001_LEN);
  678. u8 *ptr;
  679. int rc;
  680. BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0);
  681. MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_mode);
  682. rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST,
  683. inbuf, MC_CMD_START_BIST_IN_LEN, NULL, 0, NULL);
  684. if (rc)
  685. goto out;
  686. /* Wait up to 10s for BIST to finish */
  687. for (retry = 0; retry < 100; ++retry) {
  688. BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0);
  689. rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
  690. outbuf, sizeof(outbuf), &outlen);
  691. if (rc)
  692. goto out;
  693. status = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
  694. if (status != MC_CMD_POLL_BIST_RUNNING)
  695. goto finished;
  696. msleep(100);
  697. }
  698. rc = -ETIMEDOUT;
  699. goto out;
  700. finished:
  701. results[count++] = (status == MC_CMD_POLL_BIST_PASSED) ? 1 : -1;
  702. /* SFT9001 specific cable diagnostics output */
  703. if (efx->phy_type == PHY_TYPE_SFT9001B &&
  704. (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT ||
  705. bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) {
  706. ptr = MCDI_PTR(outbuf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
  707. if (status == MC_CMD_POLL_BIST_PASSED &&
  708. outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) {
  709. for (i = 0; i < 8; i++) {
  710. results[count + i] =
  711. EFX_DWORD_FIELD(((efx_dword_t *)ptr)[i],
  712. EFX_DWORD_0);
  713. }
  714. }
  715. count += 8;
  716. }
  717. rc = count;
  718. out:
  719. return rc;
  720. }
  721. static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results,
  722. unsigned flags)
  723. {
  724. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  725. u32 mode;
  726. int rc;
  727. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
  728. rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results);
  729. if (rc < 0)
  730. return rc;
  731. results += rc;
  732. }
  733. /* If we support both LONG and SHORT, then run each in response to
  734. * break or not. Otherwise, run the one we support */
  735. mode = 0;
  736. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) {
  737. if ((flags & ETH_TEST_FL_OFFLINE) &&
  738. (phy_cfg->flags &
  739. (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)))
  740. mode = MC_CMD_PHY_BIST_CABLE_LONG;
  741. else
  742. mode = MC_CMD_PHY_BIST_CABLE_SHORT;
  743. } else if (phy_cfg->flags &
  744. (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))
  745. mode = MC_CMD_PHY_BIST_CABLE_LONG;
  746. if (mode != 0) {
  747. rc = efx_mcdi_bist(efx, mode, results);
  748. if (rc < 0)
  749. return rc;
  750. results += rc;
  751. }
  752. return 0;
  753. }
  754. static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
  755. unsigned int index)
  756. {
  757. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  758. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
  759. if (index == 0)
  760. return "bist";
  761. --index;
  762. }
  763. if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) |
  764. (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) {
  765. if (index == 0)
  766. return "cable";
  767. --index;
  768. if (efx->phy_type == PHY_TYPE_SFT9001B) {
  769. if (index < ARRAY_SIZE(mcdi_sft9001_cable_diag_names))
  770. return mcdi_sft9001_cable_diag_names[index];
  771. index -= ARRAY_SIZE(mcdi_sft9001_cable_diag_names);
  772. }
  773. }
  774. return NULL;
  775. }
  776. #define SFP_PAGE_SIZE 128
  777. #define SFF_DIAG_TYPE_OFFSET 92
  778. #define SFF_DIAG_ADDR_CHANGE BIT(2)
  779. #define SFF_8079_NUM_PAGES 2
  780. #define SFF_8472_NUM_PAGES 4
  781. #define SFF_8436_NUM_PAGES 5
  782. #define SFF_DMT_LEVEL_OFFSET 94
  783. /** efx_mcdi_phy_get_module_eeprom_page() - Get a single page of module eeprom
  784. * @efx: NIC context
  785. * @page: EEPROM page number
  786. * @data: Destination data pointer
  787. * @offset: Offset in page to copy from in to data
  788. * @space: Space available in data
  789. *
  790. * Return:
  791. * >=0 - amount of data copied
  792. * <0 - error
  793. */
  794. static int efx_mcdi_phy_get_module_eeprom_page(struct efx_nic *efx,
  795. unsigned int page,
  796. u8 *data, ssize_t offset,
  797. ssize_t space)
  798. {
  799. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX);
  800. MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN);
  801. size_t outlen;
  802. unsigned int payload_len;
  803. unsigned int to_copy;
  804. int rc;
  805. if (offset > SFP_PAGE_SIZE)
  806. return -EINVAL;
  807. to_copy = min(space, SFP_PAGE_SIZE - offset);
  808. MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page);
  809. rc = efx_mcdi_rpc_quiet(efx, MC_CMD_GET_PHY_MEDIA_INFO,
  810. inbuf, sizeof(inbuf),
  811. outbuf, sizeof(outbuf),
  812. &outlen);
  813. if (rc)
  814. return rc;
  815. if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST +
  816. SFP_PAGE_SIZE))
  817. return -EIO;
  818. payload_len = MCDI_DWORD(outbuf, GET_PHY_MEDIA_INFO_OUT_DATALEN);
  819. if (payload_len != SFP_PAGE_SIZE)
  820. return -EIO;
  821. memcpy(data, MCDI_PTR(outbuf, GET_PHY_MEDIA_INFO_OUT_DATA) + offset,
  822. to_copy);
  823. return to_copy;
  824. }
  825. static int efx_mcdi_phy_get_module_eeprom_byte(struct efx_nic *efx,
  826. unsigned int page,
  827. u8 byte)
  828. {
  829. int rc;
  830. u8 data;
  831. rc = efx_mcdi_phy_get_module_eeprom_page(efx, page, &data, byte, 1);
  832. if (rc == 1)
  833. return data;
  834. return rc;
  835. }
  836. static int efx_mcdi_phy_diag_type(struct efx_nic *efx)
  837. {
  838. /* Page zero of the EEPROM includes the diagnostic type at byte 92. */
  839. return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
  840. SFF_DIAG_TYPE_OFFSET);
  841. }
  842. static int efx_mcdi_phy_sff_8472_level(struct efx_nic *efx)
  843. {
  844. /* Page zero of the EEPROM includes the DMT level at byte 94. */
  845. return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
  846. SFF_DMT_LEVEL_OFFSET);
  847. }
  848. static u32 efx_mcdi_phy_module_type(struct efx_nic *efx)
  849. {
  850. struct efx_mcdi_phy_data *phy_data = efx->phy_data;
  851. if (phy_data->media != MC_CMD_MEDIA_QSFP_PLUS)
  852. return phy_data->media;
  853. /* A QSFP+ NIC may actually have an SFP+ module attached.
  854. * The ID is page 0, byte 0.
  855. */
  856. switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) {
  857. case 0x3:
  858. return MC_CMD_MEDIA_SFP_PLUS;
  859. case 0xc:
  860. case 0xd:
  861. return MC_CMD_MEDIA_QSFP_PLUS;
  862. default:
  863. return 0;
  864. }
  865. }
  866. static int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx,
  867. struct ethtool_eeprom *ee, u8 *data)
  868. {
  869. int rc;
  870. ssize_t space_remaining = ee->len;
  871. unsigned int page_off;
  872. bool ignore_missing;
  873. int num_pages;
  874. int page;
  875. switch (efx_mcdi_phy_module_type(efx)) {
  876. case MC_CMD_MEDIA_SFP_PLUS:
  877. num_pages = efx_mcdi_phy_sff_8472_level(efx) > 0 ?
  878. SFF_8472_NUM_PAGES : SFF_8079_NUM_PAGES;
  879. page = 0;
  880. ignore_missing = false;
  881. break;
  882. case MC_CMD_MEDIA_QSFP_PLUS:
  883. num_pages = SFF_8436_NUM_PAGES;
  884. page = -1; /* We obtain the lower page by asking for -1. */
  885. ignore_missing = true; /* Ignore missing pages after page 0. */
  886. break;
  887. default:
  888. return -EOPNOTSUPP;
  889. }
  890. page_off = ee->offset % SFP_PAGE_SIZE;
  891. page += ee->offset / SFP_PAGE_SIZE;
  892. while (space_remaining && (page < num_pages)) {
  893. rc = efx_mcdi_phy_get_module_eeprom_page(efx, page,
  894. data, page_off,
  895. space_remaining);
  896. if (rc > 0) {
  897. space_remaining -= rc;
  898. data += rc;
  899. page_off = 0;
  900. page++;
  901. } else if (rc == 0) {
  902. space_remaining = 0;
  903. } else if (ignore_missing && (page > 0)) {
  904. int intended_size = SFP_PAGE_SIZE - page_off;
  905. space_remaining -= intended_size;
  906. if (space_remaining < 0) {
  907. space_remaining = 0;
  908. } else {
  909. memset(data, 0, intended_size);
  910. data += intended_size;
  911. page_off = 0;
  912. page++;
  913. rc = 0;
  914. }
  915. } else {
  916. return rc;
  917. }
  918. }
  919. return 0;
  920. }
  921. static int efx_mcdi_phy_get_module_info(struct efx_nic *efx,
  922. struct ethtool_modinfo *modinfo)
  923. {
  924. int sff_8472_level;
  925. int diag_type;
  926. switch (efx_mcdi_phy_module_type(efx)) {
  927. case MC_CMD_MEDIA_SFP_PLUS:
  928. sff_8472_level = efx_mcdi_phy_sff_8472_level(efx);
  929. /* If we can't read the diagnostics level we have none. */
  930. if (sff_8472_level < 0)
  931. return -EOPNOTSUPP;
  932. /* Check if this module requires the (unsupported) address
  933. * change operation.
  934. */
  935. diag_type = efx_mcdi_phy_diag_type(efx);
  936. if ((sff_8472_level == 0) ||
  937. (diag_type & SFF_DIAG_ADDR_CHANGE)) {
  938. modinfo->type = ETH_MODULE_SFF_8079;
  939. modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
  940. } else {
  941. modinfo->type = ETH_MODULE_SFF_8472;
  942. modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
  943. }
  944. break;
  945. case MC_CMD_MEDIA_QSFP_PLUS:
  946. modinfo->type = ETH_MODULE_SFF_8436;
  947. modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
  948. break;
  949. default:
  950. return -EOPNOTSUPP;
  951. }
  952. return 0;
  953. }
  954. static const struct efx_phy_operations efx_mcdi_phy_ops = {
  955. .probe = efx_mcdi_phy_probe,
  956. .init = efx_port_dummy_op_int,
  957. .reconfigure = efx_mcdi_port_reconfigure,
  958. .poll = efx_mcdi_phy_poll,
  959. .fini = efx_port_dummy_op_void,
  960. .remove = efx_mcdi_phy_remove,
  961. .get_link_ksettings = efx_mcdi_phy_get_link_ksettings,
  962. .set_link_ksettings = efx_mcdi_phy_set_link_ksettings,
  963. .get_fecparam = efx_mcdi_phy_get_fecparam,
  964. .set_fecparam = efx_mcdi_phy_set_fecparam,
  965. .test_alive = efx_mcdi_phy_test_alive,
  966. .run_tests = efx_mcdi_phy_run_tests,
  967. .test_name = efx_mcdi_phy_test_name,
  968. .get_module_eeprom = efx_mcdi_phy_get_module_eeprom,
  969. .get_module_info = efx_mcdi_phy_get_module_info,
  970. };
  971. u32 efx_mcdi_phy_get_caps(struct efx_nic *efx)
  972. {
  973. struct efx_mcdi_phy_data *phy_data = efx->phy_data;
  974. return phy_data->supported_cap;
  975. }
  976. static unsigned int efx_mcdi_event_link_speed[] = {
  977. [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
  978. [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
  979. [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
  980. [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
  981. [MCDI_EVENT_LINKCHANGE_SPEED_25G] = 25000,
  982. [MCDI_EVENT_LINKCHANGE_SPEED_50G] = 50000,
  983. [MCDI_EVENT_LINKCHANGE_SPEED_100G] = 100000,
  984. };
  985. void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
  986. {
  987. u32 flags, fcntl, speed, lpa;
  988. speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
  989. EFX_WARN_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
  990. speed = efx_mcdi_event_link_speed[speed];
  991. flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
  992. fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
  993. lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);
  994. /* efx->link_state is only modified by efx_mcdi_phy_get_link(),
  995. * which is only run after flushing the event queues. Therefore, it
  996. * is safe to modify the link state outside of the mac_lock here.
  997. */
  998. efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
  999. efx_mcdi_phy_check_fcntl(efx, lpa);
  1000. efx_link_status_changed(efx);
  1001. }
  1002. int efx_mcdi_set_mac(struct efx_nic *efx)
  1003. {
  1004. u32 fcntl;
  1005. MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
  1006. BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
  1007. /* This has no effect on EF10 */
  1008. ether_addr_copy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
  1009. efx->net_dev->dev_addr);
  1010. MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU,
  1011. EFX_MAX_FRAME_LEN(efx->net_dev->mtu));
  1012. MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0);
  1013. /* Set simple MAC filter for Siena */
  1014. MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_REJECT,
  1015. SET_MAC_IN_REJECT_UNCST, efx->unicast_filter);
  1016. MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
  1017. SET_MAC_IN_FLAG_INCLUDE_FCS,
  1018. !!(efx->net_dev->features & NETIF_F_RXFCS));
  1019. switch (efx->wanted_fc) {
  1020. case EFX_FC_RX | EFX_FC_TX:
  1021. fcntl = MC_CMD_FCNTL_BIDIR;
  1022. break;
  1023. case EFX_FC_RX:
  1024. fcntl = MC_CMD_FCNTL_RESPOND;
  1025. break;
  1026. default:
  1027. fcntl = MC_CMD_FCNTL_OFF;
  1028. break;
  1029. }
  1030. if (efx->wanted_fc & EFX_FC_AUTO)
  1031. fcntl = MC_CMD_FCNTL_AUTO;
  1032. if (efx->fc_disable)
  1033. fcntl = MC_CMD_FCNTL_OFF;
  1034. MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
  1035. return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes),
  1036. NULL, 0, NULL);
  1037. }
  1038. bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
  1039. {
  1040. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
  1041. size_t outlength;
  1042. int rc;
  1043. BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
  1044. rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
  1045. outbuf, sizeof(outbuf), &outlength);
  1046. if (rc)
  1047. return true;
  1048. return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
  1049. }
  1050. enum efx_stats_action {
  1051. EFX_STATS_ENABLE,
  1052. EFX_STATS_DISABLE,
  1053. EFX_STATS_PULL,
  1054. };
  1055. static int efx_mcdi_mac_stats(struct efx_nic *efx,
  1056. enum efx_stats_action action, int clear)
  1057. {
  1058. MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
  1059. int rc;
  1060. int change = action == EFX_STATS_PULL ? 0 : 1;
  1061. int enable = action == EFX_STATS_ENABLE ? 1 : 0;
  1062. int period = action == EFX_STATS_ENABLE ? 1000 : 0;
  1063. dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
  1064. u32 dma_len = action != EFX_STATS_DISABLE ?
  1065. efx->num_mac_stats * sizeof(u64) : 0;
  1066. BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
  1067. MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
  1068. MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
  1069. MAC_STATS_IN_DMA, !!enable,
  1070. MAC_STATS_IN_CLEAR, clear,
  1071. MAC_STATS_IN_PERIODIC_CHANGE, change,
  1072. MAC_STATS_IN_PERIODIC_ENABLE, enable,
  1073. MAC_STATS_IN_PERIODIC_CLEAR, 0,
  1074. MAC_STATS_IN_PERIODIC_NOEVENT, 1,
  1075. MAC_STATS_IN_PERIOD_MS, period);
  1076. MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
  1077. if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) {
  1078. struct efx_ef10_nic_data *nic_data = efx->nic_data;
  1079. MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, nic_data->vport_id);
  1080. }
  1081. rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
  1082. NULL, 0, NULL);
  1083. /* Expect ENOENT if DMA queues have not been set up */
  1084. if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
  1085. efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
  1086. NULL, 0, rc);
  1087. return rc;
  1088. }
  1089. void efx_mcdi_mac_start_stats(struct efx_nic *efx)
  1090. {
  1091. __le64 *dma_stats = efx->stats_buffer.addr;
  1092. dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
  1093. efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
  1094. }
  1095. void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
  1096. {
  1097. efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
  1098. }
  1099. #define EFX_MAC_STATS_WAIT_US 100
  1100. #define EFX_MAC_STATS_WAIT_ATTEMPTS 10
  1101. void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
  1102. {
  1103. __le64 *dma_stats = efx->stats_buffer.addr;
  1104. int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
  1105. dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
  1106. efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
  1107. while (dma_stats[efx->num_mac_stats - 1] ==
  1108. EFX_MC_STATS_GENERATION_INVALID &&
  1109. attempts-- != 0)
  1110. udelay(EFX_MAC_STATS_WAIT_US);
  1111. }
  1112. int efx_mcdi_port_probe(struct efx_nic *efx)
  1113. {
  1114. int rc;
  1115. /* Hook in PHY operations table */
  1116. efx->phy_op = &efx_mcdi_phy_ops;
  1117. /* Set up MDIO structure for PHY */
  1118. efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
  1119. efx->mdio.mdio_read = efx_mcdi_mdio_read;
  1120. efx->mdio.mdio_write = efx_mcdi_mdio_write;
  1121. /* Fill out MDIO structure, loopback modes, and initial link state */
  1122. rc = efx->phy_op->probe(efx);
  1123. if (rc != 0)
  1124. return rc;
  1125. /* Allocate buffer for stats */
  1126. rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
  1127. efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
  1128. if (rc)
  1129. return rc;
  1130. netif_dbg(efx, probe, efx->net_dev,
  1131. "stats buffer at %llx (virt %p phys %llx)\n",
  1132. (u64)efx->stats_buffer.dma_addr,
  1133. efx->stats_buffer.addr,
  1134. (u64)virt_to_phys(efx->stats_buffer.addr));
  1135. efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 1);
  1136. return 0;
  1137. }
  1138. void efx_mcdi_port_remove(struct efx_nic *efx)
  1139. {
  1140. efx->phy_op->remove(efx);
  1141. efx_nic_free_buffer(efx, &efx->stats_buffer);
  1142. }
  1143. /* Get physical port number (EF10 only; on Siena it is same as PF number) */
  1144. int efx_mcdi_port_get_number(struct efx_nic *efx)
  1145. {
  1146. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
  1147. int rc;
  1148. rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0,
  1149. outbuf, sizeof(outbuf), NULL);
  1150. if (rc)
  1151. return rc;
  1152. return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT);
  1153. }