mcdi_port_common.c 37 KB

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