Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

sfc_hunt.c 33KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. /**************************************************************************
  2. *
  3. * Device driver for Solarflare Communications EF10 devices
  4. *
  5. * Written by Shradha Shah <sshah@solarflare.com>
  6. *
  7. * Copyright 2012-2017 Solarflare Communications Inc.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of the
  12. * License, or any later version.
  13. *
  14. * You can also choose to distribute this program under the terms of
  15. * the Unmodified Binary Distribution Licence (as given in the file
  16. * COPYING.UBDL), provided that you have satisfied its requirements.
  17. *
  18. ***************************************************************************/
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <unistd.h>
  22. #include <errno.h>
  23. #include <byteswap.h>
  24. #include <ipxe/io.h>
  25. #include <ipxe/pci.h>
  26. #include <ipxe/malloc.h>
  27. #include <ipxe/ethernet.h>
  28. #include <ipxe/iobuf.h>
  29. #include <ipxe/netdevice.h>
  30. #include "efx_hunt.h"
  31. #include "efx_bitfield.h"
  32. #include "ef10_regs.h"
  33. #include "mc_driver_pcol.h"
  34. #include <ipxe/if_ether.h>
  35. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  36. #define HUNTINGTON_NVRAM_CHUNK 0x80
  37. #define HUNTINGTON_NVS_MAX_LENGTH 0x1000
  38. #define EMCDI_IO(code) EUNIQ(EINFO_EIO, (code))
  39. #ifndef MIN
  40. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  41. #endif
  42. #ifndef MAX
  43. #define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
  44. #endif
  45. struct hunt_nic *primary_nics = NULL;
  46. struct hunt_nic {
  47. struct efx_nic efx;
  48. /* PHY information */
  49. unsigned int phy_cap_mask;
  50. unsigned int phy_cap;
  51. unsigned long link_poll_timer;
  52. /* resource housekeeping */
  53. uint64_t uc_filter_id;
  54. uint64_t mc_filter_id;
  55. u8 mac[ETH_ALEN];
  56. struct {
  57. /* Common payload for all MCDI requests */
  58. unsigned int seqno;
  59. size_t resp_hdr_len;
  60. size_t resp_data_len;
  61. struct io_buffer *iob;
  62. uint64_t dma_addr;
  63. } mcdi;
  64. struct hunt_nic *primary;
  65. struct hunt_nic *next_primary;
  66. u32 flags;
  67. };
  68. static int hunt_nic_is_primary(struct hunt_nic *hunt)
  69. {
  70. return (hunt->flags & (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY));
  71. }
  72. /*******************************************************************************
  73. *
  74. *
  75. * MCDI transport
  76. *
  77. * This has been based on the implementation of MCDI in the common code driver.
  78. *
  79. *
  80. ******************************************************************************/
  81. static int hunt_mcdi_init(struct hunt_nic *hunt)
  82. {
  83. size_t max_msg_size;
  84. int rc;
  85. /* The MCDI message has two 32-bit headers (the MCDI header and the
  86. * MCDI v2 extended command) and then up to MCDI_CTL_SDU_LEN_MAX_V2
  87. * bytes of payload
  88. */
  89. max_msg_size = 2 * sizeof(efx_dword_t) + MCDI_CTL_SDU_LEN_MAX_V2;
  90. hunt->mcdi.iob = alloc_iob(max_msg_size);
  91. if (!hunt->mcdi.iob) {
  92. rc = -ENOMEM;
  93. return rc;
  94. }
  95. return 0;
  96. }
  97. static void hunt_mcdi_copyin(struct hunt_nic *hunt,
  98. unsigned int cmd,
  99. uint8_t *inbuf,
  100. size_t inlen)
  101. {
  102. efx_dword_t hdr[2];
  103. uint32_t seqno;
  104. unsigned int xflags;
  105. size_t hdr_len;
  106. u8 *pdu = hunt->mcdi.iob->data;
  107. seqno = hunt->mcdi.seqno & MCDI_SEQ_MASK;
  108. xflags = 0;
  109. EFX_POPULATE_DWORD_7(hdr[0],
  110. MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
  111. MCDI_HEADER_RESYNC, 1,
  112. MCDI_HEADER_DATALEN, 0,
  113. MCDI_HEADER_SEQ, seqno,
  114. MCDI_HEADER_ERROR, 0,
  115. MCDI_HEADER_RESPONSE, 0,
  116. MCDI_HEADER_XFLAGS, xflags);
  117. EFX_POPULATE_DWORD_2(hdr[1],
  118. MC_CMD_V2_EXTN_IN_EXTENDED_CMD, cmd,
  119. MC_CMD_V2_EXTN_IN_ACTUAL_LEN, inlen);
  120. hdr_len = sizeof(hdr);
  121. memcpy(pdu, &hdr, hdr_len);
  122. memcpy(pdu + hdr_len, inbuf, inlen);
  123. wmb(); /* Sync the data before ringing the doorbell */
  124. /* Ring the doorbell to post the command DMA address to the MC */
  125. hunt->mcdi.dma_addr = virt_to_bus(hunt->mcdi.iob->data);
  126. assert((hunt->mcdi.dma_addr & 0xFF) == 0);
  127. _efx_writel(&hunt->efx,
  128. cpu_to_le32((u64)hunt->mcdi.dma_addr >> 32),
  129. ER_DZ_MC_DB_LWRD);
  130. _efx_writel(&hunt->efx,
  131. cpu_to_le32((u32)hunt->mcdi.dma_addr),
  132. ER_DZ_MC_DB_HWRD);
  133. }
  134. static void hunt_mcdi_copyout(struct hunt_nic *hunt,
  135. uint8_t *outbuf, size_t outlen)
  136. {
  137. size_t offset;
  138. const u8 *pdu = hunt->mcdi.iob->data;
  139. offset = hunt->mcdi.resp_hdr_len;
  140. if (outlen > 0)
  141. memcpy(outbuf, pdu+offset, outlen);
  142. }
  143. static int hunt_mcdi_request_poll(struct hunt_nic *hunt, bool quiet)
  144. {
  145. unsigned int resplen, respseq, error;
  146. unsigned long finish;
  147. efx_dword_t errdword;
  148. efx_qword_t qword;
  149. const efx_dword_t *pdu = hunt->mcdi.iob->data;
  150. const u8 *pdu1 = hunt->mcdi.iob->data;
  151. int delay, rc;
  152. /* Spin for up to 5s, polling at intervals of 10us, 20us, ... ~100ms */
  153. finish = currticks() + (5 * TICKS_PER_SEC);
  154. delay = 10;
  155. while (1) {
  156. udelay(delay);
  157. /* Check for an MCDI response */
  158. if (EFX_DWORD_FIELD(*pdu, MCDI_HEADER_RESPONSE))
  159. break;
  160. if (currticks() >= finish)
  161. return -ETIMEDOUT;
  162. if (delay < 100000)
  163. delay *= 2;
  164. }
  165. memcpy(&qword, pdu1, 8);
  166. /* qword.dword[0] is the MCDI header; qword.dword[1] is the MCDI v2
  167. * extended command
  168. */
  169. respseq = EFX_DWORD_FIELD(qword.dword[0], MCDI_HEADER_SEQ);
  170. error = EFX_DWORD_FIELD(qword.dword[0], MCDI_HEADER_ERROR);
  171. resplen = EFX_DWORD_FIELD(qword.dword[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
  172. if (error && resplen == 0) {
  173. if (!quiet)
  174. DBGC(hunt, "MC rebooted\n");
  175. return -EIO;
  176. } else if ((respseq ^ hunt->mcdi.seqno) & MCDI_SEQ_MASK) {
  177. if (!quiet)
  178. DBGC(hunt, "MC response mismatch rxseq 0x%x txseq "
  179. "0x%x\n", respseq, hunt->mcdi.seqno);
  180. return -EIO;
  181. } else if (error) {
  182. memcpy(&errdword, pdu1 + 8, 4);
  183. rc = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
  184. switch (rc) {
  185. case MC_CMD_ERR_ENOENT:
  186. return -ENOENT;
  187. case MC_CMD_ERR_EINTR:
  188. return -EINTR;
  189. case MC_CMD_ERR_EACCES:
  190. return -EACCES;
  191. case MC_CMD_ERR_EBUSY:
  192. return -EBUSY;
  193. case MC_CMD_ERR_EINVAL:
  194. return -EINVAL;
  195. case MC_CMD_ERR_EDEADLK:
  196. return -EDEADLK;
  197. case MC_CMD_ERR_ENOSYS:
  198. return -ENOSYS;
  199. case MC_CMD_ERR_ETIME:
  200. return -ETIME;
  201. case MC_CMD_ERR_EPERM:
  202. return -EPERM;
  203. default:
  204. /* Return the MC error in an I/O error. */
  205. return EMCDI_IO(rc & 0xff);
  206. }
  207. }
  208. hunt->mcdi.resp_hdr_len = 8;
  209. hunt->mcdi.resp_data_len = resplen;
  210. return 0;
  211. }
  212. static void hunt_mcdi_fini(struct hunt_nic *hunt)
  213. {
  214. free_iob(hunt->mcdi.iob);
  215. }
  216. int _hunt_mcdi(struct efx_nic *efx, unsigned int cmd,
  217. const efx_dword_t *inbuf, size_t inlen,
  218. efx_dword_t *outbuf, size_t outlen,
  219. size_t *outlen_actual, bool quiet)
  220. {
  221. int rc;
  222. struct hunt_nic *hunt = (struct hunt_nic *) efx;
  223. size_t local_outlen_actual;
  224. if (outlen_actual == NULL)
  225. outlen_actual = &local_outlen_actual;
  226. ++hunt->mcdi.seqno;
  227. hunt_mcdi_copyin(hunt, cmd, (uint8_t *) inbuf, inlen);
  228. rc = hunt_mcdi_request_poll(hunt, quiet);
  229. if (rc != 0) {
  230. if (!quiet)
  231. DBGC(hunt, "MC response to cmd 0x%x: %s\n",
  232. cmd, strerror(rc));
  233. return rc;
  234. }
  235. *outlen_actual = hunt->mcdi.resp_data_len;
  236. hunt_mcdi_copyout(hunt, (uint8_t *) outbuf, outlen);
  237. return 0;
  238. }
  239. static int hunt_mcdi(struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
  240. {
  241. return _hunt_mcdi(&hunt->efx, req->emr_cmd,
  242. (const efx_dword_t *) req->emr_in_buf,
  243. req->emr_in_length,
  244. (efx_dword_t *) req->emr_out_buf, req->emr_out_length,
  245. &req->emr_out_length_used, false);
  246. }
  247. static int hunt_mcdi_quiet(struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
  248. {
  249. return _hunt_mcdi(&hunt->efx, req->emr_cmd,
  250. (const efx_dword_t *) req->emr_in_buf,
  251. req->emr_in_length,
  252. (efx_dword_t *) req->emr_out_buf, req->emr_out_length,
  253. &req->emr_out_length_used, true);
  254. }
  255. /*******************************************************************************
  256. *
  257. *
  258. * Hardware initialization
  259. *
  260. *
  261. ******************************************************************************/
  262. static int hunt_get_workarounds(struct hunt_nic *hunt, uint32_t *implemented,
  263. uint32_t *enabled)
  264. {
  265. struct efx_mcdi_req_s req;
  266. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_WORKAROUNDS_OUT_LEN);
  267. int rc;
  268. *implemented = *enabled = 0;
  269. req.emr_cmd = MC_CMD_GET_WORKAROUNDS;
  270. req.emr_in_buf = NULL;
  271. req.emr_in_length = 0;
  272. req.emr_out_buf = outbuf;
  273. req.emr_out_length = sizeof(outbuf);
  274. rc = hunt_mcdi(hunt, &req);
  275. if (rc)
  276. return rc;
  277. if (req.emr_out_length_used < MC_CMD_GET_WORKAROUNDS_OUT_LEN)
  278. return -EMSGSIZE;
  279. *implemented = MCDI_DWORD(outbuf, GET_WORKAROUNDS_OUT_IMPLEMENTED);
  280. *enabled = MCDI_DWORD(outbuf, GET_WORKAROUNDS_OUT_ENABLED);
  281. return 0;
  282. }
  283. static int hunt_enable_workaround_35388(struct hunt_nic *hunt)
  284. {
  285. struct efx_mcdi_req_s req;
  286. MCDI_DECLARE_BUF(payload, MC_CMD_WORKAROUND_IN_LEN);
  287. req.emr_cmd = MC_CMD_WORKAROUND;
  288. req.emr_in_buf = payload;
  289. req.emr_in_length = MC_CMD_WORKAROUND_IN_LEN;
  290. req.emr_out_buf = NULL;
  291. req.emr_out_length = 0;
  292. MCDI_SET_DWORD(req.emr_in_buf, WORKAROUND_IN_TYPE,
  293. MC_CMD_WORKAROUND_BUG35388);
  294. MCDI_SET_DWORD(req.emr_in_buf, WORKAROUND_IN_ENABLED, 1);
  295. /* If the firmware doesn't support this workaround, hunt_mcdi() will
  296. * return -EINVAL from hunt_mcdi_request_poll().
  297. */
  298. return hunt_mcdi(hunt, &req);
  299. }
  300. static int hunt_workaround_35388(struct hunt_nic *hunt)
  301. {
  302. uint32_t implemented, enabled;
  303. int rc = hunt_get_workarounds(hunt, &implemented, &enabled);
  304. if (rc < 0)
  305. return 0;
  306. if (!(implemented & MC_CMD_GET_WORKAROUNDS_OUT_BUG35388))
  307. return 0;
  308. if (enabled & MC_CMD_GET_WORKAROUNDS_OUT_BUG35388)
  309. return 1;
  310. rc = hunt_enable_workaround_35388(hunt);
  311. if (rc == 0)
  312. return 1; /* Workaround is enabled */
  313. else
  314. return 0;
  315. }
  316. static int hunt_get_port_assignment(struct hunt_nic *hunt)
  317. {
  318. struct efx_mcdi_req_s req;
  319. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
  320. int rc;
  321. req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
  322. req.emr_in_buf = NULL;
  323. req.emr_in_length = 0;
  324. req.emr_out_buf = outbuf;
  325. req.emr_out_length = sizeof(outbuf);
  326. rc = hunt_mcdi(hunt, &req);
  327. if (rc != 0)
  328. return rc;
  329. hunt->efx.port = MCDI_DWORD(req.emr_out_buf,
  330. GET_PORT_ASSIGNMENT_OUT_PORT);
  331. return 0;
  332. }
  333. static int hunt_mac_addr(struct hunt_nic *hunt, uint8_t *ll_addr)
  334. {
  335. struct efx_mcdi_req_s req;
  336. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
  337. int rc;
  338. req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
  339. req.emr_in_buf = NULL;
  340. req.emr_in_length = 0;
  341. req.emr_out_buf = outbuf;
  342. req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN;
  343. rc = hunt_mcdi(hunt, &req);
  344. if (rc != 0)
  345. return rc;
  346. if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)
  347. return -EMSGSIZE;
  348. memcpy(ll_addr,
  349. MCDI_PTR(req.emr_out_buf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE),
  350. ETH_ALEN);
  351. return 0;
  352. }
  353. static int hunt_get_phy_cfg(struct hunt_nic *hunt)
  354. {
  355. struct efx_mcdi_req_s req;
  356. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN);
  357. int rc;
  358. req.emr_cmd = MC_CMD_GET_PHY_CFG;
  359. req.emr_in_buf = NULL;
  360. req.emr_in_length = 0;
  361. req.emr_out_buf = outbuf;
  362. req.emr_out_length = sizeof(outbuf);
  363. rc = hunt_mcdi(hunt, &req);
  364. if (rc != 0)
  365. return rc;
  366. if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN)
  367. return -EMSGSIZE;
  368. hunt->phy_cap_mask = hunt->phy_cap =
  369. MCDI_DWORD(req.emr_out_buf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
  370. DBGC2(hunt, "GET_PHY_CFG: flags=%x, caps=%x\n", rc, hunt->phy_cap);
  371. return 0;
  372. }
  373. static int hunt_driver_attach(struct hunt_nic *hunt, int attach)
  374. {
  375. struct efx_mcdi_req_s req;
  376. MCDI_DECLARE_BUF(inbuf, MC_CMD_DRV_ATTACH_IN_LEN);
  377. MCDI_DECLARE_BUF(outbuf, MC_CMD_DRV_ATTACH_EXT_OUT_LEN);
  378. int rc;
  379. req.emr_cmd = MC_CMD_DRV_ATTACH;
  380. req.emr_in_buf = inbuf;
  381. req.emr_in_length = sizeof(inbuf);
  382. req.emr_out_buf = outbuf;
  383. req.emr_out_length = sizeof(outbuf);
  384. /* Set the PREBOOT flag to indicate later instances of attach should
  385. * force an ENTITY RESET
  386. */
  387. if (attach)
  388. attach |= 1 << MC_CMD_DRV_PREBOOT_LBN;
  389. MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_NEW_STATE, attach);
  390. MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_UPDATE, 1);
  391. MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_FIRMWARE_ID,
  392. MC_CMD_FW_DONT_CARE);
  393. rc = hunt_mcdi(hunt, &req);
  394. if (rc != 0)
  395. return rc;
  396. if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_OUT_LEN)
  397. return -EMSGSIZE;
  398. hunt->flags = MCDI_DWORD(outbuf, DRV_ATTACH_EXT_OUT_FUNC_FLAGS);
  399. return 0;
  400. }
  401. static int hunt_reset(struct hunt_nic *hunt)
  402. {
  403. struct efx_mcdi_req_s req;
  404. MCDI_DECLARE_BUF(inbuf, MC_CMD_ENTITY_RESET_IN_LEN);
  405. req.emr_cmd = MC_CMD_ENTITY_RESET;
  406. req.emr_in_buf = inbuf;
  407. req.emr_in_length = sizeof(inbuf);
  408. req.emr_out_buf = NULL;
  409. req.emr_out_length = 0;
  410. MCDI_POPULATE_DWORD_1(req.emr_in_buf, ENTITY_RESET_IN_FLAG,
  411. ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
  412. return hunt_mcdi(hunt, &req);
  413. }
  414. static void hunt_clear_udp_tunnel_ports(struct hunt_nic *hunt)
  415. {
  416. MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX);
  417. MCDI_DECLARE_BUF(outbuf, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN);
  418. struct efx_mcdi_req_s req;
  419. int rc;
  420. memset(inbuf, 0, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX);
  421. MCDI_SET_DWORD(inbuf, SET_TUNNEL_ENCAP_UDP_PORTS_IN_FLAGS,
  422. (1 << MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING_LBN));
  423. req.emr_cmd = MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS;
  424. req.emr_in_buf = inbuf;
  425. req.emr_in_length = sizeof(inbuf);
  426. req.emr_out_buf = outbuf;
  427. req.emr_out_length = sizeof(outbuf);
  428. rc = hunt_mcdi_quiet(hunt, &req);
  429. if (rc)
  430. return;
  431. if (MCDI_DWORD(outbuf, SET_TUNNEL_ENCAP_UDP_PORTS_OUT_FLAGS) &
  432. (1 << MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_LBN)) {
  433. DBGC(hunt,
  434. "Rebooting MC due to clearing UDP tunnel port list\n");
  435. /* Delay for the MC reboot to complete. */
  436. mdelay(100);
  437. }
  438. }
  439. static int hunt_set_mac(struct hunt_nic *hunt)
  440. {
  441. struct net_device *netdev = hunt->efx.netdev;
  442. struct efx_mcdi_req_s req;
  443. MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_IN_LEN);
  444. unsigned int fcntl;
  445. int rc;
  446. req.emr_cmd = MC_CMD_SET_MAC;
  447. req.emr_in_buf = payload;
  448. req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
  449. req.emr_out_buf = NULL;
  450. req.emr_out_length = 0;
  451. MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_MTU,
  452. EFX_MAC_FRAME_LEN(ETH_FRAME_LEN));
  453. MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_DRAIN, 0);
  454. memcpy(MCDI_PTR(req.emr_in_buf, SET_MAC_IN_ADDR),
  455. netdev->ll_addr, ETH_ALEN);
  456. MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_REJECT, 0);
  457. /* If the PHY supports autnegotiation, then configure the MAC to match
  458. * the negotiated settings. Otherwise force the MAC to TX and RX flow
  459. * control.
  460. */
  461. if (hunt->phy_cap_mask & (1 << MC_CMD_PHY_CAP_AN_LBN))
  462. fcntl = MC_CMD_FCNTL_AUTO;
  463. else
  464. fcntl = MC_CMD_FCNTL_BIDIR;
  465. MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_FCNTL, fcntl);
  466. rc = hunt_mcdi(hunt, &req);
  467. /* Ignore failure for permissions reasons */
  468. if (rc == -EPERM)
  469. rc = 0;
  470. return rc;
  471. }
  472. static int hunt_alloc_vis(struct hunt_nic *hunt)
  473. {
  474. struct efx_mcdi_req_s req;
  475. MCDI_DECLARE_BUF(inbuf, MC_CMD_ALLOC_VIS_IN_LEN);
  476. req.emr_cmd = MC_CMD_ALLOC_VIS;
  477. req.emr_in_buf = inbuf;
  478. req.emr_in_length = sizeof(inbuf);
  479. req.emr_out_buf = NULL;
  480. req.emr_out_length = 0;
  481. MCDI_SET_DWORD(req.emr_in_buf, ALLOC_VIS_IN_MIN_VI_COUNT, 1);
  482. MCDI_SET_DWORD(req.emr_in_buf, ALLOC_VIS_IN_MAX_VI_COUNT, 1);
  483. return hunt_mcdi(hunt, &req);
  484. }
  485. static void hunt_free_vis(struct hunt_nic *hunt)
  486. {
  487. struct efx_mcdi_req_s req;
  488. int rc;
  489. req.emr_cmd = MC_CMD_FREE_VIS;
  490. req.emr_in_buf = NULL;
  491. req.emr_in_length = 0;
  492. req.emr_out_buf = NULL;
  493. req.emr_out_length = 0;
  494. rc = hunt_mcdi(hunt, &req);
  495. if (rc != 0)
  496. DBGC(hunt, "MC_CMD_FREE_VIS Failed\n");
  497. }
  498. /*******************************************************************************
  499. *
  500. *
  501. * Link state handling
  502. *
  503. *
  504. ******************************************************************************/
  505. static int hunt_check_link(struct hunt_nic *hunt)
  506. {
  507. struct efx_mcdi_req_s req;
  508. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
  509. unsigned int flags, speed;
  510. bool up;
  511. int rc;
  512. static bool link_state = false;
  513. req.emr_cmd = MC_CMD_GET_LINK;
  514. req.emr_in_buf = NULL;
  515. req.emr_in_length = 0;
  516. req.emr_out_buf = outbuf;
  517. req.emr_out_length = sizeof(outbuf);
  518. rc = hunt_mcdi(hunt, &req);
  519. if (rc != 0)
  520. return rc;
  521. if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN)
  522. return -EMSGSIZE;
  523. flags = MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_FLAGS);
  524. up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
  525. speed = MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_LINK_SPEED);
  526. /* Set netdev_link_*() based on the link status from the MC */
  527. if (up && speed)
  528. netdev_link_up(hunt->efx.netdev);
  529. else
  530. netdev_link_down(hunt->efx.netdev);
  531. if (up != link_state) {
  532. DBGC(hunt, "Link %s, flags=%x, our caps=%x, lpa=%x, speed=%d, fcntl=%x, mac_fault=%x\n",
  533. (up? "up": "down"), flags,
  534. MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_CAP),
  535. MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_LP_CAP),
  536. speed,
  537. MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_FCNTL),
  538. MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_MAC_FAULT));
  539. link_state = up;
  540. }
  541. return 0;
  542. }
  543. #define MCDI_PORT_SPEED_CAPS ((1 << MC_CMD_PHY_CAP_10HDX_LBN) | \
  544. (1 << MC_CMD_PHY_CAP_10FDX_LBN) | \
  545. (1 << MC_CMD_PHY_CAP_100HDX_LBN) | \
  546. (1 << MC_CMD_PHY_CAP_100FDX_LBN) | \
  547. (1 << MC_CMD_PHY_CAP_1000HDX_LBN) | \
  548. (1 << MC_CMD_PHY_CAP_1000FDX_LBN) | \
  549. (1 << MC_CMD_PHY_CAP_10000FDX_LBN) | \
  550. (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
  551. /*******************************************************************************
  552. *
  553. *
  554. * TX
  555. *
  556. *
  557. ******************************************************************************/
  558. static int
  559. hunt_tx_init(struct net_device *netdev, struct hunt_nic *hunt)
  560. {
  561. struct efx_mcdi_req_s req;
  562. dma_addr_t dma_addr;
  563. efx_qword_t *addr;
  564. MCDI_DECLARE_BUF(inbuf,
  565. MC_CMD_INIT_TXQ_IN_LEN(EFX_TXQ_NBUFS(EFX_TXD_SIZE)));
  566. int rc, npages;
  567. rc = efx_hunt_tx_init(netdev, &dma_addr);
  568. if (rc != 0)
  569. return rc;
  570. npages = EFX_TXQ_NBUFS(EFX_TXD_SIZE);
  571. req.emr_cmd = MC_CMD_INIT_TXQ;
  572. req.emr_in_buf = inbuf;
  573. req.emr_in_length = MC_CMD_INIT_TXQ_IN_LEN(npages);
  574. req.emr_out_buf = NULL;
  575. req.emr_out_length = 0;
  576. MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_SIZE, EFX_TXD_SIZE);
  577. MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_TARGET_EVQ, 0);
  578. MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_LABEL, 0);
  579. MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_INSTANCE, 0);
  580. MCDI_POPULATE_DWORD_6(req.emr_in_buf, INIT_TXQ_IN_FLAGS,
  581. INIT_TXQ_IN_FLAG_BUFF_MODE, 0,
  582. INIT_TXQ_IN_FLAG_IP_CSUM_DIS, 1,
  583. INIT_TXQ_IN_FLAG_TCP_CSUM_DIS, 1,
  584. INIT_TXQ_IN_FLAG_TCP_UDP_ONLY, 0,
  585. INIT_TXQ_IN_CRC_MODE, 0,
  586. INIT_TXQ_IN_FLAG_TIMESTAMP, 0);
  587. MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_OWNER_ID, 0);
  588. MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_PORT_ID,
  589. EVB_PORT_ID_ASSIGNED);
  590. addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_TXQ_IN_DMA_ADDR);
  591. EFX_POPULATE_QWORD_2(*addr,
  592. EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
  593. EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
  594. return hunt_mcdi(hunt, &req);
  595. }
  596. static void hunt_tx_fini(struct hunt_nic *hunt)
  597. {
  598. struct efx_mcdi_req_s req;
  599. MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_TXQ_IN_LEN);
  600. struct efx_nic *efx = &hunt->efx;
  601. struct efx_tx_queue *txq = &efx->txq;
  602. int rc;
  603. req.emr_cmd = MC_CMD_FINI_TXQ;
  604. req.emr_in_buf = inbuf;
  605. req.emr_in_length = sizeof(inbuf);
  606. req.emr_out_buf = NULL;
  607. req.emr_out_length = 0;
  608. MCDI_SET_DWORD(req.emr_in_buf, FINI_TXQ_IN_INSTANCE, 0);
  609. rc = hunt_mcdi(hunt, &req);
  610. if (rc != 0)
  611. DBGC(hunt, "MC_CMD_FINI_TXQ Failed\n");
  612. efx_hunt_free_special_buffer(txq->ring,
  613. sizeof(efx_tx_desc_t) * EFX_TXD_SIZE);
  614. txq->ring = NULL;
  615. }
  616. /*******************************************************************************
  617. *
  618. *
  619. * RX
  620. *
  621. *
  622. ******************************************************************************/
  623. static int hunt_rx_filter_insert(struct net_device *netdev,
  624. struct hunt_nic *hunt,
  625. int multicast)
  626. {
  627. struct efx_mcdi_req_s req;
  628. MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_IN_LEN);
  629. MCDI_DECLARE_BUF(outbuf, MC_CMD_FILTER_OP_OUT_LEN);
  630. int rc;
  631. uint64_t filter_id;
  632. (void) netdev;
  633. req.emr_cmd = MC_CMD_FILTER_OP;
  634. req.emr_in_buf = inbuf;
  635. req.emr_in_length = sizeof(inbuf);
  636. req.emr_out_buf = outbuf;
  637. req.emr_out_length = sizeof(outbuf);
  638. MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_OP,
  639. multicast ? MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE
  640. : MC_CMD_FILTER_OP_IN_OP_INSERT);
  641. MCDI_POPULATE_DWORD_1(req.emr_in_buf, FILTER_OP_IN_MATCH_FIELDS,
  642. FILTER_OP_IN_MATCH_DST_MAC, 1);
  643. if (multicast)
  644. memset(MCDI_PTR(req.emr_in_buf, FILTER_OP_IN_DST_MAC),
  645. 0xff, ETH_ALEN);
  646. else
  647. memcpy(MCDI_PTR(req.emr_in_buf, FILTER_OP_IN_DST_MAC),
  648. hunt->mac, ETH_ALEN);
  649. MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_PORT_ID,
  650. EVB_PORT_ID_ASSIGNED);
  651. MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_DEST,
  652. MC_CMD_FILTER_OP_IN_RX_DEST_HOST);
  653. MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_QUEUE, 0);
  654. MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_MODE, 0);
  655. MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_TX_DEST,
  656. MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT);
  657. rc = hunt_mcdi(hunt, &req);
  658. if (rc != 0)
  659. return rc;
  660. if (req.emr_out_length_used < MC_CMD_FILTER_OP_OUT_LEN)
  661. return -EIO;
  662. filter_id = MCDI_QWORD(req.emr_out_buf, FILTER_OP_OUT_HANDLE);
  663. if (multicast)
  664. hunt->mc_filter_id = filter_id;
  665. else
  666. hunt->uc_filter_id = filter_id;
  667. return 0;
  668. }
  669. static int hunt_rx_filter_remove(struct hunt_nic *hunt,
  670. int multicast)
  671. {
  672. struct efx_mcdi_req_s req;
  673. MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_IN_LEN);
  674. req.emr_cmd = MC_CMD_FILTER_OP;
  675. req.emr_in_buf = inbuf;
  676. req.emr_in_length = sizeof(inbuf);
  677. req.emr_out_buf = NULL;
  678. req.emr_out_length = 0;
  679. MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_OP,
  680. multicast ? MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE :
  681. MC_CMD_FILTER_OP_IN_OP_REMOVE);
  682. MCDI_SET_QWORD(req.emr_in_buf, FILTER_OP_IN_HANDLE,
  683. multicast ? hunt->mc_filter_id :
  684. hunt->uc_filter_id);
  685. return hunt_mcdi(hunt, &req);
  686. }
  687. static int hunt_get_mac(struct hunt_nic *hunt)
  688. {
  689. struct efx_mcdi_req_s req;
  690. MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
  691. int rc;
  692. req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
  693. req.emr_in_buf = NULL;
  694. req.emr_in_length = 0;
  695. req.emr_out_buf = outbuf;
  696. req.emr_out_length = sizeof(outbuf);
  697. rc = hunt_mcdi(hunt, &req);
  698. if (rc != 0)
  699. return rc;
  700. if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN)
  701. return -EMSGSIZE;
  702. memcpy(hunt->mac, MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE),
  703. ETH_ALEN);
  704. return 0;
  705. }
  706. static int hunt_rx_filter_init(struct net_device *netdev,
  707. struct hunt_nic *hunt)
  708. {
  709. int rc = hunt_get_mac(hunt);
  710. if (rc != 0)
  711. return rc;
  712. rc = hunt_rx_filter_insert(netdev, hunt, 0);
  713. if (rc != 0)
  714. return rc;
  715. rc = hunt_rx_filter_insert(netdev, hunt, 1);
  716. if (rc != 0)
  717. hunt_rx_filter_remove(hunt, 0);
  718. return rc;
  719. }
  720. static int
  721. hunt_rx_init(struct net_device *netdev,
  722. struct hunt_nic *hunt)
  723. {
  724. struct efx_mcdi_req_s req;
  725. dma_addr_t dma_addr;
  726. efx_qword_t *addr;
  727. MCDI_DECLARE_BUF(inbuf,
  728. MC_CMD_INIT_RXQ_IN_LEN(EFX_RXQ_NBUFS(EFX_RXD_SIZE)));
  729. int rc, npages;
  730. rc = efx_hunt_rx_init(netdev, &dma_addr);
  731. if (rc != 0)
  732. return rc;
  733. npages = EFX_RXQ_NBUFS(EFX_RXD_SIZE);
  734. req.emr_cmd = MC_CMD_INIT_RXQ;
  735. req.emr_in_buf = inbuf;
  736. req.emr_in_length = MC_CMD_INIT_RXQ_IN_LEN(npages);
  737. req.emr_out_buf = NULL;
  738. req.emr_out_length = 0;
  739. MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_SIZE, EFX_RXD_SIZE);
  740. MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_TARGET_EVQ, 0);
  741. MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_LABEL, 0);
  742. MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_INSTANCE, 0);
  743. MCDI_POPULATE_DWORD_5(req.emr_in_buf, INIT_RXQ_IN_FLAGS,
  744. INIT_RXQ_IN_FLAG_BUFF_MODE, 0,
  745. INIT_RXQ_IN_FLAG_HDR_SPLIT, 0,
  746. INIT_RXQ_IN_FLAG_TIMESTAMP, 0,
  747. INIT_RXQ_IN_CRC_MODE, 0,
  748. INIT_RXQ_IN_FLAG_PREFIX, 1);
  749. MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_OWNER_ID, 0);
  750. MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_PORT_ID,
  751. EVB_PORT_ID_ASSIGNED);
  752. addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_RXQ_IN_DMA_ADDR);
  753. EFX_POPULATE_QWORD_2(*addr,
  754. EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
  755. EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
  756. return hunt_mcdi(hunt, &req);
  757. }
  758. static void hunt_rx_filter_fini(struct hunt_nic *hunt)
  759. {
  760. hunt_rx_filter_remove(hunt, 0);
  761. hunt_rx_filter_remove(hunt, 1);
  762. }
  763. static void hunt_rx_fini(struct hunt_nic *hunt)
  764. {
  765. MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_RXQ_IN_LEN);
  766. struct efx_mcdi_req_s req;
  767. struct efx_nic *efx = &hunt->efx;
  768. struct efx_rx_queue *rxq = &efx->rxq;
  769. int rc;
  770. req.emr_cmd = MC_CMD_FINI_RXQ;
  771. req.emr_in_buf = inbuf;
  772. req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN;
  773. req.emr_out_buf = NULL;
  774. req.emr_out_length = 0;
  775. MCDI_SET_DWORD(req.emr_in_buf, FINI_RXQ_IN_INSTANCE, 0);
  776. rc = hunt_mcdi(hunt, &req);
  777. if (rc != 0)
  778. DBGC(hunt, "MC_CMD_FINI_RXQ Failed\n");
  779. efx_hunt_free_special_buffer(rxq->ring,
  780. sizeof(efx_rx_desc_t) * EFX_RXD_SIZE);
  781. rxq->ring = NULL;
  782. }
  783. /*******************************************************************************
  784. *
  785. *
  786. * Event queues and interrupts
  787. *
  788. *
  789. ******************************************************************************/
  790. static int
  791. hunt_ev_init(struct net_device *netdev,
  792. struct hunt_nic *hunt)
  793. {
  794. struct efx_mcdi_req_s req;
  795. dma_addr_t dma_addr;
  796. efx_qword_t *addr;
  797. MCDI_DECLARE_BUF(inbuf,
  798. MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_SIZE)));
  799. MCDI_DECLARE_BUF(outbuf, MC_CMD_INIT_EVQ_OUT_LEN);
  800. int rc, npages;
  801. rc = efx_hunt_ev_init(netdev, &dma_addr);
  802. if (rc != 0)
  803. return rc;
  804. npages = EFX_EVQ_NBUFS(EFX_EVQ_SIZE);
  805. req.emr_cmd = MC_CMD_INIT_EVQ;
  806. req.emr_in_buf = inbuf;
  807. req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
  808. req.emr_out_buf = outbuf;
  809. req.emr_out_length = sizeof(outbuf);
  810. MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_SIZE, EFX_EVQ_SIZE);
  811. MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_INSTANCE, 0);
  812. MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_IRQ_NUM, 0);
  813. MCDI_POPULATE_DWORD_6(req.emr_in_buf, INIT_EVQ_IN_FLAGS,
  814. INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
  815. INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
  816. INIT_EVQ_IN_FLAG_INT_ARMD, 0,
  817. INIT_EVQ_IN_FLAG_CUT_THRU, 0,
  818. INIT_EVQ_IN_FLAG_RX_MERGE, 0,
  819. INIT_EVQ_IN_FLAG_TX_MERGE, 0);
  820. MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_MODE,
  821. MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS);
  822. MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_LOAD, 0);
  823. MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_RELOAD, 0);
  824. MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_COUNT_MODE,
  825. MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS);
  826. MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_COUNT_THRSHLD, 0);
  827. addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_EVQ_IN_DMA_ADDR);
  828. EFX_POPULATE_QWORD_2(*addr,
  829. EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
  830. EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
  831. rc = hunt_mcdi(hunt, &req);
  832. if (rc != 0)
  833. return rc;
  834. if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN)
  835. return -EMSGSIZE;
  836. return 0;
  837. }
  838. static void hunt_ev_fini(struct hunt_nic *hunt)
  839. {
  840. MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_EVQ_IN_LEN);
  841. struct efx_mcdi_req_s req;
  842. struct efx_nic *efx = &hunt->efx;
  843. struct efx_ev_queue *evq = &efx->evq;
  844. int rc;
  845. req.emr_cmd = MC_CMD_FINI_EVQ;
  846. req.emr_in_buf = inbuf;
  847. req.emr_in_length = sizeof(inbuf);
  848. req.emr_out_buf = NULL;
  849. req.emr_out_length = 0;
  850. MCDI_SET_DWORD(req.emr_in_buf, FINI_EVQ_IN_INSTANCE, 0);
  851. rc = hunt_mcdi(hunt, &req);
  852. if (rc != 0)
  853. DBGC(hunt, "MC_CMD_FINI_EVQ Failed\n");
  854. efx_hunt_free_special_buffer(evq->ring,
  855. sizeof(efx_event_t) * EFX_EVQ_SIZE);
  856. evq->ring = NULL;
  857. }
  858. static void
  859. hunt_poll(struct net_device *netdev)
  860. {
  861. struct hunt_nic *hunt = netdev_priv(netdev);
  862. /* If called while already polling, return immediately */
  863. if (hunt->efx.state & EFX_STATE_POLLING)
  864. return;
  865. hunt->efx.state |= EFX_STATE_POLLING;
  866. /* Poll link state */
  867. if (hunt->link_poll_timer + TICKS_PER_SEC < currticks()) {
  868. hunt->link_poll_timer = currticks();
  869. hunt_check_link(hunt);
  870. }
  871. /* Poll data path */
  872. efx_hunt_poll(netdev);
  873. hunt->efx.state &= ~EFX_STATE_POLLING;
  874. }
  875. /*******************************************************************************
  876. *
  877. *
  878. * Netdevice operations
  879. *
  880. *
  881. ******************************************************************************/
  882. static int hunt_open(struct net_device *netdev)
  883. {
  884. struct hunt_nic *hunt = netdev_priv(netdev);
  885. int rc;
  886. /* Allocate VIs */
  887. rc = hunt_alloc_vis(hunt);
  888. if (rc != 0)
  889. goto fail2;
  890. /* Initialize data path */
  891. rc = hunt_ev_init(netdev, hunt);
  892. if (rc != 0)
  893. goto fail3;
  894. rc = hunt_rx_init(netdev, hunt);
  895. if (rc != 0)
  896. goto fail4;
  897. rc = hunt_rx_filter_init(netdev, hunt);
  898. if (rc != 0)
  899. goto fail5;
  900. rc = hunt_tx_init(netdev, hunt);
  901. if (rc != 0)
  902. goto fail6;
  903. rc = efx_hunt_open(netdev);
  904. if (rc)
  905. goto fail7;
  906. rc = hunt_set_mac(hunt);
  907. if (rc)
  908. goto fail8;
  909. /* Mark the link as down before checking the link state because the
  910. * latter might fail.
  911. */
  912. netdev_link_down(netdev);
  913. hunt_check_link(hunt);
  914. DBGC2(hunt, "%s: open ok\n", netdev->name);
  915. return 0;
  916. fail8:
  917. efx_hunt_close(netdev);
  918. fail7:
  919. hunt_tx_fini(hunt);
  920. fail6:
  921. hunt_rx_filter_fini(hunt);
  922. fail5:
  923. hunt_rx_fini(hunt);
  924. fail4:
  925. hunt_ev_fini(hunt);
  926. fail3:
  927. hunt_free_vis(hunt);
  928. fail2:
  929. DBGC2(hunt, "%s: %s\n", netdev->name, strerror(rc));
  930. return rc;
  931. }
  932. static void hunt_close(struct net_device *netdev)
  933. {
  934. struct hunt_nic *hunt = netdev_priv(netdev);
  935. /* Stop datapath */
  936. efx_hunt_close(netdev);
  937. hunt_tx_fini(hunt);
  938. hunt_rx_fini(hunt);
  939. hunt_rx_filter_fini(hunt);
  940. hunt_ev_fini(hunt);
  941. hunt_free_vis(hunt);
  942. /* Reset hardware and detach */
  943. hunt_reset(hunt);
  944. }
  945. /*******************************************************************************
  946. *
  947. *
  948. * Public operations
  949. *
  950. *
  951. ******************************************************************************/
  952. static struct net_device_operations hunt_operations = {
  953. .open = hunt_open,
  954. .close = hunt_close,
  955. .transmit = efx_hunt_transmit,
  956. .poll = hunt_poll,
  957. .irq = efx_hunt_irq,
  958. };
  959. static int
  960. hunt_probe(struct pci_device *pci)
  961. {
  962. struct net_device *netdev;
  963. struct hunt_nic *hunt;
  964. struct efx_nic *efx;
  965. int rc = 0;
  966. /* Create the network adapter */
  967. netdev = alloc_etherdev(sizeof(struct hunt_nic));
  968. if (!netdev) {
  969. rc = -ENOMEM;
  970. goto fail1;
  971. }
  972. /* Initialise the network adapter, and initialise private storage */
  973. netdev_init(netdev, &hunt_operations);
  974. pci_set_drvdata(pci, netdev);
  975. netdev->dev = &pci->dev;
  976. netdev->state |= NETDEV_IRQ_UNSUPPORTED;
  977. hunt = netdev_priv(netdev);
  978. memset(hunt, 0, sizeof(*hunt));
  979. efx = &hunt->efx;
  980. efx->type = &hunt_nic_type;
  981. /* Initialise efx datapath */
  982. efx_probe(netdev, EFX_HUNTINGTON);
  983. /* Initialise MCDI. In case we are recovering from a crash, first
  984. * cancel any outstanding request by sending a special message using the
  985. * least significant bits of the 'high' (doorbell) register.
  986. */
  987. _efx_writel(efx, cpu_to_le32(1), ER_DZ_MC_DB_HWRD);
  988. rc = hunt_mcdi_init(hunt);
  989. if (rc != 0)
  990. goto fail2;
  991. /* Reset (most) configuration for this function */
  992. rc = hunt_reset(hunt);
  993. if (rc != 0)
  994. goto fail3;
  995. /* Medford has a list of UDP tunnel ports that is populated by the
  996. * driver. Avoid dropping any unencapsulated packets. This may cause
  997. * an MC reboot.
  998. */
  999. hunt_clear_udp_tunnel_ports(hunt);
  1000. /* Enable the workaround for bug35388, if supported */
  1001. efx->workaround_35388 = hunt_workaround_35388(hunt);
  1002. /* Set the RX packet prefix size */
  1003. efx->rx_prefix_size = ES_DZ_RX_PREFIX_SIZE;
  1004. rc = hunt_get_port_assignment(hunt);
  1005. if (rc != 0)
  1006. goto fail3;
  1007. rc = hunt_mac_addr(hunt, netdev->ll_addr);
  1008. if (rc != 0)
  1009. goto fail4;
  1010. rc = hunt_get_phy_cfg(hunt);
  1011. if (rc != 0)
  1012. goto fail5;
  1013. rc = hunt_driver_attach(hunt, 1);
  1014. if (rc != 0)
  1015. goto fail5;
  1016. /* If not exposing this network device, return successfully here */
  1017. if (hunt->flags & (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT))
  1018. return 0;
  1019. if (hunt_nic_is_primary(hunt)) {
  1020. hunt->next_primary = primary_nics;
  1021. primary_nics = hunt;
  1022. hunt->primary = hunt;
  1023. } else {
  1024. struct hunt_nic *other_hunt = primary_nics;
  1025. while (other_hunt && !hunt->primary) {
  1026. struct pci_device *other_pci = (struct pci_device *)
  1027. other_hunt->efx.netdev->dev;
  1028. /* Check if the seg:bus:dev parts match. */
  1029. if (PCI_FIRST_FUNC(other_pci->busdevfn) ==
  1030. PCI_FIRST_FUNC(pci->busdevfn))
  1031. hunt->primary = other_hunt;
  1032. other_hunt = other_hunt->next_primary;
  1033. }
  1034. if (!hunt->primary) {
  1035. rc = -EIO;
  1036. goto fail6;
  1037. }
  1038. }
  1039. rc = register_netdev(netdev);
  1040. if (rc != 0)
  1041. goto fail8;
  1042. DBG2("%s " PCI_FMT " ok\n", __func__, PCI_ARGS(pci));
  1043. return 0;
  1044. fail8:
  1045. fail6:
  1046. (void) hunt_driver_attach(hunt, 0);
  1047. fail5:
  1048. fail4:
  1049. fail3:
  1050. hunt_mcdi_fini(hunt);
  1051. fail2:
  1052. efx_remove(netdev);
  1053. netdev_put(netdev);
  1054. fail1:
  1055. DBG2("%s " PCI_FMT " rc=%d\n", __func__, PCI_ARGS(pci), rc);
  1056. return rc;
  1057. }
  1058. static void hunt_remove(struct pci_device *pci)
  1059. {
  1060. struct net_device *netdev = pci_get_drvdata(pci);
  1061. struct hunt_nic *hunt = netdev_priv(netdev);
  1062. if (!(hunt->flags &
  1063. (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT))) {
  1064. /* The netdevice might still be open, so unregister it now
  1065. * before ripping stuff out from underneath.
  1066. */
  1067. unregister_netdev(netdev);
  1068. }
  1069. (void)hunt_driver_attach(hunt, 0);
  1070. hunt_mcdi_fini(hunt);
  1071. /* Destroy data path */
  1072. efx_remove(netdev);
  1073. netdev_nullify(netdev);
  1074. netdev_put(netdev);
  1075. }
  1076. const struct efx_nic_type hunt_nic_type = {
  1077. .mcdi_rpc = _hunt_mcdi,
  1078. };
  1079. static struct pci_device_id hunt_nics[] = {
  1080. PCI_ROM(0x1924, 0x0a03, "SFC9220", "Solarflare SFN8xxx Adapter", 0),
  1081. };
  1082. struct pci_driver hunt_driver __pci_driver = {
  1083. .ids = hunt_nics,
  1084. .id_count = ARRAY_SIZE(hunt_nics),
  1085. .probe = hunt_probe,
  1086. .remove = hunt_remove,
  1087. };