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