iPXE
sfc_hunt.c
Go to the documentation of this file.
1 /**************************************************************************
2  *
3  * Device driver for Solarflare Communications EF10 devices
4  *
5  * Written by Shradha Shah, maintained by <pre-boot-drivers@xilinx.com>
6  *
7  * Copyright 2012-2019 Solarflare Communications Inc.
8  * Copyright 2019-2020 Xilinx Inc.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of the
13  * License, or any later version.
14  *
15  * You can also choose to distribute this program under the terms of
16  * the Unmodified Binary Distribution Licence (as given in the file
17  * COPYING.UBDL), provided that you have satisfied its requirements.
18  *
19  ***************************************************************************/
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <byteswap.h>
26 #include <ipxe/io.h>
27 #include <ipxe/pci.h>
28 #include <ipxe/malloc.h>
29 #include <ipxe/ethernet.h>
30 #include <ipxe/iobuf.h>
31 #include <ipxe/netdevice.h>
32 #include "efx_hunt.h"
33 #include "efx_bitfield.h"
34 #include "ef10_regs.h"
35 #include "mc_driver_pcol.h"
36 #include <ipxe/if_ether.h>
37 
38 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
39 
40 #define HUNTINGTON_NVRAM_CHUNK 0x80
41 #define HUNTINGTON_NVS_MAX_LENGTH 0x1000
42 
43 #define EMCDI_IO(code) EUNIQ(EINFO_EIO, (code))
44 
45 #ifndef MIN
46 #define MIN(a, b) ((a) < (b) ? (a) : (b))
47 #endif
48 #ifndef MAX
49 #define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
50 #endif
51 
53 
54 struct hunt_nic {
55  struct efx_nic efx;
56 
57  /* PHY information */
58  unsigned int phy_cap_mask;
59  unsigned int phy_cap;
60  unsigned long link_poll_timer;
61 
62  /* resource housekeeping */
66 
67  struct {
68  /* Common payload for all MCDI requests */
69  unsigned int seqno;
70 
71  size_t resp_hdr_len;
72  size_t resp_data_len;
73 
74  struct io_buffer *iob;
76  } mcdi;
77 
78  struct hunt_nic *primary;
81 };
82 
83 static int hunt_nic_is_primary(struct hunt_nic *hunt)
84 {
85  return (hunt->flags & (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY));
86 }
87 
88 /*******************************************************************************
89  *
90  *
91  * MCDI transport
92  *
93  * This has been based on the implementation of MCDI in the common code driver.
94  *
95  *
96  ******************************************************************************/
97 
98 static int hunt_mcdi_init(struct hunt_nic *hunt)
99 {
100  size_t max_msg_size;
101  int rc;
102 
103  /* The MCDI message has two 32-bit headers (the MCDI header and the
104  * MCDI v2 extended command) and then up to MCDI_CTL_SDU_LEN_MAX_V2
105  * bytes of payload
106  */
107  max_msg_size = 2 * sizeof(efx_dword_t) + MCDI_CTL_SDU_LEN_MAX_V2;
108 
109  hunt->mcdi.iob = alloc_iob(max_msg_size);
110  if (!hunt->mcdi.iob) {
111  rc = -ENOMEM;
112  return rc;
113  }
114  return 0;
115 }
116 
117 static void hunt_mcdi_copyin(struct hunt_nic *hunt,
118  unsigned int cmd,
119  uint8_t *inbuf,
120  size_t inlen)
121 {
122  efx_dword_t hdr[2];
123  uint32_t seqno;
124  unsigned int xflags;
125  size_t hdr_len;
126  u8 *pdu = hunt->mcdi.iob->data;
127 
128  seqno = hunt->mcdi.seqno & MCDI_SEQ_MASK;
129 
130  xflags = 0;
131 
133  MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
134  MCDI_HEADER_RESYNC, 1,
135  MCDI_HEADER_DATALEN, 0,
136  MCDI_HEADER_SEQ, seqno,
137  MCDI_HEADER_ERROR, 0,
138  MCDI_HEADER_RESPONSE, 0,
139  MCDI_HEADER_XFLAGS, xflags);
141  MC_CMD_V2_EXTN_IN_EXTENDED_CMD, cmd,
142  MC_CMD_V2_EXTN_IN_ACTUAL_LEN, inlen);
143 
144  hdr_len = sizeof(hdr);
145 
146  memcpy(pdu, &hdr, hdr_len);
148  memcpy(pdu + hdr_len, inbuf, inlen);
149 
150  wmb(); /* Sync the data before ringing the doorbell */
151 
152  /* Ring the doorbell to post the command DMA address to the MC */
153  hunt->mcdi.dma_addr = virt_to_bus(hunt->mcdi.iob->data);
154 
155  assert((hunt->mcdi.dma_addr & 0xFF) == 0);
156 
157  _efx_writel(&hunt->efx,
158  cpu_to_le32((u64)hunt->mcdi.dma_addr >> 32),
160 
161  _efx_writel(&hunt->efx,
162  cpu_to_le32((u32)hunt->mcdi.dma_addr),
164 }
165 
166 static void hunt_mcdi_copyout(struct hunt_nic *hunt,
167  uint8_t *outbuf, size_t outlen)
168 {
169  size_t offset;
170  const u8 *pdu = hunt->mcdi.iob->data;
171 
172  offset = hunt->mcdi.resp_hdr_len;
173 
174  if (outlen > 0)
175  memcpy(outbuf, pdu+offset, outlen);
176 }
177 
178 static int hunt_mcdi_request_poll(struct hunt_nic *hunt, bool quiet)
179 {
180  unsigned int resplen, respseq, error;
181  unsigned long finish;
182  efx_dword_t errdword;
183  efx_qword_t qword;
184  const efx_dword_t *pdu = hunt->mcdi.iob->data;
185  const u8 *pdu1 = hunt->mcdi.iob->data;
186  int delay, rc;
187 
188  /* Spin for up to 5s, polling at intervals of 10us, 20us, ... ~100ms */
189  finish = currticks() + (5 * TICKS_PER_SEC);
190  delay = 10;
191  while (1) {
192  udelay(delay);
193 
194  /* Check for an MCDI response */
195  if (EFX_DWORD_FIELD(*pdu, MCDI_HEADER_RESPONSE))
196  break;
197 
198  if (currticks() >= finish)
199  return -ETIMEDOUT;
200 
201  if (delay < 100000)
202  delay *= 2;
203  }
204 
205  memcpy(&qword, pdu1, 8);
206 
207  /* qword.dword[0] is the MCDI header; qword.dword[1] is the MCDI v2
208  * extended command
209  */
210  respseq = EFX_DWORD_FIELD(qword.dword[0], MCDI_HEADER_SEQ);
211  error = EFX_DWORD_FIELD(qword.dword[0], MCDI_HEADER_ERROR);
212  resplen = EFX_DWORD_FIELD(qword.dword[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
213 
214  if (error && resplen == 0) {
215  if (!quiet)
216  DBGC(hunt, "MC rebooted\n");
217  return -EIO;
218  } else if ((respseq ^ hunt->mcdi.seqno) & MCDI_SEQ_MASK) {
219  if (!quiet)
220  DBGC(hunt, "MC response mismatch rxseq 0x%x txseq "
221  "0x%x\n", respseq, hunt->mcdi.seqno);
222  return -EIO;
223  } else if (error) {
224  memcpy(&errdword, pdu1 + 8, 4);
225  rc = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
226  switch (rc) {
227  case MC_CMD_ERR_ENOENT:
228  return -ENOENT;
229  case MC_CMD_ERR_EINTR:
230  return -EINTR;
231  case MC_CMD_ERR_EACCES:
232  return -EACCES;
233  case MC_CMD_ERR_EBUSY:
234  return -EBUSY;
235  case MC_CMD_ERR_EINVAL:
236  return -EINVAL;
237  case MC_CMD_ERR_EDEADLK:
238  return -EDEADLK;
239  case MC_CMD_ERR_ENOSYS:
240  return -ENOSYS;
241  case MC_CMD_ERR_ETIME:
242  return -ETIME;
243  case MC_CMD_ERR_EPERM:
244  return -EPERM;
245  default:
246  /* Return the MC error in an I/O error. */
247  return EMCDI_IO(rc & 0xff);
248  }
249  }
250  hunt->mcdi.resp_hdr_len = 8;
251  hunt->mcdi.resp_data_len = resplen;
252 
253  return 0;
254 }
255 
256 static void hunt_mcdi_fini(struct hunt_nic *hunt)
257 {
258  free_iob(hunt->mcdi.iob);
259 }
260 
261 int _hunt_mcdi(struct efx_nic *efx, unsigned int cmd,
262  const efx_dword_t *inbuf, size_t inlen,
263  efx_dword_t *outbuf, size_t outlen,
264  size_t *outlen_actual, bool quiet)
265 {
266  int rc;
267  struct hunt_nic *hunt = (struct hunt_nic *) efx;
268  size_t local_outlen_actual;
269 
270  if (outlen_actual == NULL)
271  outlen_actual = &local_outlen_actual;
272 
273  ++hunt->mcdi.seqno;
274  hunt_mcdi_copyin(hunt, cmd, (uint8_t *) inbuf, inlen);
275 
276  rc = hunt_mcdi_request_poll(hunt, quiet);
277  if (rc != 0) {
278  if (!quiet)
279  DBGC(hunt, "MC response to cmd 0x%x: %s\n",
280  cmd, strerror(rc));
281  return rc;
282  }
283 
284  *outlen_actual = hunt->mcdi.resp_data_len;
285 
286  hunt_mcdi_copyout(hunt, (uint8_t *) outbuf, outlen);
287 
288  return 0;
289 }
290 
291 static int hunt_mcdi(struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
292 {
293  return _hunt_mcdi(&hunt->efx, req->emr_cmd,
294  (const efx_dword_t *) req->emr_in_buf,
295  req->emr_in_length,
296  (efx_dword_t *) req->emr_out_buf, req->emr_out_length,
297  &req->emr_out_length_used, false);
298 }
299 
300 static int hunt_mcdi_quiet(struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
301 {
302  return _hunt_mcdi(&hunt->efx, req->emr_cmd,
303  (const efx_dword_t *) req->emr_in_buf,
304  req->emr_in_length,
305  (efx_dword_t *) req->emr_out_buf, req->emr_out_length,
306  &req->emr_out_length_used, true);
307 }
308 
309 /*******************************************************************************
310  *
311  *
312  * Hardware initialization
313  *
314  *
315  ******************************************************************************/
316 static int hunt_get_workarounds(struct hunt_nic *hunt, uint32_t *implemented,
317  uint32_t *enabled)
318 {
319  struct efx_mcdi_req_s req;
321  int rc;
322 
323  *implemented = *enabled = 0;
324 
326  req.emr_in_buf = NULL;
327  req.emr_in_length = 0;
328  req.emr_out_buf = outbuf;
329  req.emr_out_length = sizeof(outbuf);
330 
331  rc = hunt_mcdi(hunt, &req);
332 
333  if (rc)
334  return rc;
335 
337  return -EMSGSIZE;
338 
339  *implemented = MCDI_DWORD(outbuf, GET_WORKAROUNDS_OUT_IMPLEMENTED);
340  *enabled = MCDI_DWORD(outbuf, GET_WORKAROUNDS_OUT_ENABLED);
341  return 0;
342 }
343 
344 static int hunt_enable_workaround_35388(struct hunt_nic *hunt)
345 {
346  struct efx_mcdi_req_s req;
348 
350  req.emr_in_buf = payload;
352  req.emr_out_buf = NULL;
353  req.emr_out_length = 0;
354 
355  MCDI_SET_DWORD(req.emr_in_buf, WORKAROUND_IN_TYPE,
357  MCDI_SET_DWORD(req.emr_in_buf, WORKAROUND_IN_ENABLED, 1);
358 
359  /* If the firmware doesn't support this workaround, hunt_mcdi() will
360  * return -EINVAL from hunt_mcdi_request_poll().
361  */
362  return hunt_mcdi(hunt, &req);
363 }
364 
365 static int hunt_workaround_35388(struct hunt_nic *hunt)
366 {
367  uint32_t implemented, enabled;
368  int rc = hunt_get_workarounds(hunt, &implemented, &enabled);
369 
370  if (rc < 0)
371  return 0;
372  if (!(implemented & MC_CMD_GET_WORKAROUNDS_OUT_BUG35388))
373  return 0;
375  return 1;
376 
378  if (rc == 0)
379  return 1; /* Workaround is enabled */
380  else
381  return 0;
382 }
383 
384 static int hunt_get_port_assignment(struct hunt_nic *hunt)
385 {
386  struct efx_mcdi_req_s req;
388  int rc;
389 
391  req.emr_in_buf = NULL;
392  req.emr_in_length = 0;
393  req.emr_out_buf = outbuf;
394  req.emr_out_length = sizeof(outbuf);
395 
396  rc = hunt_mcdi(hunt, &req);
397  if (rc != 0)
398  return rc;
399 
400  hunt->efx.port = MCDI_DWORD(req.emr_out_buf,
401  GET_PORT_ASSIGNMENT_OUT_PORT);
402  return 0;
403 }
404 
405 static int hunt_mac_addr(struct hunt_nic *hunt, uint8_t *ll_addr)
406 {
407  struct efx_mcdi_req_s req;
409  int rc;
410 
412  req.emr_in_buf = NULL;
413  req.emr_in_length = 0;
414  req.emr_out_buf = outbuf;
416 
417  rc = hunt_mcdi(hunt, &req);
418  if (rc != 0)
419  return rc;
420 
422  return -EMSGSIZE;
423 
424  memcpy(ll_addr,
425  MCDI_PTR(req.emr_out_buf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE),
426  ETH_ALEN);
427 
428  return 0;
429 }
430 
431 static int hunt_get_phy_cfg(struct hunt_nic *hunt)
432 {
433  struct efx_mcdi_req_s req;
435  int rc;
436 
438  req.emr_in_buf = NULL;
439  req.emr_in_length = 0;
440  req.emr_out_buf = outbuf;
441  req.emr_out_length = sizeof(outbuf);
442 
443  rc = hunt_mcdi(hunt, &req);
444  if (rc != 0)
445  return rc;
446 
448  return -EMSGSIZE;
449 
450  hunt->phy_cap_mask = hunt->phy_cap =
451  MCDI_DWORD(req.emr_out_buf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
452  DBGC2(hunt, "GET_PHY_CFG: flags=%x, caps=%x\n", rc, hunt->phy_cap);
453  return 0;
454 }
455 
456 static int hunt_driver_attach(struct hunt_nic *hunt, int attach)
457 {
458  struct efx_mcdi_req_s req;
461  int rc;
462 
464  req.emr_in_buf = inbuf;
465  req.emr_in_length = sizeof(inbuf);
466  req.emr_out_buf = outbuf;
467  req.emr_out_length = sizeof(outbuf);
468 
469  /* Set the PREBOOT flag to indicate later instances of attach should
470  * force an ENTITY RESET
471  */
472  if (attach)
473  attach |= 1 << MC_CMD_DRV_PREBOOT_LBN;
474 
475  MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_NEW_STATE, attach);
476  MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_UPDATE, 1);
477  MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_FIRMWARE_ID,
479 
480  rc = hunt_mcdi(hunt, &req);
481  if (rc != 0)
482  return rc;
483 
485  return -EMSGSIZE;
486 
487  hunt->flags = MCDI_DWORD(outbuf, DRV_ATTACH_EXT_OUT_FUNC_FLAGS);
488 
489  return 0;
490 }
491 
492 static int hunt_reset(struct hunt_nic *hunt)
493 {
494  struct efx_mcdi_req_s req;
496 
498  req.emr_in_buf = inbuf;
499  req.emr_in_length = sizeof(inbuf);
500  req.emr_out_buf = NULL;
501  req.emr_out_length = 0;
502 
503  MCDI_POPULATE_DWORD_1(req.emr_in_buf, ENTITY_RESET_IN_FLAG,
504  ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
505  return hunt_mcdi(hunt, &req);
506 }
507 
508 static void hunt_clear_udp_tunnel_ports(struct hunt_nic *hunt)
509 {
512  struct efx_mcdi_req_s req;
513  int rc;
514 
516  MCDI_SET_DWORD(inbuf, SET_TUNNEL_ENCAP_UDP_PORTS_IN_FLAGS,
518 
520  req.emr_in_buf = inbuf;
521  req.emr_in_length = sizeof(inbuf);
522  req.emr_out_buf = outbuf;
523  req.emr_out_length = sizeof(outbuf);
524 
525  rc = hunt_mcdi_quiet(hunt, &req);
526  if (rc)
527  return;
528 
529  if (MCDI_DWORD(outbuf, SET_TUNNEL_ENCAP_UDP_PORTS_OUT_FLAGS) &
531  DBGC(hunt,
532  "Rebooting MC due to clearing UDP tunnel port list\n");
533  /* Delay for the MC reboot to complete. */
534  mdelay(100);
535  }
536 }
537 
538 static int hunt_set_mac(struct hunt_nic *hunt)
539 {
540  struct net_device *netdev = hunt->efx.netdev;
541  struct efx_mcdi_req_s req;
543  unsigned int fcntl;
544  int rc;
545 
546  req.emr_cmd = MC_CMD_SET_MAC;
547  req.emr_in_buf = payload;
549  req.emr_out_buf = NULL;
550  req.emr_out_length = 0;
551 
552  MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_MTU,
554  MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_DRAIN, 0);
555  memcpy(MCDI_PTR(req.emr_in_buf, SET_MAC_IN_ADDR),
557  MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_REJECT, 0);
558 
559  /* If the PHY supports autnegotiation, then configure the MAC to match
560  * the negotiated settings. Otherwise force the MAC to TX and RX flow
561  * control.
562  */
563  if (hunt->phy_cap_mask & (1 << MC_CMD_PHY_CAP_AN_LBN))
564  fcntl = MC_CMD_FCNTL_AUTO;
565  else
566  fcntl = MC_CMD_FCNTL_BIDIR;
567  MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_FCNTL, fcntl);
568 
569  rc = hunt_mcdi(hunt, &req);
570  /* Ignore failure for permissions reasons */
571  if (rc == -EPERM)
572  rc = 0;
573  return rc;
574 }
575 
576 static int hunt_alloc_vis(struct hunt_nic *hunt)
577 {
578  struct efx_mcdi_req_s req;
580 
582  req.emr_in_buf = inbuf;
583  req.emr_in_length = sizeof(inbuf);
584  req.emr_out_buf = NULL;
585  req.emr_out_length = 0;
586 
587  MCDI_SET_DWORD(req.emr_in_buf, ALLOC_VIS_IN_MIN_VI_COUNT, 1);
588  MCDI_SET_DWORD(req.emr_in_buf, ALLOC_VIS_IN_MAX_VI_COUNT, 1);
589 
590  return hunt_mcdi(hunt, &req);
591 }
592 
593 static void hunt_free_vis(struct hunt_nic *hunt)
594 {
595  struct efx_mcdi_req_s req;
596  int rc;
597 
598  req.emr_cmd = MC_CMD_FREE_VIS;
599  req.emr_in_buf = NULL;
600  req.emr_in_length = 0;
601  req.emr_out_buf = NULL;
602  req.emr_out_length = 0;
603 
604  rc = hunt_mcdi(hunt, &req);
605  if (rc != 0)
606  DBGC(hunt, "MC_CMD_FREE_VIS Failed\n");
607 }
608 
609 /*******************************************************************************
610  *
611  *
612  * Link state handling
613  *
614  *
615  ******************************************************************************/
616 static int hunt_check_link(struct hunt_nic *hunt)
617 {
618  struct efx_mcdi_req_s req;
620  unsigned int flags, speed;
621  bool up;
622  int rc;
623  static bool link_state = false;
624 
625  req.emr_cmd = MC_CMD_GET_LINK;
626  req.emr_in_buf = NULL;
627  req.emr_in_length = 0;
628  req.emr_out_buf = outbuf;
629  req.emr_out_length = sizeof(outbuf);
630 
631  rc = hunt_mcdi(hunt, &req);
632  if (rc != 0)
633  return rc;
634 
636  return -EMSGSIZE;
637 
638  flags = MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_FLAGS);
639  up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
640  speed = MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_LINK_SPEED);
641 
642  /* Set netdev_link_*() based on the link status from the MC */
643  if (up && speed)
644  netdev_link_up(hunt->efx.netdev);
645  else
646  netdev_link_down(hunt->efx.netdev);
647 
648  if (up != link_state) {
649  DBGC(hunt, "Link %s, flags=%x, our caps=%x, lpa=%x, speed=%d, fcntl=%x, mac_fault=%x\n",
650  (up? "up": "down"), flags,
651  MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_CAP),
652  MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_LP_CAP),
653  speed,
654  MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_FCNTL),
655  MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_MAC_FAULT));
656  link_state = up;
657  }
658 
659  return 0;
660 }
661 
662 #define MCDI_PORT_SPEED_CAPS ((1 << MC_CMD_PHY_CAP_10HDX_LBN) | \
663  (1 << MC_CMD_PHY_CAP_10FDX_LBN) | \
664  (1 << MC_CMD_PHY_CAP_100HDX_LBN) | \
665  (1 << MC_CMD_PHY_CAP_100FDX_LBN) | \
666  (1 << MC_CMD_PHY_CAP_1000HDX_LBN) | \
667  (1 << MC_CMD_PHY_CAP_1000FDX_LBN) | \
668  (1 << MC_CMD_PHY_CAP_10000FDX_LBN) | \
669  (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
670 
671 /*******************************************************************************
672  *
673  *
674  * TX
675  *
676  *
677  ******************************************************************************/
678 static int
679 hunt_tx_init(struct net_device *netdev, struct hunt_nic *hunt)
680 {
681  struct efx_mcdi_req_s req;
682  dma_addr_t dma_addr;
683  efx_qword_t *addr;
684  MCDI_DECLARE_BUF(inbuf,
686  int rc, npages;
687 
688  rc = efx_hunt_tx_init(netdev, &dma_addr);
689  if (rc != 0)
690  return rc;
691 
692  npages = EFX_TXQ_NBUFS(EFX_TXD_SIZE);
693 
694  req.emr_cmd = MC_CMD_INIT_TXQ;
695  req.emr_in_buf = inbuf;
697  req.emr_out_buf = NULL;
698  req.emr_out_length = 0;
699 
700  MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_SIZE, EFX_TXD_SIZE);
701  MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_TARGET_EVQ, 0);
702  MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_LABEL, 0);
703  MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_INSTANCE, 0);
704 
705  MCDI_POPULATE_DWORD_6(req.emr_in_buf, INIT_TXQ_IN_FLAGS,
706  INIT_TXQ_IN_FLAG_BUFF_MODE, 0,
707  INIT_TXQ_IN_FLAG_IP_CSUM_DIS, 1,
708  INIT_TXQ_IN_FLAG_TCP_CSUM_DIS, 1,
709  INIT_TXQ_IN_FLAG_TCP_UDP_ONLY, 0,
710  INIT_TXQ_IN_CRC_MODE, 0,
711  INIT_TXQ_IN_FLAG_TIMESTAMP, 0);
712 
713  MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_OWNER_ID, 0);
714  MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_PORT_ID,
716 
717  addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_TXQ_IN_DMA_ADDR);
718 
720  EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
721  EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
722 
723  return hunt_mcdi(hunt, &req);
724 }
725 
726 static void hunt_tx_fini(struct hunt_nic *hunt)
727 {
728  struct efx_mcdi_req_s req;
730  struct efx_nic *efx = &hunt->efx;
731  struct efx_tx_queue *txq = &efx->txq;
732  int rc;
733 
734  req.emr_cmd = MC_CMD_FINI_TXQ;
735  req.emr_in_buf = inbuf;
736  req.emr_in_length = sizeof(inbuf);
737  req.emr_out_buf = NULL;
738  req.emr_out_length = 0;
739 
740  MCDI_SET_DWORD(req.emr_in_buf, FINI_TXQ_IN_INSTANCE, 0);
741 
742  rc = hunt_mcdi(hunt, &req);
743  if (rc != 0)
744  DBGC(hunt, "MC_CMD_FINI_TXQ Failed\n");
745 
747  sizeof(efx_tx_desc_t) * EFX_TXD_SIZE);
748  txq->ring = NULL;
749 }
750 
751 /*******************************************************************************
752  *
753  *
754  * RX
755  *
756  *
757  ******************************************************************************/
759  struct hunt_nic *hunt,
760  int multicast)
761 {
762  struct efx_mcdi_req_s req;
765  int rc;
766  uint64_t filter_id;
767  (void) netdev;
768 
770  req.emr_in_buf = inbuf;
771  req.emr_in_length = sizeof(inbuf);
772  req.emr_out_buf = outbuf;
773  req.emr_out_length = sizeof(outbuf);
774 
775  MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_OP,
778  MCDI_POPULATE_DWORD_1(req.emr_in_buf, FILTER_OP_IN_MATCH_FIELDS,
779  FILTER_OP_IN_MATCH_DST_MAC, 1);
780  if (multicast)
781  memset(MCDI_PTR(req.emr_in_buf, FILTER_OP_IN_DST_MAC),
782  0xff, ETH_ALEN);
783  else
784  memcpy(MCDI_PTR(req.emr_in_buf, FILTER_OP_IN_DST_MAC),
785  hunt->mac, ETH_ALEN);
786 
787  MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_PORT_ID,
789  MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_DEST,
791  MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_QUEUE, 0);
792  MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_MODE, 0);
793  MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_TX_DEST,
795 
796  rc = hunt_mcdi(hunt, &req);
797  if (rc != 0)
798  return rc;
799 
801  return -EIO;
802 
803  filter_id = MCDI_QWORD(req.emr_out_buf, FILTER_OP_OUT_HANDLE);
804  if (multicast)
805  hunt->mc_filter_id = filter_id;
806  else
807  hunt->uc_filter_id = filter_id;
808 
809  return 0;
810 }
811 
812 static int hunt_rx_filter_remove(struct hunt_nic *hunt,
813  int multicast)
814 {
815  struct efx_mcdi_req_s req;
817 
819  req.emr_in_buf = inbuf;
820  req.emr_in_length = sizeof(inbuf);
821  req.emr_out_buf = NULL;
822  req.emr_out_length = 0;
823 
824  MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_OP,
827  MCDI_SET_QWORD(req.emr_in_buf, FILTER_OP_IN_HANDLE,
828  multicast ? hunt->mc_filter_id :
829  hunt->uc_filter_id);
830  return hunt_mcdi(hunt, &req);
831 }
832 
833 static int hunt_get_mac(struct hunt_nic *hunt)
834 {
835  struct efx_mcdi_req_s req;
837  int rc;
838 
840  req.emr_in_buf = NULL;
841  req.emr_in_length = 0;
842  req.emr_out_buf = outbuf;
843  req.emr_out_length = sizeof(outbuf);
844 
845  rc = hunt_mcdi(hunt, &req);
846  if (rc != 0)
847  return rc;
848 
850  return -EMSGSIZE;
851 
852  memcpy(hunt->mac, MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE),
853  ETH_ALEN);
854  return 0;
855 }
856 
858  struct hunt_nic *hunt)
859 {
860  int rc = hunt_get_mac(hunt);
861 
862  if (rc != 0)
863  return rc;
864 
865  rc = hunt_rx_filter_insert(netdev, hunt, 0);
866  if (rc != 0)
867  return rc;
868 
869  rc = hunt_rx_filter_insert(netdev, hunt, 1);
870  if (rc != 0)
871  hunt_rx_filter_remove(hunt, 0);
872 
873  return rc;
874 }
875 
876 static int
878  struct hunt_nic *hunt)
879 {
880  struct efx_mcdi_req_s req;
881  dma_addr_t dma_addr;
882  efx_qword_t *addr;
883  MCDI_DECLARE_BUF(inbuf,
885  int rc, npages;
886 
887  rc = efx_hunt_rx_init(netdev, &dma_addr);
888  if (rc != 0)
889  return rc;
890 
891  npages = EFX_RXQ_NBUFS(EFX_RXD_SIZE);
892 
893  req.emr_cmd = MC_CMD_INIT_RXQ;
894  req.emr_in_buf = inbuf;
896  req.emr_out_buf = NULL;
897  req.emr_out_length = 0;
898 
899  MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_SIZE, EFX_RXD_SIZE);
900  MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_TARGET_EVQ, 0);
901  MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_LABEL, 0);
902  MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_INSTANCE, 0);
903  MCDI_POPULATE_DWORD_5(req.emr_in_buf, INIT_RXQ_IN_FLAGS,
904  INIT_RXQ_IN_FLAG_BUFF_MODE, 0,
905  INIT_RXQ_IN_FLAG_HDR_SPLIT, 0,
906  INIT_RXQ_IN_FLAG_TIMESTAMP, 0,
907  INIT_RXQ_IN_CRC_MODE, 0,
908  INIT_RXQ_IN_FLAG_PREFIX, 1);
909  MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_OWNER_ID, 0);
910  MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_PORT_ID,
912 
913  addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_RXQ_IN_DMA_ADDR);
914 
916  EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
917  EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
918  return hunt_mcdi(hunt, &req);
919 }
920 
921 static void hunt_rx_filter_fini(struct hunt_nic *hunt)
922 {
923  hunt_rx_filter_remove(hunt, 0);
924  hunt_rx_filter_remove(hunt, 1);
925 }
926 
927 static void hunt_rx_fini(struct hunt_nic *hunt)
928 {
930  struct efx_mcdi_req_s req;
931  struct efx_nic *efx = &hunt->efx;
932  struct efx_rx_queue *rxq = &efx->rxq;
933  int rc;
934 
935  req.emr_cmd = MC_CMD_FINI_RXQ;
936  req.emr_in_buf = inbuf;
938  req.emr_out_buf = NULL;
939  req.emr_out_length = 0;
940 
941  MCDI_SET_DWORD(req.emr_in_buf, FINI_RXQ_IN_INSTANCE, 0);
942 
943  rc = hunt_mcdi(hunt, &req);
944  if (rc != 0)
945  DBGC(hunt, "MC_CMD_FINI_RXQ Failed\n");
946 
948  sizeof(efx_rx_desc_t) * EFX_RXD_SIZE);
949  rxq->ring = NULL;
950 }
951 
952 /*******************************************************************************
953  *
954  *
955  * Event queues and interrupts
956  *
957  *
958  ******************************************************************************/
959 static int
961  struct hunt_nic *hunt)
962 {
963  struct efx_mcdi_req_s req;
964  dma_addr_t dma_addr;
965  efx_qword_t *addr;
966  MCDI_DECLARE_BUF(inbuf,
969  int rc, npages;
970 
971  rc = efx_hunt_ev_init(netdev, &dma_addr);
972  if (rc != 0)
973  return rc;
974 
975  npages = EFX_EVQ_NBUFS(EFX_EVQ_SIZE);
976 
977  req.emr_cmd = MC_CMD_INIT_EVQ;
978  req.emr_in_buf = inbuf;
980  req.emr_out_buf = outbuf;
981  req.emr_out_length = sizeof(outbuf);
982 
983  MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_SIZE, EFX_EVQ_SIZE);
984  MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_INSTANCE, 0);
985  MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_IRQ_NUM, 0);
986 
987  MCDI_POPULATE_DWORD_6(req.emr_in_buf, INIT_EVQ_IN_FLAGS,
988  INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
989  INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
990  INIT_EVQ_IN_FLAG_INT_ARMD, 0,
991  INIT_EVQ_IN_FLAG_CUT_THRU, 0,
992  INIT_EVQ_IN_FLAG_RX_MERGE, 0,
993  INIT_EVQ_IN_FLAG_TX_MERGE, 0);
994 
995  MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_MODE,
997  MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_LOAD, 0);
998  MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_RELOAD, 0);
999 
1000  MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_COUNT_MODE,
1002  MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_COUNT_THRSHLD, 0);
1003 
1004  addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_EVQ_IN_DMA_ADDR);
1005 
1007  EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
1008  EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
1009  rc = hunt_mcdi(hunt, &req);
1010  if (rc != 0)
1011  return rc;
1012 
1014  return -EMSGSIZE;
1015 
1016  return 0;
1017 }
1018 
1019 static void hunt_ev_fini(struct hunt_nic *hunt)
1020 {
1022  struct efx_mcdi_req_s req;
1023  struct efx_nic *efx = &hunt->efx;
1024  struct efx_ev_queue *evq = &efx->evq;
1025  int rc;
1026 
1027  req.emr_cmd = MC_CMD_FINI_EVQ;
1028  req.emr_in_buf = inbuf;
1029  req.emr_in_length = sizeof(inbuf);
1030  req.emr_out_buf = NULL;
1031  req.emr_out_length = 0;
1032 
1033  MCDI_SET_DWORD(req.emr_in_buf, FINI_EVQ_IN_INSTANCE, 0);
1034 
1035  rc = hunt_mcdi(hunt, &req);
1036  if (rc != 0)
1037  DBGC(hunt, "MC_CMD_FINI_EVQ Failed\n");
1038 
1040  sizeof(efx_event_t) * EFX_EVQ_SIZE);
1041  evq->ring = NULL;
1042 }
1043 
1044 static void
1046 {
1047  struct hunt_nic *hunt = netdev->priv;
1048 
1049  /* If called while already polling, return immediately */
1050  if (hunt->efx.state & EFX_STATE_POLLING)
1051  return;
1052  hunt->efx.state |= EFX_STATE_POLLING;
1053 
1054  /* Poll link state */
1055  if (hunt->link_poll_timer + TICKS_PER_SEC < currticks()) {
1056  hunt->link_poll_timer = currticks();
1057  hunt_check_link(hunt);
1058  }
1059 
1060  /* Poll data path */
1062 
1063  hunt->efx.state &= ~EFX_STATE_POLLING;
1064 }
1065 
1066 /*******************************************************************************
1067  *
1068  *
1069  * Netdevice operations
1070  *
1071  *
1072  ******************************************************************************/
1073 static int hunt_open(struct net_device *netdev)
1074 {
1075  struct hunt_nic *hunt = netdev->priv;
1076  int rc;
1077 
1078  /* Allocate VIs */
1079  rc = hunt_alloc_vis(hunt);
1080  if (rc != 0)
1081  goto fail2;
1082 
1083  /* Initialize data path */
1084  rc = hunt_ev_init(netdev, hunt);
1085  if (rc != 0)
1086  goto fail3;
1087 
1088  rc = hunt_rx_init(netdev, hunt);
1089  if (rc != 0)
1090  goto fail4;
1091 
1092  rc = hunt_rx_filter_init(netdev, hunt);
1093  if (rc != 0)
1094  goto fail5;
1095 
1096  rc = hunt_tx_init(netdev, hunt);
1097  if (rc != 0)
1098  goto fail6;
1099 
1100  rc = efx_hunt_open(netdev);
1101  if (rc)
1102  goto fail7;
1103 
1104  rc = hunt_set_mac(hunt);
1105  if (rc)
1106  goto fail8;
1107 
1108  /* Mark the link as down before checking the link state because the
1109  * latter might fail.
1110  */
1112  hunt_check_link(hunt);
1113 
1114  DBGC2(hunt, "%s: open ok\n", netdev->name);
1115  return 0;
1116 
1117 fail8:
1119 fail7:
1120  hunt_tx_fini(hunt);
1121 fail6:
1122  hunt_rx_filter_fini(hunt);
1123 fail5:
1124  hunt_rx_fini(hunt);
1125 fail4:
1126  hunt_ev_fini(hunt);
1127 fail3:
1128  hunt_free_vis(hunt);
1129 fail2:
1130  DBGC2(hunt, "%s: %s\n", netdev->name, strerror(rc));
1131  return rc;
1132 }
1133 
1134 
1135 static void hunt_close(struct net_device *netdev)
1136 {
1137  struct hunt_nic *hunt = netdev->priv;
1138 
1139  /* Stop datapath */
1141 
1142  hunt_tx_fini(hunt);
1143  hunt_rx_fini(hunt);
1144  hunt_rx_filter_fini(hunt);
1145  hunt_ev_fini(hunt);
1146 
1147  hunt_free_vis(hunt);
1148 
1149  /* Reset hardware and detach */
1150  hunt_reset(hunt);
1151 }
1152 
1153 
1154 /*******************************************************************************
1155  *
1156  *
1157  * Public operations
1158  *
1159  *
1160  ******************************************************************************/
1161 
1163  .open = hunt_open,
1164  .close = hunt_close,
1165  .transmit = efx_hunt_transmit,
1166  .poll = hunt_poll,
1167  .irq = efx_hunt_irq,
1168 };
1169 
1170 static int
1172 {
1173  struct net_device *netdev;
1174  struct hunt_nic *hunt;
1175  struct efx_nic *efx;
1176  int rc = 0;
1177 
1178  /* Create the network adapter */
1179  netdev = alloc_etherdev(sizeof(struct hunt_nic));
1180  if (!netdev) {
1181  rc = -ENOMEM;
1182  goto fail1;
1183  }
1184 
1185  /* Initialise the network adapter, and initialise private storage */
1187  pci_set_drvdata(pci, netdev);
1188  netdev->dev = &pci->dev;
1190 
1191  hunt = netdev->priv;
1192  memset(hunt, 0, sizeof(*hunt));
1193  efx = &hunt->efx;
1194 
1195  efx->type = &hunt_nic_type;
1196 
1197  /* Initialise efx datapath */
1199 
1200  /* Initialise MCDI. In case we are recovering from a crash, first
1201  * cancel any outstanding request by sending a special message using the
1202  * least significant bits of the 'high' (doorbell) register.
1203  */
1205  rc = hunt_mcdi_init(hunt);
1206  if (rc != 0)
1207  goto fail2;
1208 
1209  /* Reset (most) configuration for this function */
1210  rc = hunt_reset(hunt);
1211  if (rc != 0)
1212  goto fail3;
1213 
1214  /* Medford has a list of UDP tunnel ports that is populated by the
1215  * driver. Avoid dropping any unencapsulated packets. This may cause
1216  * an MC reboot.
1217  */
1219 
1220  /* Enable the workaround for bug35388, if supported */
1222 
1223  /* Set the RX packet prefix size */
1225 
1226  rc = hunt_get_port_assignment(hunt);
1227  if (rc != 0)
1228  goto fail3;
1229 
1230  rc = hunt_mac_addr(hunt, netdev->ll_addr);
1231  if (rc != 0)
1232  goto fail4;
1233 
1234  rc = hunt_get_phy_cfg(hunt);
1235  if (rc != 0)
1236  goto fail5;
1237 
1238  rc = hunt_driver_attach(hunt, 1);
1239  if (rc != 0)
1240  goto fail5;
1241 
1242  /* If not exposing this network device, return successfully here */
1244  return 0;
1245 
1246  if (hunt_nic_is_primary(hunt)) {
1247  hunt->next_primary = primary_nics;
1248  primary_nics = hunt;
1249  hunt->primary = hunt;
1250  } else {
1251  struct hunt_nic *other_hunt = primary_nics;
1252 
1253  while (other_hunt && !hunt->primary) {
1254  struct pci_device *other_pci = (struct pci_device *)
1255  other_hunt->efx.netdev->dev;
1256  /* Check if the seg:bus:dev parts match. */
1257  if (PCI_FIRST_FUNC(other_pci->busdevfn) ==
1258  PCI_FIRST_FUNC(pci->busdevfn))
1259  hunt->primary = other_hunt;
1260 
1261  other_hunt = other_hunt->next_primary;
1262  }
1263  if (!hunt->primary) {
1264  rc = -EIO;
1265  goto fail6;
1266  }
1267  }
1268 
1270  if (rc != 0)
1271  goto fail8;
1272 
1273  DBG2("%s " PCI_FMT " ok\n", __func__, PCI_ARGS(pci));
1274  return 0;
1275 
1276 fail8:
1277 fail6:
1278  (void) hunt_driver_attach(hunt, 0);
1279 fail5:
1280 fail4:
1281 fail3:
1282  hunt_mcdi_fini(hunt);
1283 fail2:
1284  efx_remove(netdev);
1285  netdev_put(netdev);
1286 fail1:
1287  DBG2("%s " PCI_FMT " rc=%d\n", __func__, PCI_ARGS(pci), rc);
1288  return rc;
1289 }
1290 
1291 static void hunt_remove(struct pci_device *pci)
1292 {
1293  struct net_device *netdev = pci_get_drvdata(pci);
1294  struct hunt_nic *hunt = netdev->priv;
1295 
1296  if (!(hunt->flags &
1298  /* The netdevice might still be open, so unregister it now
1299  * before ripping stuff out from underneath.
1300  */
1302  }
1303 
1304  (void)hunt_driver_attach(hunt, 0);
1305  hunt_mcdi_fini(hunt);
1306 
1307  /* Destroy data path */
1308  efx_remove(netdev);
1309 
1311  netdev_put(netdev);
1312 }
1313 
1314 const struct efx_nic_type hunt_nic_type = {
1315  .mcdi_rpc = _hunt_mcdi,
1316 };
1317 
1318 static struct pci_device_id hunt_nics[] = {
1319  PCI_ROM(0x1924, 0x0903, "SFC9120", "Solarflare SFC9120 Adapter", 0),
1320  PCI_ROM(0x1924, 0x0923, "SFC9140", "Solarflare SFC9140 Adapter", 0),
1321  PCI_ROM(0x1924, 0x0a03, "SFC9220", "Solarflare SFN8xxx Adapter", 0),
1322  PCI_ROM(0x1924, 0x0b03, "SFC9250", "Solarflare X25xx Adapter", 0),
1323 };
1324 
1325 struct pci_driver hunt_driver __pci_driver = {
1326  .ids = hunt_nics,
1327  .id_count = ARRAY_SIZE(hunt_nics),
1328  .probe = hunt_probe,
1329  .remove = hunt_remove,
1330 };
void efx_hunt_irq(struct net_device *netdev, int enable)
Definition: efx_hunt.c:445
#define MC_CMD_INIT_TXQ_IN_LEN(num)
#define MC_CMD_ERR_ENOENT
size_t emr_in_length
Definition: efx_hunt.h:47
#define EINVAL
Invalid argument.
Definition: errno.h:428
static int hunt_workaround_35388(struct hunt_nic *hunt)
Definition: sfc_hunt.c:365
#define MCDI_SET_DWORD(_buf, _field, _value)
Definition: mcdi.h:51
#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY
static int hunt_get_port_assignment(struct hunt_nic *hunt)
Definition: sfc_hunt.c:384
static int hunt_probe(struct pci_device *pci)
Definition: sfc_hunt.c:1171
int port
Definition: efx_common.h:152
iPXE I/O API
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void efx_hunt_poll(struct net_device *netdev)
Definition: efx_hunt.c:406
static struct net_device_operations hunt_operations
Definition: sfc_hunt.c:1162
static int hunt_set_mac(struct hunt_nic *hunt)
Definition: sfc_hunt.c:538
wmb()
struct io_buffer * iob
Definition: sfc_hunt.c:74
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
int efx_hunt_rx_init(struct net_device *netdev, dma_addr_t *dma_addr)
Definition: efx_hunt.c:272
static int hunt_alloc_vis(struct hunt_nic *hunt)
Definition: sfc_hunt.c:576
#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST
A PCI driver.
Definition: pci.h:251
#define EBUSY
Device or resource busy.
Definition: errno.h:338
#define MC_CMD_FILTER_OP_IN_OP_INSERT
#define MC_CMD_INIT_TXQ
union efx_dword efx_dword_t
A doubleword (4 byte) datatype - little-endian in HW.
#define MCDI_QWORD(_buf, _field)
Definition: mcdi.h:116
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:222
#define MC_CMD_FILTER_OP_IN_OP_REMOVE
efx_dword_t * emr_out_buf
Definition: efx_hunt.h:49
#define MC_CMD_GET_MAC_ADDRESSES_OUT_LEN
static int hunt_mcdi_init(struct hunt_nic *hunt)
Definition: sfc_hunt.c:98
#define MC_CMD_INIT_EVQ_IN_LEN(num)
Hardware access.
Definition: efx_common.h:147
uint64_t dma_addr
Definition: sfc_hunt.c:75
A transmit queue.
Definition: efx_common.h:89
#define MC_CMD_GET_LINK_OUT_LEN
static int hunt_rx_filter_insert(struct net_device *netdev, struct hunt_nic *hunt, int multicast)
Definition: sfc_hunt.c:758
A receive queue.
Definition: efx_common.h:107
Error codes.
efx_dword_t dword[2]
Definition: efx_bitfield.h:95
#define MC_CMD_FINI_TXQ
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define MC_CMD_FILTER_OP_IN_LEN
#define MC_CMD_GET_LINK
#define EFX_EVQ_SIZE
Definition: efx_common.h:60
#define MCDI_POPULATE_DWORD_1(_buf, _field, _name1, _value1)
Definition: mcdi.h:55
static void hunt_clear_udp_tunnel_ports(struct hunt_nic *hunt)
Definition: sfc_hunt.c:508
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:253
#define MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS
#define EFX_TXQ_NBUFS(_ndescs)
Definition: efx_hunt.h:41
struct arbelprm_completion_with_error error
Definition: arbel.h:12
static int hunt_mcdi_request_poll(struct hunt_nic *hunt, bool quiet)
Definition: sfc_hunt.c:178
#define MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT
#define DBGC(...)
Definition: compiler.h:505
#define MCDI_DWORD(_buf, _field)
Definition: mcdi.h:53
#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE
efx_rx_desc_t * ring
Definition: efx_common.h:109
#define MC_CMD_FW_DONT_CARE
bool workaround_35388
Definition: efx_common.h:175
static int hunt_open(struct net_device *netdev)
Definition: sfc_hunt.c:1073
#define MC_CMD_FCNTL_AUTO
#define ENOENT
No such file or directory.
Definition: errno.h:514
size_t emr_out_length_used
Definition: efx_hunt.h:51
unsigned long long uint64_t
Definition: stdint.h:13
unsigned int state
Current device state.
Definition: netdevice.h:395
int efx_hunt_ev_init(struct net_device *netdev, dma_addr_t *dma_addr)
Definition: efx_hunt.c:296
unsigned long dma_addr_t
Definition: bnx2.h:20
#define ER_DZ_MC_DB_LWRD
Definition: ef10_regs.h:70
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition: netdevice.c:230
__be32 outlen
Definition: CIB_PRM.h:41
#define MC_CMD_ERR_EBUSY
#define MC_CMD_WORKAROUND_IN_LEN
#define EACCES
Permission denied.
Definition: errno.h:298
static void _efx_writel(struct efx_nic *efx, uint32_t value, unsigned int reg)
Definition: efx_common.h:205
#define MC_CMD_FINI_EVQ
static int hunt_mcdi_quiet(struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
Definition: sfc_hunt.c:300
#define MC_CMD_ERR_EINTR
#define MC_CMD_ERR_EINVAL
int efx_hunt_tx_init(struct net_device *netdev, dma_addr_t *dma_addr)
Definition: efx_hunt.c:157
static int hunt_tx_init(struct net_device *netdev, struct hunt_nic *hunt)
Definition: sfc_hunt.c:679
#define MC_CMD_INIT_RXQ
A doubleword (4 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:87
void efx_probe(struct net_device *netdev, enum efx_revision revision)
Definition: efx_common.c:71
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:130
static int hunt_rx_init(struct net_device *netdev, struct hunt_nic *hunt)
Definition: sfc_hunt.c:877
size_t emr_out_length
Definition: efx_hunt.h:50
uint64_t mc_filter_id
Definition: sfc_hunt.c:64
struct device dev
Generic device.
Definition: pci.h:212
uint16_t enabled
Single-entry bitmask of the enabled option value.
Definition: ena.h:14
static void hunt_ev_fini(struct hunt_nic *hunt)
Definition: sfc_hunt.c:1019
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS
#define EFX_EVQ_NBUFS(_nevs)
Definition: efx_hunt.h:35
size_t resp_hdr_len
Definition: sfc_hunt.c:71
#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT
#define MC_CMD_DRV_ATTACH_OUT_LEN
Dynamic memory allocation.
u8 mac[ETH_ALEN]
Definition: sfc_hunt.c:65
#define MC_CMD_FINI_RXQ_IN_LEN
u32 state
Definition: efx_common.h:153
#define MC_CMD_FILTER_OP
#define MC_CMD_DRV_PREBOOT_LBN
#define MC_CMD_GET_WORKAROUNDS
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:518
static int hunt_rx_filter_init(struct net_device *netdev, struct hunt_nic *hunt)
Definition: sfc_hunt.c:857
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition: pci.h:365
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define MCDI_PTR(_buf, _field)
Definition: mcdi.h:41
#define MC_CMD_ERR_EPERM
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define MC_CMD_DRV_ATTACH
#define MC_CMD_GET_WORKAROUNDS_OUT_BUG35388
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
void efx_hunt_close(struct net_device *netdev)
Definition: efx_hunt.c:488
struct pci_driver hunt_driver __pci_driver
Definition: sfc_hunt.c:1325
#define ER_DZ_MC_DB_HWRD
Definition: ef10_regs.h:75
#define EMSGSIZE
Message too long.
Definition: errno.h:463
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:575
Ethernet protocol.
struct hunt_nic * next_primary
Definition: sfc_hunt.c:79
efx_tx_desc_t * ring
Definition: efx_common.h:91
#define EINTR
Interrupted function call.
Definition: errno.h:423
static void hunt_close(struct net_device *netdev)
Definition: sfc_hunt.c:1135
static int hunt_rx_filter_remove(struct hunt_nic *hunt, int multicast)
Definition: sfc_hunt.c:812
#define ETH_FRAME_LEN
Definition: if_ether.h:11
#define PCI_FIRST_FUNC(busdevfn)
Definition: pci.h:286
void * priv
Driver private data.
Definition: netdevice.h:431
int(* mcdi_rpc)(struct efx_nic *efx, unsigned int cmd, const efx_dword_t *inbuf, size_t inlen, efx_dword_t *outbuf, size_t outlen, size_t *outlen_actual, bool quiet)
Definition: efx_common.h:182
#define MC_CMD_GET_PORT_ASSIGNMENT
Efx bitfield access.
static int hunt_get_workarounds(struct hunt_nic *hunt, uint32_t *implemented, uint32_t *enabled)
Definition: sfc_hunt.c:316
struct efx_nic efx
Definition: sfc_hunt.c:55
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition: netdevice.h:788
#define EDEADLK
Resource deadlock avoided.
Definition: errno.h:368
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
static struct net_device * netdev
Definition: gdbudp.c:52
uint64_t u64
Definition: stdint.h:25
#define EFX_RXD_SIZE
Definition: efx_common.h:56
#define EFX_MAC_FRAME_LEN(_mtu)
Definition: efx_common.h:190
#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct hunt_nic * primary_nics
Definition: sfc_hunt.c:52
#define MC_CMD_ERR_ENOSYS
static int hunt_enable_workaround_35388(struct hunt_nic *hunt)
Definition: sfc_hunt.c:344
#define MC_CMD_SET_MAC
EF10 hardware architecture definitions.
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
#define EFX_POPULATE_QWORD_2(qword,...)
Definition: efx_bitfield.h:394
efx_dword_t * emr_in_buf
Definition: efx_hunt.h:46
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN
#define MCDI_DECLARE_BUF(_name, _len)
Definition: mcdi.h:35
#define MC_CMD_ERR_ETIME
static void hunt_mcdi_copyout(struct hunt_nic *hunt, uint8_t *outbuf, size_t outlen)
Definition: sfc_hunt.c:166
uint8_t flags
Flags.
Definition: ena.h:18
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define MC_CMD_ERR_EACCES
unsigned int seqno
Definition: sfc_hunt.c:69
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:311
#define EFX_RXQ_NBUFS(_ndescs)
Definition: efx_hunt.h:38
unsigned int emr_cmd
Definition: efx_hunt.h:45
PCI bus.
A PCI device.
Definition: pci.h:210
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:759
#define EFX_STATE_POLLING
Definition: efx_common.h:78
uint32_t addr
Buffer address.
Definition: dwmac.h:20
#define MC_CMD_FILTER_OP_OUT_LEN
size_t resp_data_len
Definition: sfc_hunt.c:72
A network device.
Definition: netdevice.h:352
const struct efx_nic_type * type
Definition: efx_common.h:150
#define MC_CMD_ENTITY_RESET_IN_LEN
unsigned int phy_cap
Definition: sfc_hunt.c:59
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:531
#define EMCDI_IO(code)
Definition: sfc_hunt.c:43
#define ARRAY_SIZE(x)
Definition: efx_common.h:43
static void hunt_remove(struct pci_device *pci)
Definition: sfc_hunt.c:1291
unsigned char uint8_t
Definition: stdint.h:10
static int hunt_get_mac(struct hunt_nic *hunt)
Definition: sfc_hunt.c:833
#define MC_CMD_FREE_VIS
#define MC_CMD_GET_PHY_CFG_OUT_LEN
#define MC_CMD_GET_MAC_ADDRESSES
const struct efx_nic_type hunt_nic_type
Definition: sfc_hunt.c:1314
#define ETH_ALEN
Definition: if_ether.h:8
#define MC_CMD_ALLOC_VIS_IN_LEN
#define ETIME
Timer expired.
Definition: errno.h:664
A PCI device ID list entry.
Definition: pci.h:174
unsigned int uint32_t
Definition: stdint.h:12
static void hunt_rx_filter_fini(struct hunt_nic *hunt)
Definition: sfc_hunt.c:921
#define EFX_DWORD_FIELD(dword, field)
Definition: efx_bitfield.h:197
u32 flags
Definition: sfc_hunt.c:80
#define MC_CMD_GET_WORKAROUNDS_OUT_LEN
struct efx_rx_queue rxq
Definition: efx_common.h:164
#define EFX_POPULATE_DWORD_2(dword,...)
Definition: efx_bitfield.h:421
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING_LBN
static void hunt_mcdi_fini(struct hunt_nic *hunt)
Definition: sfc_hunt.c:256
int _hunt_mcdi(struct efx_nic *efx, unsigned int cmd, const efx_dword_t *inbuf, size_t inlen, efx_dword_t *outbuf, size_t outlen, size_t *outlen_actual, bool quiet)
Definition: sfc_hunt.c:261
unsigned int rx_prefix_size
Definition: efx_common.h:168
#define MCDI_SEQ_MASK
Definition: mcdi.h:28
#define MCDI_POPULATE_DWORD_6(_buf, _field, _name1, _value1, _name2, _value2, _name3, _value3, _name4, _value4, _name5, _value5, _name6, _value6)
Definition: mcdi.h:86
Network device operations.
Definition: netdevice.h:213
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
int efx_hunt_open(struct net_device *netdev)
Definition: efx_hunt.c:467
#define EPERM
Operation not permitted.
Definition: errno.h:614
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_LBN
efx_event_t * ring
Definition: efx_common.h:132
Network device management.
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition: pci.h:375
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
static int hunt_get_phy_cfg(struct hunt_nic *hunt)
Definition: sfc_hunt.c:431
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:237
void efx_remove(struct net_device *netdev)
Definition: efx_common.c:98
static int hunt_reset(struct hunt_nic *hunt)
Definition: sfc_hunt.c:492
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define ES_DZ_RX_PREFIX_SIZE
Definition: ef10_regs.h:362
struct hunt_nic::@116 mcdi
#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE
static int hunt_driver_attach(struct hunt_nic *hunt, int attach)
Definition: sfc_hunt.c:456
static void hunt_poll(struct net_device *netdev)
Definition: sfc_hunt.c:1045
int efx_hunt_transmit(struct net_device *netdev, struct io_buffer *iob)
Definition: efx_hunt.c:102
static int hunt_check_link(struct hunt_nic *hunt)
Definition: sfc_hunt.c:616
#define DBGC2(...)
Definition: compiler.h:522
#define MC_CMD_GET_LINK_OUT_LINK_UP_LBN
static int hunt_mcdi(struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
Definition: sfc_hunt.c:291
uint16_t delay
Forward delay.
Definition: stp.h:40
unsigned int phy_cap_mask
Definition: sfc_hunt.c:58
struct efx_ev_queue evq
Definition: efx_common.h:166
struct efx_tx_queue txq
Definition: efx_common.h:165
#define MC_CMD_FCNTL_BIDIR
void * data
Start of data.
Definition: iobuf.h:52
#define EIO
Input/output error.
Definition: errno.h:433
#define EFX_POPULATE_DWORD_7(dword,...)
Definition: efx_bitfield.h:411
static struct pci_device_id hunt_nics[]
Definition: sfc_hunt.c:1318
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:314
#define MC_CMD_FINI_RXQ
#define MC_CMD_DRV_ATTACH_IN_LEN
#define EFX_TXD_SIZE
Definition: efx_common.h:58
#define MC_CMD_ENTITY_RESET
#define ENOSYS
Function not implemented.
Definition: errno.h:564
#define MC_CMD_PHY_CAP_AN_LBN
#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN
#define MC_CMD_FINI_EVQ_IN_LEN
#define MC_CMD_INIT_EVQ
static void hunt_mcdi_copyin(struct hunt_nic *hunt, unsigned int cmd, uint8_t *inbuf, size_t inlen)
Definition: sfc_hunt.c:117
static int hunt_ev_init(struct net_device *netdev, struct hunt_nic *hunt)
Definition: sfc_hunt.c:960
Efx device type definition.
Definition: efx_common.h:181
#define MC_CMD_ERR_EDEADLK
struct hunt_nic * primary
Definition: sfc_hunt.c:78
#define EVB_PORT_ID_ASSIGNED
An event queue.
Definition: efx_common.h:128
void efx_hunt_free_special_buffer(void *buf, int bytes)
Definition: efx_hunt.c:40
static int hunt_nic_is_primary(struct hunt_nic *hunt)
Definition: sfc_hunt.c:83
__be32 inlen
Definition: CIB_PRM.h:30
#define MCDI_SET_QWORD(_buf, _field, _value)
Definition: mcdi.h:109
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define MC_CMD_ALLOC_VIS
static void hunt_tx_fini(struct hunt_nic *hunt)
Definition: sfc_hunt.c:726
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define MC_CMD_FINI_TXQ_IN_LEN
static int hunt_mac_addr(struct hunt_nic *hunt, uint8_t *ll_addr)
Definition: sfc_hunt.c:405
#define MC_CMD_GET_PHY_CFG
#define MC_CMD_WORKAROUND
#define NETDEV_IRQ_UNSUPPORTED
Network device interrupts are unsupported.
Definition: netdevice.h:452
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX
This file is a subset of the MCDI headers generated from the yml files.
unsigned long link_poll_timer
Definition: sfc_hunt.c:60
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct golan_eqe_cmd cmd
Definition: CIB_PRM.h:29
#define MC_CMD_INIT_EVQ_OUT_LEN
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
String functions.
#define MCDI_POPULATE_DWORD_5(_buf, _field, _name1, _value1, _name2, _value2, _name3, _value3, _name4, _value4, _name5, _value5)
Definition: mcdi.h:77
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition: pci.h:307
#define MC_CMD_SET_MAC_IN_LEN
static void hunt_free_vis(struct hunt_nic *hunt)
Definition: sfc_hunt.c:593
A quadword (8 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:92
#define MCDI_CTL_SDU_LEN_MAX_V2
uint8_t u8
Definition: stdint.h:19
struct net_device * netdev
Definition: efx_common.h:148
#define MC_CMD_V2_EXTN
static void hunt_rx_fini(struct hunt_nic *hunt)
Definition: sfc_hunt.c:927
uint32_t u32
Definition: stdint.h:23
#define MC_CMD_DRV_ATTACH_EXT_OUT_LEN
uint64_t uc_filter_id
Definition: sfc_hunt.c:63
#define MC_CMD_WORKAROUND_BUG35388
#define DBG2(...)
Definition: compiler.h:515
if(natsemi->flags &NATSEMI_64BIT) return 1
MCDI request structure.
Definition: efx_hunt.h:44
void * memset(void *dest, int character, size_t len) __nonnull
#define MC_CMD_INIT_RXQ_IN_LEN(num)
A persistent I/O buffer.
Definition: iobuf.h:37