mcdi_port_common.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  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(sizeof(*phy_data), GFP_KERNEL);
  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. efx->mdio_bus = phy_data->channel;
  389. efx->mdio.prtad = phy_data->port;
  390. efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
  391. efx->mdio.mode_support = 0;
  392. if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
  393. efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
  394. if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
  395. efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
  396. caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
  397. if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
  398. mcdi_to_ethtool_linkset(phy_data->media, caps,
  399. efx->link_advertising);
  400. else
  401. phy_data->forced_cap = caps;
  402. /* Assert that we can map efx -> mcdi loopback modes */
  403. BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE);
  404. BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA);
  405. BUILD_BUG_ON(LOOPBACK_GMAC != MC_CMD_LOOPBACK_GMAC);
  406. BUILD_BUG_ON(LOOPBACK_XGMII != MC_CMD_LOOPBACK_XGMII);
  407. BUILD_BUG_ON(LOOPBACK_XGXS != MC_CMD_LOOPBACK_XGXS);
  408. BUILD_BUG_ON(LOOPBACK_XAUI != MC_CMD_LOOPBACK_XAUI);
  409. BUILD_BUG_ON(LOOPBACK_GMII != MC_CMD_LOOPBACK_GMII);
  410. BUILD_BUG_ON(LOOPBACK_SGMII != MC_CMD_LOOPBACK_SGMII);
  411. BUILD_BUG_ON(LOOPBACK_XGBR != MC_CMD_LOOPBACK_XGBR);
  412. BUILD_BUG_ON(LOOPBACK_XFI != MC_CMD_LOOPBACK_XFI);
  413. BUILD_BUG_ON(LOOPBACK_XAUI_FAR != MC_CMD_LOOPBACK_XAUI_FAR);
  414. BUILD_BUG_ON(LOOPBACK_GMII_FAR != MC_CMD_LOOPBACK_GMII_FAR);
  415. BUILD_BUG_ON(LOOPBACK_SGMII_FAR != MC_CMD_LOOPBACK_SGMII_FAR);
  416. BUILD_BUG_ON(LOOPBACK_XFI_FAR != MC_CMD_LOOPBACK_XFI_FAR);
  417. BUILD_BUG_ON(LOOPBACK_GPHY != MC_CMD_LOOPBACK_GPHY);
  418. BUILD_BUG_ON(LOOPBACK_PHYXS != MC_CMD_LOOPBACK_PHYXS);
  419. BUILD_BUG_ON(LOOPBACK_PCS != MC_CMD_LOOPBACK_PCS);
  420. BUILD_BUG_ON(LOOPBACK_PMAPMD != MC_CMD_LOOPBACK_PMAPMD);
  421. BUILD_BUG_ON(LOOPBACK_XPORT != MC_CMD_LOOPBACK_XPORT);
  422. BUILD_BUG_ON(LOOPBACK_XGMII_WS != MC_CMD_LOOPBACK_XGMII_WS);
  423. BUILD_BUG_ON(LOOPBACK_XAUI_WS != MC_CMD_LOOPBACK_XAUI_WS);
  424. BUILD_BUG_ON(LOOPBACK_XAUI_WS_FAR != MC_CMD_LOOPBACK_XAUI_WS_FAR);
  425. BUILD_BUG_ON(LOOPBACK_XAUI_WS_NEAR != MC_CMD_LOOPBACK_XAUI_WS_NEAR);
  426. BUILD_BUG_ON(LOOPBACK_GMII_WS != MC_CMD_LOOPBACK_GMII_WS);
  427. BUILD_BUG_ON(LOOPBACK_XFI_WS != MC_CMD_LOOPBACK_XFI_WS);
  428. BUILD_BUG_ON(LOOPBACK_XFI_WS_FAR != MC_CMD_LOOPBACK_XFI_WS_FAR);
  429. BUILD_BUG_ON(LOOPBACK_PHYXS_WS != MC_CMD_LOOPBACK_PHYXS_WS);
  430. rc = efx_mcdi_loopback_modes(efx, &efx->loopback_modes);
  431. if (rc != 0)
  432. goto fail;
  433. /* The MC indicates that LOOPBACK_NONE is a valid loopback mode,
  434. * but by convention we don't
  435. */
  436. efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
  437. /* Set the initial link mode */
  438. efx_mcdi_phy_decode_link(efx, &efx->link_state,
  439. MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
  440. MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
  441. MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
  442. /* Record the initial FEC configuration (or nearest approximation
  443. * representable in the ethtool configuration space)
  444. */
  445. efx->fec_config = mcdi_fec_caps_to_ethtool(caps,
  446. efx->link_state.speed == 25000 ||
  447. efx->link_state.speed == 50000);
  448. /* Default to Autonegotiated flow control if the PHY supports it */
  449. efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
  450. if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
  451. efx->wanted_fc |= EFX_FC_AUTO;
  452. efx_link_set_wanted_fc(efx, efx->wanted_fc);
  453. return 0;
  454. fail:
  455. kfree(phy_data);
  456. return rc;
  457. }
  458. void efx_mcdi_phy_remove(struct efx_nic *efx)
  459. {
  460. struct efx_mcdi_phy_data *phy_data = efx->phy_data;
  461. efx->phy_data = NULL;
  462. kfree(phy_data);
  463. }
  464. void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx, struct ethtool_link_ksettings *cmd)
  465. {
  466. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  467. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
  468. int rc;
  469. cmd->base.speed = efx->link_state.speed;
  470. cmd->base.duplex = efx->link_state.fd;
  471. cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
  472. cmd->base.phy_address = phy_cfg->port;
  473. cmd->base.autoneg = !!(efx->link_advertising[0] & ADVERTISED_Autoneg);
  474. cmd->base.mdio_support = (efx->mdio.mode_support &
  475. (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
  476. mcdi_to_ethtool_linkset(phy_cfg->media, phy_cfg->supported_cap,
  477. cmd->link_modes.supported);
  478. memcpy(cmd->link_modes.advertising, efx->link_advertising,
  479. sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
  480. BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
  481. rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
  482. outbuf, sizeof(outbuf), NULL);
  483. if (rc)
  484. return;
  485. mcdi_to_ethtool_linkset(phy_cfg->media,
  486. MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP),
  487. cmd->link_modes.lp_advertising);
  488. }
  489. int efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx, const struct ethtool_link_ksettings *cmd)
  490. {
  491. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  492. u32 caps;
  493. int rc;
  494. if (cmd->base.autoneg) {
  495. caps = (ethtool_linkset_to_mcdi_cap(cmd->link_modes.advertising) |
  496. 1 << MC_CMD_PHY_CAP_AN_LBN);
  497. } else if (cmd->base.duplex) {
  498. switch (cmd->base.speed) {
  499. case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break;
  500. case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break;
  501. case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break;
  502. case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break;
  503. case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break;
  504. case 100000: caps = 1 << MC_CMD_PHY_CAP_100000FDX_LBN; break;
  505. case 25000: caps = 1 << MC_CMD_PHY_CAP_25000FDX_LBN; break;
  506. case 50000: caps = 1 << MC_CMD_PHY_CAP_50000FDX_LBN; break;
  507. default: return -EINVAL;
  508. }
  509. } else {
  510. switch (cmd->base.speed) {
  511. case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break;
  512. case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break;
  513. case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break;
  514. default: return -EINVAL;
  515. }
  516. }
  517. caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, efx->fec_config);
  518. rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
  519. efx->loopback_mode, 0);
  520. if (rc)
  521. return rc;
  522. if (cmd->base.autoneg) {
  523. efx_link_set_advertising(efx, cmd->link_modes.advertising);
  524. phy_cfg->forced_cap = 0;
  525. } else {
  526. efx_link_clear_advertising(efx);
  527. phy_cfg->forced_cap = caps;
  528. }
  529. return 0;
  530. }
  531. int efx_mcdi_phy_get_fecparam(struct efx_nic *efx, struct ethtool_fecparam *fec)
  532. {
  533. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN);
  534. u32 caps, active, speed; /* MCDI format */
  535. bool is_25g = false;
  536. size_t outlen;
  537. int rc;
  538. BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
  539. rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
  540. outbuf, sizeof(outbuf), &outlen);
  541. if (rc)
  542. return rc;
  543. if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN)
  544. return -EOPNOTSUPP;
  545. /* behaviour for 25G/50G links depends on 25G BASER bit */
  546. speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED);
  547. is_25g = speed == 25000 || speed == 50000;
  548. caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP);
  549. fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g);
  550. /* BASER is never supported on 100G */
  551. if (speed == 100000)
  552. fec->fec &= ~ETHTOOL_FEC_BASER;
  553. active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE);
  554. switch (active) {
  555. case MC_CMD_FEC_NONE:
  556. fec->active_fec = ETHTOOL_FEC_OFF;
  557. break;
  558. case MC_CMD_FEC_BASER:
  559. fec->active_fec = ETHTOOL_FEC_BASER;
  560. break;
  561. case MC_CMD_FEC_RS:
  562. fec->active_fec = ETHTOOL_FEC_RS;
  563. break;
  564. default:
  565. netif_warn(efx, hw, efx->net_dev,
  566. "Firmware reports unrecognised FEC_TYPE %u\n",
  567. active);
  568. /* We don't know what firmware has picked. AUTO is as good a
  569. * "can't happen" value as any other.
  570. */
  571. fec->active_fec = ETHTOOL_FEC_AUTO;
  572. break;
  573. }
  574. return 0;
  575. }
  576. /* Basic validation to ensure that the caps we are going to attempt to set are
  577. * in fact supported by the adapter. Note that 'no FEC' is always supported.
  578. */
  579. static int ethtool_fec_supported(u32 supported_cap, u32 ethtool_cap)
  580. {
  581. if (ethtool_cap & ETHTOOL_FEC_OFF)
  582. return 0;
  583. if (ethtool_cap &&
  584. !ethtool_fec_caps_to_mcdi(supported_cap, ethtool_cap))
  585. return -EINVAL;
  586. return 0;
  587. }
  588. int efx_mcdi_phy_set_fecparam(struct efx_nic *efx, const struct ethtool_fecparam *fec)
  589. {
  590. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  591. u32 caps;
  592. int rc;
  593. rc = ethtool_fec_supported(phy_cfg->supported_cap, fec->fec);
  594. if (rc)
  595. return rc;
  596. /* Work out what efx_mcdi_phy_set_link_ksettings() would produce from
  597. * saved advertising bits
  598. */
  599. if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, efx->link_advertising))
  600. caps = (ethtool_linkset_to_mcdi_cap(efx->link_advertising) |
  601. 1 << MC_CMD_PHY_CAP_AN_LBN);
  602. else
  603. caps = phy_cfg->forced_cap;
  604. caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, fec->fec);
  605. rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
  606. efx->loopback_mode, 0);
  607. if (rc)
  608. return rc;
  609. /* Record the new FEC setting for subsequent set_link calls */
  610. efx->fec_config = fec->fec;
  611. return 0;
  612. }
  613. int efx_mcdi_phy_test_alive(struct efx_nic *efx)
  614. {
  615. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
  616. size_t outlen;
  617. int rc;
  618. BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
  619. rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
  620. outbuf, sizeof(outbuf), &outlen);
  621. if (rc)
  622. return rc;
  623. if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
  624. return -EIO;
  625. if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK)
  626. return -EINVAL;
  627. return 0;
  628. }
  629. int efx_mcdi_port_reconfigure(struct efx_nic *efx)
  630. {
  631. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  632. u32 caps = (efx->link_advertising[0] ?
  633. ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
  634. phy_cfg->forced_cap);
  635. caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, efx->fec_config);
  636. return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
  637. efx->loopback_mode, 0);
  638. }
  639. static const char *const mcdi_sft9001_cable_diag_names[] = {
  640. "cable.pairA.length",
  641. "cable.pairB.length",
  642. "cable.pairC.length",
  643. "cable.pairD.length",
  644. "cable.pairA.status",
  645. "cable.pairB.status",
  646. "cable.pairC.status",
  647. "cable.pairD.status",
  648. };
  649. static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
  650. int *results)
  651. {
  652. unsigned int retry, i, count = 0;
  653. size_t outlen;
  654. u32 status;
  655. MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
  656. MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_SFT9001_LEN);
  657. u8 *ptr;
  658. int rc;
  659. BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0);
  660. MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_mode);
  661. rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST,
  662. inbuf, MC_CMD_START_BIST_IN_LEN, NULL, 0, NULL);
  663. if (rc)
  664. goto out;
  665. /* Wait up to 10s for BIST to finish */
  666. for (retry = 0; retry < 100; ++retry) {
  667. BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0);
  668. rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
  669. outbuf, sizeof(outbuf), &outlen);
  670. if (rc)
  671. goto out;
  672. status = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
  673. if (status != MC_CMD_POLL_BIST_RUNNING)
  674. goto finished;
  675. msleep(100);
  676. }
  677. rc = -ETIMEDOUT;
  678. goto out;
  679. finished:
  680. results[count++] = (status == MC_CMD_POLL_BIST_PASSED) ? 1 : -1;
  681. /* SFT9001 specific cable diagnostics output */
  682. if (efx->phy_type == PHY_TYPE_SFT9001B &&
  683. (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT ||
  684. bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) {
  685. ptr = MCDI_PTR(outbuf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
  686. if (status == MC_CMD_POLL_BIST_PASSED &&
  687. outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) {
  688. for (i = 0; i < 8; i++) {
  689. results[count + i] =
  690. EFX_DWORD_FIELD(((efx_dword_t *)ptr)[i],
  691. EFX_DWORD_0);
  692. }
  693. }
  694. count += 8;
  695. }
  696. rc = count;
  697. out:
  698. return rc;
  699. }
  700. int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, unsigned int flags)
  701. {
  702. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  703. u32 mode;
  704. int rc;
  705. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
  706. rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results);
  707. if (rc < 0)
  708. return rc;
  709. results += rc;
  710. }
  711. /* If we support both LONG and SHORT, then run each in response to
  712. * break or not. Otherwise, run the one we support
  713. */
  714. mode = 0;
  715. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) {
  716. if ((flags & ETH_TEST_FL_OFFLINE) &&
  717. (phy_cfg->flags &
  718. (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)))
  719. mode = MC_CMD_PHY_BIST_CABLE_LONG;
  720. else
  721. mode = MC_CMD_PHY_BIST_CABLE_SHORT;
  722. } else if (phy_cfg->flags &
  723. (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))
  724. mode = MC_CMD_PHY_BIST_CABLE_LONG;
  725. if (mode != 0) {
  726. rc = efx_mcdi_bist(efx, mode, results);
  727. if (rc < 0)
  728. return rc;
  729. results += rc;
  730. }
  731. return 0;
  732. }
  733. const char *efx_mcdi_phy_test_name(struct efx_nic *efx, unsigned int index)
  734. {
  735. struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
  736. if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
  737. if (index == 0)
  738. return "bist";
  739. --index;
  740. }
  741. if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) |
  742. (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) {
  743. if (index == 0)
  744. return "cable";
  745. --index;
  746. if (efx->phy_type == PHY_TYPE_SFT9001B) {
  747. if (index < ARRAY_SIZE(mcdi_sft9001_cable_diag_names))
  748. return mcdi_sft9001_cable_diag_names[index];
  749. index -= ARRAY_SIZE(mcdi_sft9001_cable_diag_names);
  750. }
  751. }
  752. return NULL;
  753. }
  754. #define SFP_PAGE_SIZE 128
  755. #define SFF_DIAG_TYPE_OFFSET 92
  756. #define SFF_DIAG_ADDR_CHANGE BIT(2)
  757. #define SFF_8079_NUM_PAGES 2
  758. #define SFF_8472_NUM_PAGES 4
  759. #define SFF_8436_NUM_PAGES 5
  760. #define SFF_DMT_LEVEL_OFFSET 94
  761. /** efx_mcdi_phy_get_module_eeprom_page() - Get a single page of module eeprom
  762. * @efx: NIC context
  763. * @page: EEPROM page number
  764. * @data: Destination data pointer
  765. * @offset: Offset in page to copy from in to data
  766. * @space: Space available in data
  767. *
  768. * Return:
  769. * >=0 - amount of data copied
  770. * <0 - error
  771. */
  772. static int efx_mcdi_phy_get_module_eeprom_page(struct efx_nic *efx,
  773. unsigned int page,
  774. u8 *data, ssize_t offset,
  775. ssize_t space)
  776. {
  777. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX);
  778. MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN);
  779. unsigned int payload_len;
  780. unsigned int to_copy;
  781. size_t outlen;
  782. int rc;
  783. if (offset > SFP_PAGE_SIZE)
  784. return -EINVAL;
  785. to_copy = min(space, SFP_PAGE_SIZE - offset);
  786. MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page);
  787. rc = efx_mcdi_rpc_quiet(efx, MC_CMD_GET_PHY_MEDIA_INFO,
  788. inbuf, sizeof(inbuf),
  789. outbuf, sizeof(outbuf),
  790. &outlen);
  791. if (rc)
  792. return rc;
  793. if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST +
  794. SFP_PAGE_SIZE))
  795. return -EIO;
  796. payload_len = MCDI_DWORD(outbuf, GET_PHY_MEDIA_INFO_OUT_DATALEN);
  797. if (payload_len != SFP_PAGE_SIZE)
  798. return -EIO;
  799. memcpy(data, MCDI_PTR(outbuf, GET_PHY_MEDIA_INFO_OUT_DATA) + offset,
  800. to_copy);
  801. return to_copy;
  802. }
  803. static int efx_mcdi_phy_get_module_eeprom_byte(struct efx_nic *efx,
  804. unsigned int page,
  805. u8 byte)
  806. {
  807. u8 data;
  808. int rc;
  809. rc = efx_mcdi_phy_get_module_eeprom_page(efx, page, &data, byte, 1);
  810. if (rc == 1)
  811. return data;
  812. return rc;
  813. }
  814. static int efx_mcdi_phy_diag_type(struct efx_nic *efx)
  815. {
  816. /* Page zero of the EEPROM includes the diagnostic type at byte 92. */
  817. return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
  818. SFF_DIAG_TYPE_OFFSET);
  819. }
  820. static int efx_mcdi_phy_sff_8472_level(struct efx_nic *efx)
  821. {
  822. /* Page zero of the EEPROM includes the DMT level at byte 94. */
  823. return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
  824. SFF_DMT_LEVEL_OFFSET);
  825. }
  826. static u32 efx_mcdi_phy_module_type(struct efx_nic *efx)
  827. {
  828. struct efx_mcdi_phy_data *phy_data = efx->phy_data;
  829. if (phy_data->media != MC_CMD_MEDIA_QSFP_PLUS)
  830. return phy_data->media;
  831. /* A QSFP+ NIC may actually have an SFP+ module attached.
  832. * The ID is page 0, byte 0.
  833. * QSFP28 is of type SFF_8636, however, this is treated
  834. * the same by ethtool, so we can also treat them the same.
  835. */
  836. switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) {
  837. case 0x3: /* SFP */
  838. return MC_CMD_MEDIA_SFP_PLUS;
  839. case 0xc: /* QSFP */
  840. case 0xd: /* QSFP+ */
  841. case 0x11: /* QSFP28 */
  842. return MC_CMD_MEDIA_QSFP_PLUS;
  843. default:
  844. return 0;
  845. }
  846. }
  847. int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx, struct ethtool_eeprom *ee, u8 *data)
  848. {
  849. int rc;
  850. ssize_t space_remaining = ee->len;
  851. unsigned int page_off;
  852. bool ignore_missing;
  853. int num_pages;
  854. int page;
  855. switch (efx_mcdi_phy_module_type(efx)) {
  856. case MC_CMD_MEDIA_SFP_PLUS:
  857. num_pages = efx_mcdi_phy_sff_8472_level(efx) > 0 ?
  858. SFF_8472_NUM_PAGES : SFF_8079_NUM_PAGES;
  859. page = 0;
  860. ignore_missing = false;
  861. break;
  862. case MC_CMD_MEDIA_QSFP_PLUS:
  863. num_pages = SFF_8436_NUM_PAGES;
  864. page = -1; /* We obtain the lower page by asking for -1. */
  865. ignore_missing = true; /* Ignore missing pages after page 0. */
  866. break;
  867. default:
  868. return -EOPNOTSUPP;
  869. }
  870. page_off = ee->offset % SFP_PAGE_SIZE;
  871. page += ee->offset / SFP_PAGE_SIZE;
  872. while (space_remaining && (page < num_pages)) {
  873. rc = efx_mcdi_phy_get_module_eeprom_page(efx, page,
  874. data, page_off,
  875. space_remaining);
  876. if (rc > 0) {
  877. space_remaining -= rc;
  878. data += rc;
  879. page_off = 0;
  880. page++;
  881. } else if (rc == 0) {
  882. space_remaining = 0;
  883. } else if (ignore_missing && (page > 0)) {
  884. int intended_size = SFP_PAGE_SIZE - page_off;
  885. space_remaining -= intended_size;
  886. if (space_remaining < 0) {
  887. space_remaining = 0;
  888. } else {
  889. memset(data, 0, intended_size);
  890. data += intended_size;
  891. page_off = 0;
  892. page++;
  893. rc = 0;
  894. }
  895. } else {
  896. return rc;
  897. }
  898. }
  899. return 0;
  900. }
  901. int efx_mcdi_phy_get_module_info(struct efx_nic *efx, struct ethtool_modinfo *modinfo)
  902. {
  903. int sff_8472_level;
  904. int diag_type;
  905. switch (efx_mcdi_phy_module_type(efx)) {
  906. case MC_CMD_MEDIA_SFP_PLUS:
  907. sff_8472_level = efx_mcdi_phy_sff_8472_level(efx);
  908. /* If we can't read the diagnostics level we have none. */
  909. if (sff_8472_level < 0)
  910. return -EOPNOTSUPP;
  911. /* Check if this module requires the (unsupported) address
  912. * change operation.
  913. */
  914. diag_type = efx_mcdi_phy_diag_type(efx);
  915. if (sff_8472_level == 0 ||
  916. (diag_type & SFF_DIAG_ADDR_CHANGE)) {
  917. modinfo->type = ETH_MODULE_SFF_8079;
  918. modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
  919. } else {
  920. modinfo->type = ETH_MODULE_SFF_8472;
  921. modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
  922. }
  923. break;
  924. case MC_CMD_MEDIA_QSFP_PLUS:
  925. modinfo->type = ETH_MODULE_SFF_8436;
  926. modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
  927. break;
  928. default:
  929. return -EOPNOTSUPP;
  930. }
  931. return 0;
  932. }
  933. static unsigned int efx_calc_mac_mtu(struct efx_nic *efx)
  934. {
  935. return EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
  936. }
  937. int efx_mcdi_set_mac(struct efx_nic *efx)
  938. {
  939. u32 fcntl;
  940. MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
  941. BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
  942. /* This has no effect on EF10 */
  943. ether_addr_copy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
  944. efx->net_dev->dev_addr);
  945. MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU, efx_calc_mac_mtu(efx));
  946. MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0);
  947. MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
  948. SET_MAC_IN_FLAG_INCLUDE_FCS,
  949. !!(efx->net_dev->features & NETIF_F_RXFCS));
  950. switch (efx->wanted_fc) {
  951. case EFX_FC_RX | EFX_FC_TX:
  952. fcntl = MC_CMD_FCNTL_BIDIR;
  953. break;
  954. case EFX_FC_RX:
  955. fcntl = MC_CMD_FCNTL_RESPOND;
  956. break;
  957. default:
  958. fcntl = MC_CMD_FCNTL_OFF;
  959. break;
  960. }
  961. if (efx->wanted_fc & EFX_FC_AUTO)
  962. fcntl = MC_CMD_FCNTL_AUTO;
  963. if (efx->fc_disable)
  964. fcntl = MC_CMD_FCNTL_OFF;
  965. MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
  966. return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes),
  967. NULL, 0, NULL);
  968. }
  969. int efx_mcdi_set_mtu(struct efx_nic *efx)
  970. {
  971. MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_MAC_EXT_IN_LEN);
  972. BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
  973. MCDI_SET_DWORD(inbuf, SET_MAC_EXT_IN_MTU, efx_calc_mac_mtu(efx));
  974. MCDI_POPULATE_DWORD_1(inbuf, SET_MAC_EXT_IN_CONTROL,
  975. SET_MAC_EXT_IN_CFG_MTU, 1);
  976. return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, inbuf, sizeof(inbuf),
  977. NULL, 0, NULL);
  978. }
  979. enum efx_stats_action {
  980. EFX_STATS_ENABLE,
  981. EFX_STATS_DISABLE,
  982. EFX_STATS_PULL,
  983. };
  984. static int efx_mcdi_mac_stats(struct efx_nic *efx,
  985. enum efx_stats_action action, int clear)
  986. {
  987. MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
  988. int rc;
  989. int change = action == EFX_STATS_PULL ? 0 : 1;
  990. int enable = action == EFX_STATS_ENABLE ? 1 : 0;
  991. int period = action == EFX_STATS_ENABLE ? 1000 : 0;
  992. dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
  993. u32 dma_len = action != EFX_STATS_DISABLE ?
  994. efx->num_mac_stats * sizeof(u64) : 0;
  995. BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
  996. MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
  997. MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
  998. MAC_STATS_IN_DMA, !!enable,
  999. MAC_STATS_IN_CLEAR, clear,
  1000. MAC_STATS_IN_PERIODIC_CHANGE, change,
  1001. MAC_STATS_IN_PERIODIC_ENABLE, enable,
  1002. MAC_STATS_IN_PERIODIC_CLEAR, 0,
  1003. MAC_STATS_IN_PERIODIC_NOEVENT, 1,
  1004. MAC_STATS_IN_PERIOD_MS, period);
  1005. MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
  1006. if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
  1007. MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, efx->vport_id);
  1008. rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
  1009. NULL, 0, NULL);
  1010. /* Expect ENOENT if DMA queues have not been set up */
  1011. if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
  1012. efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
  1013. NULL, 0, rc);
  1014. return rc;
  1015. }
  1016. void efx_mcdi_mac_start_stats(struct efx_nic *efx)
  1017. {
  1018. __le64 *dma_stats = efx->stats_buffer.addr;
  1019. dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
  1020. efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
  1021. }
  1022. void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
  1023. {
  1024. efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
  1025. }
  1026. #define EFX_MAC_STATS_WAIT_US 100
  1027. #define EFX_MAC_STATS_WAIT_ATTEMPTS 10
  1028. void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
  1029. {
  1030. __le64 *dma_stats = efx->stats_buffer.addr;
  1031. int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
  1032. dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
  1033. efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
  1034. while (dma_stats[efx->num_mac_stats - 1] ==
  1035. EFX_MC_STATS_GENERATION_INVALID &&
  1036. attempts-- != 0)
  1037. udelay(EFX_MAC_STATS_WAIT_US);
  1038. }
  1039. int efx_mcdi_mac_init_stats(struct efx_nic *efx)
  1040. {
  1041. int rc;
  1042. if (!efx->num_mac_stats)
  1043. return 0;
  1044. /* Allocate buffer for stats */
  1045. rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
  1046. efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
  1047. if (rc) {
  1048. netif_warn(efx, probe, efx->net_dev,
  1049. "failed to allocate DMA buffer: %d\n", rc);
  1050. return rc;
  1051. }
  1052. netif_dbg(efx, probe, efx->net_dev,
  1053. "stats buffer at %llx (virt %p phys %llx)\n",
  1054. (u64) efx->stats_buffer.dma_addr,
  1055. efx->stats_buffer.addr,
  1056. (u64) virt_to_phys(efx->stats_buffer.addr));
  1057. return 0;
  1058. }
  1059. void efx_mcdi_mac_fini_stats(struct efx_nic *efx)
  1060. {
  1061. efx_nic_free_buffer(efx, &efx->stats_buffer);
  1062. }
  1063. /* Get physical port number (EF10 only; on Siena it is same as PF number) */
  1064. int efx_mcdi_port_get_number(struct efx_nic *efx)
  1065. {
  1066. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
  1067. int rc;
  1068. rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0,
  1069. outbuf, sizeof(outbuf), NULL);
  1070. if (rc)
  1071. return rc;
  1072. return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT);
  1073. }
  1074. static unsigned int efx_mcdi_event_link_speed[] = {
  1075. [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
  1076. [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
  1077. [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
  1078. [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
  1079. [MCDI_EVENT_LINKCHANGE_SPEED_25G] = 25000,
  1080. [MCDI_EVENT_LINKCHANGE_SPEED_50G] = 50000,
  1081. [MCDI_EVENT_LINKCHANGE_SPEED_100G] = 100000,
  1082. };
  1083. void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
  1084. {
  1085. u32 flags, fcntl, speed, lpa;
  1086. speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
  1087. EFX_WARN_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
  1088. speed = efx_mcdi_event_link_speed[speed];
  1089. flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
  1090. fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
  1091. lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);
  1092. /* efx->link_state is only modified by efx_mcdi_phy_get_link(),
  1093. * which is only run after flushing the event queues. Therefore, it
  1094. * is safe to modify the link state outside of the mac_lock here.
  1095. */
  1096. efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
  1097. efx_mcdi_phy_check_fcntl(efx, lpa);
  1098. efx_link_status_changed(efx);
  1099. }