mcdi_port.c 33 KB

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