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