iPXE
sfc_hunt.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/io.h>
#include <ipxe/pci.h>
#include <ipxe/malloc.h>
#include <ipxe/ethernet.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include "efx_hunt.h"
#include "efx_bitfield.h"
#include "ef10_regs.h"
#include "mc_driver_pcol.h"
#include <ipxe/if_ether.h>

Go to the source code of this file.

Data Structures

struct  hunt_nic

Macros

#define HUNTINGTON_NVRAM_CHUNK   0x80
#define HUNTINGTON_NVS_MAX_LENGTH   0x1000
#define EMCDI_IO(code)
#define MIN(a, b)
#define MAX(_a, _b)
#define MCDI_PORT_SPEED_CAPS

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int hunt_nic_is_primary (struct hunt_nic *hunt)
static int hunt_mcdi_init (struct hunt_nic *hunt)
static void hunt_mcdi_copyin (struct hunt_nic *hunt, unsigned int cmd, uint8_t *inbuf, size_t inlen)
static void hunt_mcdi_copyout (struct hunt_nic *hunt, uint8_t *outbuf, size_t outlen)
static int hunt_mcdi_request_poll (struct hunt_nic *hunt, bool quiet)
static void hunt_mcdi_fini (struct hunt_nic *hunt)
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)
static int hunt_mcdi (struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
static int hunt_mcdi_quiet (struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
static int hunt_get_workarounds (struct hunt_nic *hunt, uint32_t *implemented, uint32_t *enabled)
static int hunt_enable_workaround_35388 (struct hunt_nic *hunt)
static int hunt_workaround_35388 (struct hunt_nic *hunt)
static int hunt_get_port_assignment (struct hunt_nic *hunt)
static int hunt_mac_addr (struct hunt_nic *hunt, uint8_t *ll_addr)
static int hunt_get_phy_cfg (struct hunt_nic *hunt)
static int hunt_driver_attach (struct hunt_nic *hunt, int attach)
static int hunt_reset (struct hunt_nic *hunt)
static void hunt_clear_udp_tunnel_ports (struct hunt_nic *hunt)
static int hunt_set_mac (struct hunt_nic *hunt)
static int hunt_alloc_vis (struct hunt_nic *hunt)
static void hunt_free_vis (struct hunt_nic *hunt)
static int hunt_check_link (struct hunt_nic *hunt)
static int hunt_tx_init (struct net_device *netdev, struct hunt_nic *hunt)
static void hunt_tx_fini (struct hunt_nic *hunt)
static int hunt_rx_filter_insert (struct net_device *netdev, struct hunt_nic *hunt, int multicast)
static int hunt_rx_filter_remove (struct hunt_nic *hunt, int multicast)
static int hunt_get_mac (struct hunt_nic *hunt)
static int hunt_rx_filter_init (struct net_device *netdev, struct hunt_nic *hunt)
static int hunt_rx_init (struct net_device *netdev, struct hunt_nic *hunt)
static void hunt_rx_filter_fini (struct hunt_nic *hunt)
static void hunt_rx_fini (struct hunt_nic *hunt)
static int hunt_ev_init (struct net_device *netdev, struct hunt_nic *hunt)
static void hunt_ev_fini (struct hunt_nic *hunt)
static void hunt_poll (struct net_device *netdev)
static int hunt_open (struct net_device *netdev)
static void hunt_close (struct net_device *netdev)
static int hunt_probe (struct pci_device *pci)
static void hunt_remove (struct pci_device *pci)

Variables

struct hunt_nicprimary_nics = NULL
static struct net_device_operations hunt_operations
const struct efx_nic_type hunt_nic_type
static struct pci_device_id hunt_nics []
struct pci_driver hunt_driver __pci_driver

Macro Definition Documentation

◆ HUNTINGTON_NVRAM_CHUNK

#define HUNTINGTON_NVRAM_CHUNK   0x80

Definition at line 40 of file sfc_hunt.c.

◆ HUNTINGTON_NVS_MAX_LENGTH

#define HUNTINGTON_NVS_MAX_LENGTH   0x1000

Definition at line 41 of file sfc_hunt.c.

◆ EMCDI_IO

#define EMCDI_IO ( code)
Value:
static unsigned int code
Response code.
Definition hyperv.h:26
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition errno.h:226
#define EINFO_EIO
Definition errno.h:435

Definition at line 43 of file sfc_hunt.c.

Referenced by hunt_mcdi_request_poll().

◆ MIN

#define MIN ( a,
b )
Value:
((a) < (b) ? (a) : (b))

Definition at line 46 of file sfc_hunt.c.

◆ MAX

#define MAX ( _a,
_b )
Value:
((_a) > (_b) ? (_a) : (_b))

Definition at line 49 of file sfc_hunt.c.

◆ MCDI_PORT_SPEED_CAPS

#define MCDI_PORT_SPEED_CAPS
Value:
#define MC_CMD_PHY_CAP_40000FDX_LBN
#define MC_CMD_PHY_CAP_10FDX_LBN
#define MC_CMD_PHY_CAP_100FDX_LBN
#define MC_CMD_PHY_CAP_1000FDX_LBN
#define MC_CMD_PHY_CAP_10HDX_LBN
#define MC_CMD_PHY_CAP_10000FDX_LBN
#define MC_CMD_PHY_CAP_1000HDX_LBN
#define MC_CMD_PHY_CAP_100HDX_LBN

Definition at line 662 of file sfc_hunt.c.

662#define MCDI_PORT_SPEED_CAPS ((1 << MC_CMD_PHY_CAP_10HDX_LBN) | \
663 (1 << MC_CMD_PHY_CAP_10FDX_LBN) | \
664 (1 << MC_CMD_PHY_CAP_100HDX_LBN) | \
665 (1 << MC_CMD_PHY_CAP_100FDX_LBN) | \
666 (1 << MC_CMD_PHY_CAP_1000HDX_LBN) | \
667 (1 << MC_CMD_PHY_CAP_1000FDX_LBN) | \
668 (1 << MC_CMD_PHY_CAP_10000FDX_LBN) | \
669 (1 << MC_CMD_PHY_CAP_40000FDX_LBN))

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ hunt_nic_is_primary()

int hunt_nic_is_primary ( struct hunt_nic * hunt)
static

Definition at line 83 of file sfc_hunt.c.

84{
85 return (hunt->flags & (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY));
86}
#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY
u32 flags
Definition sfc_hunt.c:80

References hunt_nic::flags, and MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY.

Referenced by hunt_probe().

◆ hunt_mcdi_init()

int hunt_mcdi_init ( struct hunt_nic * hunt)
static

Definition at line 98 of file sfc_hunt.c.

99{
100 size_t max_msg_size;
101 int rc;
102
103 /* The MCDI message has two 32-bit headers (the MCDI header and the
104 * MCDI v2 extended command) and then up to MCDI_CTL_SDU_LEN_MAX_V2
105 * bytes of payload
106 */
107 max_msg_size = 2 * sizeof(efx_dword_t) + MCDI_CTL_SDU_LEN_MAX_V2;
108
109 hunt->mcdi.iob = alloc_iob(max_msg_size);
110 if (!hunt->mcdi.iob) {
111 rc = -ENOMEM;
112 return rc;
113 }
114 return 0;
115}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
union efx_dword efx_dword_t
A doubleword (4 byte) datatype - little-endian in HW.
#define ENOMEM
Not enough space.
Definition errno.h:535
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define MCDI_CTL_SDU_LEN_MAX_V2
struct io_buffer * iob
Definition sfc_hunt.c:74
struct hunt_nic::@135364134257000067112155101147146075317041072205 mcdi

References alloc_iob(), ENOMEM, hunt_nic::iob, hunt_nic::mcdi, MCDI_CTL_SDU_LEN_MAX_V2, and rc.

Referenced by hunt_probe().

◆ hunt_mcdi_copyin()

void hunt_mcdi_copyin ( struct hunt_nic * hunt,
unsigned int cmd,
uint8_t * inbuf,
size_t inlen )
static

Definition at line 117 of file sfc_hunt.c.

121{
122 efx_dword_t hdr[2];
123 uint32_t seqno;
124 unsigned int xflags;
125 size_t hdr_len;
126 u8 *pdu = hunt->mcdi.iob->data;
127
128 seqno = hunt->mcdi.seqno & MCDI_SEQ_MASK;
129
130 xflags = 0;
131
133 MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
134 MCDI_HEADER_RESYNC, 1,
135 MCDI_HEADER_DATALEN, 0,
136 MCDI_HEADER_SEQ, seqno,
137 MCDI_HEADER_ERROR, 0,
138 MCDI_HEADER_RESPONSE, 0,
139 MCDI_HEADER_XFLAGS, xflags);
141 MC_CMD_V2_EXTN_IN_EXTENDED_CMD, cmd,
142 MC_CMD_V2_EXTN_IN_ACTUAL_LEN, inlen);
143
144 hdr_len = sizeof(hdr);
145
146 memcpy(pdu, &hdr, hdr_len);
148 memcpy(pdu + hdr_len, inbuf, inlen);
149
150 wmb(); /* Sync the data before ringing the doorbell */
151
152 /* Ring the doorbell to post the command DMA address to the MC */
153 hunt->mcdi.dma_addr = virt_to_bus(hunt->mcdi.iob->data);
154
155 assert((hunt->mcdi.dma_addr & 0xFF) == 0);
156
157 _efx_writel(&hunt->efx,
158 cpu_to_le32((u64)hunt->mcdi.dma_addr >> 32),
160
161 _efx_writel(&hunt->efx,
164}
__be32 inlen
Definition CIB_PRM.h:2
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
struct golan_eqe_cmd cmd
Definition CIB_PRM.h:1
unsigned int uint32_t
Definition stdint.h:12
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define ER_DZ_MC_DB_LWRD
Definition ef10_regs.h:70
#define ER_DZ_MC_DB_HWRD
Definition ef10_regs.h:75
#define EFX_POPULATE_DWORD_2(dword,...)
#define EFX_POPULATE_DWORD_7(dword,...)
static void _efx_writel(struct efx_nic *efx, uint32_t value, unsigned int reg)
Definition efx_common.h:205
#define u8
Definition igbvf_osdep.h:40
#define cpu_to_le32(value)
Definition byteswap.h:108
#define wmb()
Definition io.h:546
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition io.h:184
uint64_t u64
Definition stdint.h:26
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define MC_CMD_V2_EXTN
#define MCDI_SEQ_MASK
Definition mcdi.h:28
uint64_t dma_addr
Definition sfc_hunt.c:75
struct efx_nic efx
Definition sfc_hunt.c:55
unsigned int seqno
Definition sfc_hunt.c:69
void * data
Start of data.
Definition iobuf.h:53
#define u32
Definition vga.h:21

References _efx_writel(), assert, cmd, cpu_to_le32, io_buffer::data, hunt_nic::dma_addr, hunt_nic::efx, EFX_POPULATE_DWORD_2, EFX_POPULATE_DWORD_7, ER_DZ_MC_DB_HWRD, ER_DZ_MC_DB_LWRD, hdr, inlen, hunt_nic::iob, MC_CMD_V2_EXTN, hunt_nic::mcdi, MCDI_CTL_SDU_LEN_MAX_V2, MCDI_SEQ_MASK, memcpy(), hunt_nic::seqno, u32, u8, virt_to_bus(), and wmb.

Referenced by _hunt_mcdi().

◆ hunt_mcdi_copyout()

void hunt_mcdi_copyout ( struct hunt_nic * hunt,
uint8_t * outbuf,
size_t outlen )
static

Definition at line 166 of file sfc_hunt.c.

168{
169 size_t offset;
170 const u8 *pdu = hunt->mcdi.iob->data;
171
172 offset = hunt->mcdi.resp_hdr_len;
173
174 if (outlen > 0)
175 memcpy(outbuf, pdu+offset, outlen);
176}
__be32 outlen
Definition CIB_PRM.h:13
uint16_t offset
Offset to command line.
Definition bzimage.h:3
size_t resp_hdr_len
Definition sfc_hunt.c:71

References io_buffer::data, hunt_nic::iob, hunt_nic::mcdi, memcpy(), offset, outlen, hunt_nic::resp_hdr_len, and u8.

Referenced by _hunt_mcdi().

◆ hunt_mcdi_request_poll()

int hunt_mcdi_request_poll ( struct hunt_nic * hunt,
bool quiet )
static

Definition at line 178 of file sfc_hunt.c.

179{
180 unsigned int resplen, respseq, error;
181 unsigned long finish;
182 efx_dword_t errdword;
183 efx_qword_t qword;
184 const efx_dword_t *pdu = hunt->mcdi.iob->data;
185 const u8 *pdu1 = hunt->mcdi.iob->data;
186 int delay, rc;
187
188 /* Spin for up to 5s, polling at intervals of 10us, 20us, ... ~100ms */
189 finish = currticks() + (5 * TICKS_PER_SEC);
190 delay = 10;
191 while (1) {
192 udelay(delay);
193
194 /* Check for an MCDI response */
195 if (EFX_DWORD_FIELD(*pdu, MCDI_HEADER_RESPONSE))
196 break;
197
198 if (currticks() >= finish)
199 return -ETIMEDOUT;
200
201 if (delay < 100000)
202 delay *= 2;
203 }
204
205 memcpy(&qword, pdu1, 8);
206
207 /* qword.dword[0] is the MCDI header; qword.dword[1] is the MCDI v2
208 * extended command
209 */
210 respseq = EFX_DWORD_FIELD(qword.dword[0], MCDI_HEADER_SEQ);
211 error = EFX_DWORD_FIELD(qword.dword[0], MCDI_HEADER_ERROR);
212 resplen = EFX_DWORD_FIELD(qword.dword[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
213
214 if (error && resplen == 0) {
215 if (!quiet)
216 DBGC(hunt, "MC rebooted\n");
217 return -EIO;
218 } else if ((respseq ^ hunt->mcdi.seqno) & MCDI_SEQ_MASK) {
219 if (!quiet)
220 DBGC(hunt, "MC response mismatch rxseq 0x%x txseq "
221 "0x%x\n", respseq, hunt->mcdi.seqno);
222 return -EIO;
223 } else if (error) {
224 memcpy(&errdword, pdu1 + 8, 4);
225 rc = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
226 switch (rc) {
228 return -ENOENT;
229 case MC_CMD_ERR_EINTR:
230 return -EINTR;
232 return -EACCES;
233 case MC_CMD_ERR_EBUSY:
234 return -EBUSY;
236 return -EINVAL;
238 return -EDEADLK;
240 return -ENOSYS;
241 case MC_CMD_ERR_ETIME:
242 return -ETIME;
243 case MC_CMD_ERR_EPERM:
244 return -EPERM;
245 default:
246 /* Return the MC error in an I/O error. */
247 return EMCDI_IO(rc & 0xff);
248 }
249 }
250 hunt->mcdi.resp_hdr_len = 8;
251 hunt->mcdi.resp_data_len = resplen;
252
253 return 0;
254}
struct arbelprm_completion_with_error error
Definition arbel.h:1
#define EFX_DWORD_FIELD(dword, field)
union efx_qword efx_qword_t
A quadword (8 byte) datatype - little-endian in HW.
#define delay(nanosec)
Definition epic100.c:49
#define DBGC(...)
Definition compiler.h:505
#define ENOENT
No such file or directory.
Definition errno.h:515
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOSYS
Function not implemented.
Definition errno.h:565
#define EINTR
Interrupted function call.
Definition errno.h:424
#define EDEADLK
Resource deadlock avoided.
Definition errno.h:369
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define EIO
Input/output error.
Definition errno.h:434
#define EBUSY
Device or resource busy.
Definition errno.h:339
#define ETIME
Timer expired.
Definition errno.h:665
#define EACCES
Permission denied.
Definition errno.h:299
#define EPERM
Operation not permitted.
Definition errno.h:615
#define TICKS_PER_SEC
Number of ticks per second.
Definition timer.h:16
#define MC_CMD_ERR_ENOENT
#define MC_CMD_ERR_EINTR
#define MC_CMD_ERR_ENOSYS
#define MC_CMD_ERR_EACCES
#define MC_CMD_ERR_EINVAL
#define MC_CMD_ERR_EBUSY
#define MC_CMD_ERR_EPERM
#define MC_CMD_ERR_EDEADLK
#define MC_CMD_ERR_ETIME
#define EMCDI_IO(code)
Definition sfc_hunt.c:43
size_t resp_data_len
Definition sfc_hunt.c:72
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition timer.c:61
efx_dword_t dword[2]

References currticks(), io_buffer::data, DBGC, delay, efx_qword::dword, EACCES, EBUSY, EDEADLK, EFX_DWORD_FIELD, EINTR, EINVAL, EIO, EMCDI_IO, ENOENT, ENOSYS, EPERM, error, ETIME, ETIMEDOUT, hunt_nic::iob, MC_CMD_ERR_EACCES, MC_CMD_ERR_EBUSY, MC_CMD_ERR_EDEADLK, MC_CMD_ERR_EINTR, MC_CMD_ERR_EINVAL, MC_CMD_ERR_ENOENT, MC_CMD_ERR_ENOSYS, MC_CMD_ERR_EPERM, MC_CMD_ERR_ETIME, hunt_nic::mcdi, MCDI_SEQ_MASK, memcpy(), rc, hunt_nic::resp_data_len, hunt_nic::resp_hdr_len, hunt_nic::seqno, TICKS_PER_SEC, u8, and udelay().

Referenced by _hunt_mcdi().

◆ hunt_mcdi_fini()

void hunt_mcdi_fini ( struct hunt_nic * hunt)
static

Definition at line 256 of file sfc_hunt.c.

257{
258 free_iob(hunt->mcdi.iob);
259}
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153

References free_iob(), hunt_nic::iob, and hunt_nic::mcdi.

Referenced by hunt_probe(), and hunt_remove().

◆ _hunt_mcdi()

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 at line 261 of file sfc_hunt.c.

265{
266 int rc;
267 struct hunt_nic *hunt = (struct hunt_nic *) efx;
268 size_t local_outlen_actual;
269
270 if (outlen_actual == NULL)
271 outlen_actual = &local_outlen_actual;
272
273 ++hunt->mcdi.seqno;
274 hunt_mcdi_copyin(hunt, cmd, (uint8_t *) inbuf, inlen);
275
276 rc = hunt_mcdi_request_poll(hunt, quiet);
277 if (rc != 0) {
278 if (!quiet)
279 DBGC(hunt, "MC response to cmd 0x%x: %s\n",
280 cmd, strerror(rc));
281 return rc;
282 }
283
284 *outlen_actual = hunt->mcdi.resp_data_len;
285
286 hunt_mcdi_copyout(hunt, (uint8_t *) outbuf, outlen);
287
288 return 0;
289}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
unsigned char uint8_t
Definition stdint.h:10
static int hunt_mcdi_request_poll(struct hunt_nic *hunt, bool quiet)
Definition sfc_hunt.c:178
static void hunt_mcdi_copyin(struct hunt_nic *hunt, unsigned int cmd, uint8_t *inbuf, size_t inlen)
Definition sfc_hunt.c:117
static void hunt_mcdi_copyout(struct hunt_nic *hunt, uint8_t *outbuf, size_t outlen)
Definition sfc_hunt.c:166
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79

References cmd, DBGC, hunt_nic::efx, hunt_mcdi_copyin(), hunt_mcdi_copyout(), hunt_mcdi_request_poll(), inlen, hunt_nic::mcdi, NULL, outlen, rc, hunt_nic::resp_data_len, hunt_nic::seqno, and strerror().

Referenced by hunt_mcdi(), and hunt_mcdi_quiet().

◆ hunt_mcdi()

int hunt_mcdi ( struct hunt_nic * hunt,
struct efx_mcdi_req_s * req )
static

Definition at line 291 of file sfc_hunt.c.

292{
293 return _hunt_mcdi(&hunt->efx, req->emr_cmd,
294 (const efx_dword_t *) req->emr_in_buf,
295 req->emr_in_length,
297 &req->emr_out_length_used, false);
298}
int _hunt_mcdi(struct efx_nic *efx, unsigned int cmd, const efx_dword_t *inbuf, size_t inlen, efx_dword_t *outbuf, size_t outlen, size_t *outlen_actual, bool quiet)
Definition sfc_hunt.c:261
size_t emr_out_length
Definition efx_hunt.h:50
efx_dword_t * emr_in_buf
Definition efx_hunt.h:46
size_t emr_out_length_used
Definition efx_hunt.h:51
size_t emr_in_length
Definition efx_hunt.h:47
efx_dword_t * emr_out_buf
Definition efx_hunt.h:49
unsigned int emr_cmd
Definition efx_hunt.h:45

References _hunt_mcdi(), hunt_nic::efx, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, and efx_mcdi_req_s::emr_out_length_used.

Referenced by hunt_alloc_vis(), hunt_check_link(), hunt_driver_attach(), hunt_enable_workaround_35388(), hunt_ev_fini(), hunt_ev_init(), hunt_free_vis(), hunt_get_mac(), hunt_get_phy_cfg(), hunt_get_port_assignment(), hunt_get_workarounds(), hunt_mac_addr(), hunt_reset(), hunt_rx_filter_insert(), hunt_rx_filter_remove(), hunt_rx_fini(), hunt_rx_init(), hunt_set_mac(), hunt_tx_fini(), and hunt_tx_init().

◆ hunt_mcdi_quiet()

int hunt_mcdi_quiet ( struct hunt_nic * hunt,
struct efx_mcdi_req_s * req )
static

◆ hunt_get_workarounds()

int hunt_get_workarounds ( struct hunt_nic * hunt,
uint32_t * implemented,
uint32_t * enabled )
static

Definition at line 316 of file sfc_hunt.c.

318{
319 struct efx_mcdi_req_s req;
321 int rc;
322
323 *implemented = *enabled = 0;
324
325 req.emr_cmd = MC_CMD_GET_WORKAROUNDS;
326 req.emr_in_buf = NULL;
327 req.emr_in_length = 0;
328 req.emr_out_buf = outbuf;
329 req.emr_out_length = sizeof(outbuf);
330
331 rc = hunt_mcdi(hunt, &req);
332
333 if (rc)
334 return rc;
335
336 if (req.emr_out_length_used < MC_CMD_GET_WORKAROUNDS_OUT_LEN)
337 return -EMSGSIZE;
338
339 *implemented = MCDI_DWORD(outbuf, GET_WORKAROUNDS_OUT_IMPLEMENTED);
340 *enabled = MCDI_DWORD(outbuf, GET_WORKAROUNDS_OUT_ENABLED);
341 return 0;
342}
uint16_t enabled
Single-entry bitmask of the enabled option value.
Definition ena.h:3
#define EMSGSIZE
Message too long.
Definition errno.h:464
#define MC_CMD_GET_WORKAROUNDS_OUT_LEN
#define MC_CMD_GET_WORKAROUNDS
#define MCDI_DECLARE_BUF(_name, _len)
Definition mcdi.h:35
#define MCDI_DWORD(_buf, _field)
Definition mcdi.h:53
static int hunt_mcdi(struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
Definition sfc_hunt.c:291
MCDI request structure.
Definition efx_hunt.h:44

References efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_mcdi_req_s::emr_out_length_used, EMSGSIZE, enabled, hunt_mcdi(), MC_CMD_GET_WORKAROUNDS, MC_CMD_GET_WORKAROUNDS_OUT_LEN, MCDI_DECLARE_BUF, MCDI_DWORD, NULL, and rc.

Referenced by hunt_workaround_35388().

◆ hunt_enable_workaround_35388()

int hunt_enable_workaround_35388 ( struct hunt_nic * hunt)
static

Definition at line 344 of file sfc_hunt.c.

345{
346 struct efx_mcdi_req_s req;
348
349 req.emr_cmd = MC_CMD_WORKAROUND;
350 req.emr_in_buf = payload;
351 req.emr_in_length = MC_CMD_WORKAROUND_IN_LEN;
352 req.emr_out_buf = NULL;
353 req.emr_out_length = 0;
354
355 MCDI_SET_DWORD(req.emr_in_buf, WORKAROUND_IN_TYPE,
357 MCDI_SET_DWORD(req.emr_in_buf, WORKAROUND_IN_ENABLED, 1);
358
359 /* If the firmware doesn't support this workaround, hunt_mcdi() will
360 * return -EINVAL from hunt_mcdi_request_poll().
361 */
362 return hunt_mcdi(hunt, &req);
363}
#define MC_CMD_WORKAROUND
#define MC_CMD_WORKAROUND_IN_LEN
#define MC_CMD_WORKAROUND_BUG35388
#define MCDI_SET_DWORD(_buf, _field, _value)
Definition mcdi.h:51

References efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi(), MC_CMD_WORKAROUND, MC_CMD_WORKAROUND_BUG35388, MC_CMD_WORKAROUND_IN_LEN, MCDI_DECLARE_BUF, MCDI_SET_DWORD, and NULL.

Referenced by hunt_workaround_35388().

◆ hunt_workaround_35388()

int hunt_workaround_35388 ( struct hunt_nic * hunt)
static

Definition at line 365 of file sfc_hunt.c.

366{
367 uint32_t implemented, enabled;
368 int rc = hunt_get_workarounds(hunt, &implemented, &enabled);
369
370 if (rc < 0)
371 return 0;
372 if (!(implemented & MC_CMD_GET_WORKAROUNDS_OUT_BUG35388))
373 return 0;
375 return 1;
376
378 if (rc == 0)
379 return 1; /* Workaround is enabled */
380 else
381 return 0;
382}
#define MC_CMD_GET_WORKAROUNDS_OUT_BUG35388
static int hunt_enable_workaround_35388(struct hunt_nic *hunt)
Definition sfc_hunt.c:344
static int hunt_get_workarounds(struct hunt_nic *hunt, uint32_t *implemented, uint32_t *enabled)
Definition sfc_hunt.c:316

References enabled, hunt_enable_workaround_35388(), hunt_get_workarounds(), MC_CMD_GET_WORKAROUNDS_OUT_BUG35388, and rc.

Referenced by hunt_probe().

◆ hunt_get_port_assignment()

int hunt_get_port_assignment ( struct hunt_nic * hunt)
static

Definition at line 384 of file sfc_hunt.c.

385{
386 struct efx_mcdi_req_s req;
388 int rc;
389
390 req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
391 req.emr_in_buf = NULL;
392 req.emr_in_length = 0;
393 req.emr_out_buf = outbuf;
394 req.emr_out_length = sizeof(outbuf);
395
396 rc = hunt_mcdi(hunt, &req);
397 if (rc != 0)
398 return rc;
399
400 hunt->efx.port = MCDI_DWORD(req.emr_out_buf,
401 GET_PORT_ASSIGNMENT_OUT_PORT);
402 return 0;
403}
#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN
#define MC_CMD_GET_PORT_ASSIGNMENT

References hunt_nic::efx, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi(), MC_CMD_GET_PORT_ASSIGNMENT, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN, MCDI_DECLARE_BUF, MCDI_DWORD, NULL, efx_nic::port, and rc.

Referenced by hunt_probe().

◆ hunt_mac_addr()

int hunt_mac_addr ( struct hunt_nic * hunt,
uint8_t * ll_addr )
static

Definition at line 405 of file sfc_hunt.c.

406{
407 struct efx_mcdi_req_s req;
409 int rc;
410
411 req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
412 req.emr_in_buf = NULL;
413 req.emr_in_length = 0;
414 req.emr_out_buf = outbuf;
415 req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN;
416
417 rc = hunt_mcdi(hunt, &req);
418 if (rc != 0)
419 return rc;
420
421 if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)
422 return -EMSGSIZE;
423
424 memcpy(ll_addr,
425 MCDI_PTR(req.emr_out_buf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE),
426 ETH_ALEN);
427
428 return 0;
429}
#define ETH_ALEN
Definition if_ether.h:9
#define MC_CMD_GET_MAC_ADDRESSES_OUT_LEN
#define MC_CMD_GET_MAC_ADDRESSES
#define MCDI_PTR(_buf, _field)
Definition mcdi.h:41

References efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_mcdi_req_s::emr_out_length_used, EMSGSIZE, ETH_ALEN, hunt_mcdi(), MC_CMD_GET_MAC_ADDRESSES, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN, MCDI_DECLARE_BUF, MCDI_PTR, memcpy(), NULL, and rc.

Referenced by hunt_probe().

◆ hunt_get_phy_cfg()

int hunt_get_phy_cfg ( struct hunt_nic * hunt)
static

Definition at line 431 of file sfc_hunt.c.

432{
433 struct efx_mcdi_req_s req;
435 int rc;
436
437 req.emr_cmd = MC_CMD_GET_PHY_CFG;
438 req.emr_in_buf = NULL;
439 req.emr_in_length = 0;
440 req.emr_out_buf = outbuf;
441 req.emr_out_length = sizeof(outbuf);
442
443 rc = hunt_mcdi(hunt, &req);
444 if (rc != 0)
445 return rc;
446
447 if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN)
448 return -EMSGSIZE;
449
450 hunt->phy_cap_mask = hunt->phy_cap =
451 MCDI_DWORD(req.emr_out_buf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
452 DBGC2(hunt, "GET_PHY_CFG: flags=%x, caps=%x\n", rc, hunt->phy_cap);
453 return 0;
454}
#define DBGC2(...)
Definition compiler.h:522
#define MC_CMD_GET_PHY_CFG_OUT_LEN
#define MC_CMD_GET_PHY_CFG
unsigned int phy_cap
Definition sfc_hunt.c:59
unsigned int phy_cap_mask
Definition sfc_hunt.c:58

References DBGC2, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_mcdi_req_s::emr_out_length_used, EMSGSIZE, hunt_mcdi(), MC_CMD_GET_PHY_CFG, MC_CMD_GET_PHY_CFG_OUT_LEN, MCDI_DECLARE_BUF, MCDI_DWORD, NULL, hunt_nic::phy_cap, hunt_nic::phy_cap_mask, and rc.

Referenced by hunt_probe().

◆ hunt_driver_attach()

int hunt_driver_attach ( struct hunt_nic * hunt,
int attach )
static

Definition at line 456 of file sfc_hunt.c.

457{
458 struct efx_mcdi_req_s req;
461 int rc;
462
463 req.emr_cmd = MC_CMD_DRV_ATTACH;
464 req.emr_in_buf = inbuf;
465 req.emr_in_length = sizeof(inbuf);
466 req.emr_out_buf = outbuf;
467 req.emr_out_length = sizeof(outbuf);
468
469 /* Set the PREBOOT flag to indicate later instances of attach should
470 * force an ENTITY RESET
471 */
472 if (attach)
473 attach |= 1 << MC_CMD_DRV_PREBOOT_LBN;
474
475 MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_NEW_STATE, attach);
476 MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_UPDATE, 1);
477 MCDI_SET_DWORD(req.emr_in_buf, DRV_ATTACH_IN_FIRMWARE_ID,
479
480 rc = hunt_mcdi(hunt, &req);
481 if (rc != 0)
482 return rc;
483
484 if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_OUT_LEN)
485 return -EMSGSIZE;
486
487 hunt->flags = MCDI_DWORD(outbuf, DRV_ATTACH_EXT_OUT_FUNC_FLAGS);
488
489 return 0;
490}
#define MC_CMD_FW_DONT_CARE
#define MC_CMD_DRV_ATTACH_OUT_LEN
#define MC_CMD_DRV_ATTACH_EXT_OUT_LEN
#define MC_CMD_DRV_ATTACH_IN_LEN
#define MC_CMD_DRV_PREBOOT_LBN
#define MC_CMD_DRV_ATTACH

References efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_mcdi_req_s::emr_out_length_used, EMSGSIZE, hunt_nic::flags, hunt_mcdi(), MC_CMD_DRV_ATTACH, MC_CMD_DRV_ATTACH_EXT_OUT_LEN, MC_CMD_DRV_ATTACH_IN_LEN, MC_CMD_DRV_ATTACH_OUT_LEN, MC_CMD_DRV_PREBOOT_LBN, MC_CMD_FW_DONT_CARE, MCDI_DECLARE_BUF, MCDI_DWORD, MCDI_SET_DWORD, and rc.

Referenced by hunt_probe(), and hunt_remove().

◆ hunt_reset()

int hunt_reset ( struct hunt_nic * hunt)
static

Definition at line 492 of file sfc_hunt.c.

493{
494 struct efx_mcdi_req_s req;
496
497 req.emr_cmd = MC_CMD_ENTITY_RESET;
498 req.emr_in_buf = inbuf;
499 req.emr_in_length = sizeof(inbuf);
500 req.emr_out_buf = NULL;
501 req.emr_out_length = 0;
502
503 MCDI_POPULATE_DWORD_1(req.emr_in_buf, ENTITY_RESET_IN_FLAG,
504 ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
505 return hunt_mcdi(hunt, &req);
506}
#define MC_CMD_ENTITY_RESET
#define MC_CMD_ENTITY_RESET_IN_LEN
#define MCDI_POPULATE_DWORD_1(_buf, _field, _name1, _value1)
Definition mcdi.h:55

References efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi(), MC_CMD_ENTITY_RESET, MC_CMD_ENTITY_RESET_IN_LEN, MCDI_DECLARE_BUF, MCDI_POPULATE_DWORD_1, and NULL.

Referenced by hunt_close(), and hunt_probe().

◆ hunt_clear_udp_tunnel_ports()

void hunt_clear_udp_tunnel_ports ( struct hunt_nic * hunt)
static

Definition at line 508 of file sfc_hunt.c.

509{
512 struct efx_mcdi_req_s req;
513 int rc;
514
516 MCDI_SET_DWORD(inbuf, SET_TUNNEL_ENCAP_UDP_PORTS_IN_FLAGS,
518
520 req.emr_in_buf = inbuf;
521 req.emr_in_length = sizeof(inbuf);
522 req.emr_out_buf = outbuf;
523 req.emr_out_length = sizeof(outbuf);
524
525 rc = hunt_mcdi_quiet(hunt, &req);
526 if (rc)
527 return;
528
529 if (MCDI_DWORD(outbuf, SET_TUNNEL_ENCAP_UDP_PORTS_OUT_FLAGS) &
531 DBGC(hunt,
532 "Rebooting MC due to clearing UDP tunnel port list\n");
533 /* Delay for the MC reboot to complete. */
534 mdelay(100);
535 }
536}
void * memset(void *dest, int character, size_t len) __nonnull
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_LBN
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING_LBN
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN
static int hunt_mcdi_quiet(struct hunt_nic *hunt, struct efx_mcdi_req_s *req)
Definition sfc_hunt.c:300
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79

References DBGC, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi_quiet(), MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING_LBN, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_LBN, MCDI_DECLARE_BUF, MCDI_DWORD, MCDI_SET_DWORD, mdelay(), memset(), and rc.

Referenced by hunt_probe().

◆ hunt_set_mac()

int hunt_set_mac ( struct hunt_nic * hunt)
static

Definition at line 538 of file sfc_hunt.c.

539{
540 struct net_device *netdev = hunt->efx.netdev;
541 struct efx_mcdi_req_s req;
543 unsigned int fcntl;
544 int rc;
545
546 req.emr_cmd = MC_CMD_SET_MAC;
547 req.emr_in_buf = payload;
548 req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
549 req.emr_out_buf = NULL;
550 req.emr_out_length = 0;
551
552 MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_MTU,
554 MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_DRAIN, 0);
555 memcpy(MCDI_PTR(req.emr_in_buf, SET_MAC_IN_ADDR),
556 netdev->ll_addr, ETH_ALEN);
557 MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_REJECT, 0);
558
559 /* If the PHY supports autnegotiation, then configure the MAC to match
560 * the negotiated settings. Otherwise force the MAC to TX and RX flow
561 * control.
562 */
563 if (hunt->phy_cap_mask & (1 << MC_CMD_PHY_CAP_AN_LBN))
564 fcntl = MC_CMD_FCNTL_AUTO;
565 else
566 fcntl = MC_CMD_FCNTL_BIDIR;
567 MCDI_SET_DWORD(req.emr_in_buf, SET_MAC_IN_FCNTL, fcntl);
568
569 rc = hunt_mcdi(hunt, &req);
570 /* Ignore failure for permissions reasons */
571 if (rc == -EPERM)
572 rc = 0;
573 return rc;
574}
#define EFX_MAC_FRAME_LEN(_mtu)
Definition efx_common.h:190
static struct net_device * netdev
Definition gdbudp.c:53
#define ETH_FRAME_LEN
Definition if_ether.h:12
#define MC_CMD_PHY_CAP_AN_LBN
#define MC_CMD_FCNTL_BIDIR
#define MC_CMD_SET_MAC_IN_LEN
#define MC_CMD_SET_MAC
#define MC_CMD_FCNTL_AUTO
struct net_device * netdev
Definition efx_common.h:148
A network device.
Definition netdevice.h:353

References hunt_nic::efx, EFX_MAC_FRAME_LEN, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, EPERM, ETH_ALEN, ETH_FRAME_LEN, hunt_mcdi(), MC_CMD_FCNTL_AUTO, MC_CMD_FCNTL_BIDIR, MC_CMD_PHY_CAP_AN_LBN, MC_CMD_SET_MAC, MC_CMD_SET_MAC_IN_LEN, MCDI_DECLARE_BUF, MCDI_PTR, MCDI_SET_DWORD, memcpy(), efx_nic::netdev, netdev, NULL, hunt_nic::phy_cap_mask, and rc.

Referenced by hunt_open().

◆ hunt_alloc_vis()

int hunt_alloc_vis ( struct hunt_nic * hunt)
static

Definition at line 576 of file sfc_hunt.c.

577{
578 struct efx_mcdi_req_s req;
580
581 req.emr_cmd = MC_CMD_ALLOC_VIS;
582 req.emr_in_buf = inbuf;
583 req.emr_in_length = sizeof(inbuf);
584 req.emr_out_buf = NULL;
585 req.emr_out_length = 0;
586
587 MCDI_SET_DWORD(req.emr_in_buf, ALLOC_VIS_IN_MIN_VI_COUNT, 1);
588 MCDI_SET_DWORD(req.emr_in_buf, ALLOC_VIS_IN_MAX_VI_COUNT, 1);
589
590 return hunt_mcdi(hunt, &req);
591}
#define MC_CMD_ALLOC_VIS_IN_LEN
#define MC_CMD_ALLOC_VIS

References efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi(), MC_CMD_ALLOC_VIS, MC_CMD_ALLOC_VIS_IN_LEN, MCDI_DECLARE_BUF, MCDI_SET_DWORD, and NULL.

Referenced by hunt_open().

◆ hunt_free_vis()

void hunt_free_vis ( struct hunt_nic * hunt)
static

Definition at line 593 of file sfc_hunt.c.

594{
595 struct efx_mcdi_req_s req;
596 int rc;
597
598 req.emr_cmd = MC_CMD_FREE_VIS;
599 req.emr_in_buf = NULL;
600 req.emr_in_length = 0;
601 req.emr_out_buf = NULL;
602 req.emr_out_length = 0;
603
604 rc = hunt_mcdi(hunt, &req);
605 if (rc != 0)
606 DBGC(hunt, "MC_CMD_FREE_VIS Failed\n");
607}
#define MC_CMD_FREE_VIS

References DBGC, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi(), MC_CMD_FREE_VIS, NULL, and rc.

Referenced by hunt_close(), and hunt_open().

◆ hunt_check_link()

int hunt_check_link ( struct hunt_nic * hunt)
static

Definition at line 616 of file sfc_hunt.c.

617{
618 struct efx_mcdi_req_s req;
620 unsigned int flags, speed;
621 bool up;
622 int rc;
623 static bool link_state = false;
624
625 req.emr_cmd = MC_CMD_GET_LINK;
626 req.emr_in_buf = NULL;
627 req.emr_in_length = 0;
628 req.emr_out_buf = outbuf;
629 req.emr_out_length = sizeof(outbuf);
630
631 rc = hunt_mcdi(hunt, &req);
632 if (rc != 0)
633 return rc;
634
635 if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN)
636 return -EMSGSIZE;
637
638 flags = MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_FLAGS);
639 up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
640 speed = MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_LINK_SPEED);
641
642 /* Set netdev_link_*() based on the link status from the MC */
643 if (up && speed)
645 else
647
648 if (up != link_state) {
649 DBGC(hunt, "Link %s, flags=%x, our caps=%x, lpa=%x, speed=%d, fcntl=%x, mac_fault=%x\n",
650 (up? "up": "down"), flags,
651 MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_CAP),
652 MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_LP_CAP),
653 speed,
654 MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_FCNTL),
655 MCDI_DWORD(req.emr_out_buf, GET_LINK_OUT_MAC_FAULT));
656 link_state = up;
657 }
658
659 return 0;
660}
uint8_t flags
Flags.
Definition ena.h:7
#define MC_CMD_GET_LINK_OUT_LEN
#define MC_CMD_GET_LINK
#define MC_CMD_GET_LINK_OUT_LINK_UP_LBN
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition netdevice.c:231
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789

References DBGC, hunt_nic::efx, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_mcdi_req_s::emr_out_length_used, EMSGSIZE, flags, hunt_mcdi(), MC_CMD_GET_LINK, MC_CMD_GET_LINK_OUT_LEN, MC_CMD_GET_LINK_OUT_LINK_UP_LBN, MCDI_DECLARE_BUF, MCDI_DWORD, efx_nic::netdev, netdev_link_down(), netdev_link_up(), NULL, and rc.

Referenced by hunt_open(), and hunt_poll().

◆ hunt_tx_init()

int hunt_tx_init ( struct net_device * netdev,
struct hunt_nic * hunt )
static

Definition at line 679 of file sfc_hunt.c.

680{
681 struct efx_mcdi_req_s req;
682 dma_addr_t dma_addr;
684 MCDI_DECLARE_BUF(inbuf,
686 int rc, npages;
687
688 rc = efx_hunt_tx_init(netdev, &dma_addr);
689 if (rc != 0)
690 return rc;
691
692 npages = EFX_TXQ_NBUFS(EFX_TXD_SIZE);
693
694 req.emr_cmd = MC_CMD_INIT_TXQ;
695 req.emr_in_buf = inbuf;
696 req.emr_in_length = MC_CMD_INIT_TXQ_IN_LEN(npages);
697 req.emr_out_buf = NULL;
698 req.emr_out_length = 0;
699
700 MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_SIZE, EFX_TXD_SIZE);
701 MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_TARGET_EVQ, 0);
702 MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_LABEL, 0);
703 MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_INSTANCE, 0);
704
705 MCDI_POPULATE_DWORD_6(req.emr_in_buf, INIT_TXQ_IN_FLAGS,
706 INIT_TXQ_IN_FLAG_BUFF_MODE, 0,
707 INIT_TXQ_IN_FLAG_IP_CSUM_DIS, 1,
708 INIT_TXQ_IN_FLAG_TCP_CSUM_DIS, 1,
709 INIT_TXQ_IN_FLAG_TCP_UDP_ONLY, 0,
710 INIT_TXQ_IN_CRC_MODE, 0,
711 INIT_TXQ_IN_FLAG_TIMESTAMP, 0);
712
713 MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_OWNER_ID, 0);
714 MCDI_SET_DWORD(req.emr_in_buf, INIT_TXQ_IN_PORT_ID,
716
717 addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_TXQ_IN_DMA_ADDR);
718
720 EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
721 EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
722
723 return hunt_mcdi(hunt, &req);
724}
uint32_t addr
Buffer address.
Definition dwmac.h:9
#define EFX_POPULATE_QWORD_2(qword,...)
#define EFX_TXD_SIZE
Definition efx_common.h:58
int efx_hunt_tx_init(struct net_device *netdev, dma_addr_t *dma_addr)
Definition efx_hunt.c:157
#define EFX_TXQ_NBUFS(_ndescs)
Definition efx_hunt.h:41
#define dma_addr_t
#define MC_CMD_INIT_TXQ_IN_LEN(num)
#define MC_CMD_INIT_TXQ
#define EVB_PORT_ID_ASSIGNED
#define MCDI_POPULATE_DWORD_6(_buf, _field, _name1, _value1, _name2, _value2, _name3, _value3, _name4, _value4, _name5, _value5, _name6, _value6)
Definition mcdi.h:86

References addr, dma_addr_t, efx_hunt_tx_init(), EFX_POPULATE_QWORD_2, EFX_TXD_SIZE, EFX_TXQ_NBUFS, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, EVB_PORT_ID_ASSIGNED, hunt_mcdi(), MC_CMD_INIT_TXQ, MC_CMD_INIT_TXQ_IN_LEN, MCDI_DECLARE_BUF, MCDI_POPULATE_DWORD_6, MCDI_PTR, MCDI_SET_DWORD, netdev, NULL, and rc.

Referenced by hunt_open().

◆ hunt_tx_fini()

void hunt_tx_fini ( struct hunt_nic * hunt)
static

Definition at line 726 of file sfc_hunt.c.

727{
728 struct efx_mcdi_req_s req;
730 struct efx_nic *efx = &hunt->efx;
731 struct efx_tx_queue *txq = &efx->txq;
732 int rc;
733
734 req.emr_cmd = MC_CMD_FINI_TXQ;
735 req.emr_in_buf = inbuf;
736 req.emr_in_length = sizeof(inbuf);
737 req.emr_out_buf = NULL;
738 req.emr_out_length = 0;
739
740 MCDI_SET_DWORD(req.emr_in_buf, FINI_TXQ_IN_INSTANCE, 0);
741
742 rc = hunt_mcdi(hunt, &req);
743 if (rc != 0)
744 DBGC(hunt, "MC_CMD_FINI_TXQ Failed\n");
745
747 sizeof(efx_tx_desc_t) * EFX_TXD_SIZE);
748 txq->ring = NULL;
749}
efx_qword_t efx_tx_desc_t
Definition efx_common.h:52
void efx_hunt_free_special_buffer(void *buf, int bytes)
Definition efx_hunt.c:40
#define MC_CMD_FINI_TXQ
#define MC_CMD_FINI_TXQ_IN_LEN
Hardware access.
Definition efx_common.h:147
struct efx_tx_queue txq
Definition efx_common.h:165
A transmit queue.
Definition efx_common.h:89
efx_tx_desc_t * ring
Definition efx_common.h:91

References DBGC, hunt_nic::efx, efx_hunt_free_special_buffer(), EFX_TXD_SIZE, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi(), MC_CMD_FINI_TXQ, MC_CMD_FINI_TXQ_IN_LEN, MCDI_DECLARE_BUF, MCDI_SET_DWORD, NULL, rc, efx_tx_queue::ring, and efx_nic::txq.

Referenced by hunt_close(), and hunt_open().

◆ hunt_rx_filter_insert()

int hunt_rx_filter_insert ( struct net_device * netdev,
struct hunt_nic * hunt,
int multicast )
static

Definition at line 758 of file sfc_hunt.c.

761{
762 struct efx_mcdi_req_s req;
765 int rc;
766 uint64_t filter_id;
767 (void) netdev;
768
769 req.emr_cmd = MC_CMD_FILTER_OP;
770 req.emr_in_buf = inbuf;
771 req.emr_in_length = sizeof(inbuf);
772 req.emr_out_buf = outbuf;
773 req.emr_out_length = sizeof(outbuf);
774
775 MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_OP,
778 MCDI_POPULATE_DWORD_1(req.emr_in_buf, FILTER_OP_IN_MATCH_FIELDS,
779 FILTER_OP_IN_MATCH_DST_MAC, 1);
780 if (multicast)
781 memset(MCDI_PTR(req.emr_in_buf, FILTER_OP_IN_DST_MAC),
782 0xff, ETH_ALEN);
783 else
784 memcpy(MCDI_PTR(req.emr_in_buf, FILTER_OP_IN_DST_MAC),
785 hunt->mac, ETH_ALEN);
786
787 MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_PORT_ID,
789 MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_DEST,
791 MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_QUEUE, 0);
792 MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_RX_MODE, 0);
793 MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_TX_DEST,
795
796 rc = hunt_mcdi(hunt, &req);
797 if (rc != 0)
798 return rc;
799
800 if (req.emr_out_length_used < MC_CMD_FILTER_OP_OUT_LEN)
801 return -EIO;
802
803 filter_id = MCDI_QWORD(req.emr_out_buf, FILTER_OP_OUT_HANDLE);
804 if (multicast)
805 hunt->mc_filter_id = filter_id;
806 else
807 hunt->uc_filter_id = filter_id;
808
809 return 0;
810}
unsigned long long uint64_t
Definition stdint.h:13
#define MC_CMD_FILTER_OP_IN_OP_INSERT
#define MC_CMD_FILTER_OP
#define MC_CMD_FILTER_OP_IN_LEN
#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE
#define MC_CMD_FILTER_OP_OUT_LEN
#define MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT
#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST
#define MCDI_QWORD(_buf, _field)
Definition mcdi.h:116
u8 mac[ETH_ALEN]
Definition sfc_hunt.c:65
uint64_t uc_filter_id
Definition sfc_hunt.c:63
uint64_t mc_filter_id
Definition sfc_hunt.c:64

References EIO, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_mcdi_req_s::emr_out_length_used, ETH_ALEN, EVB_PORT_ID_ASSIGNED, hunt_mcdi(), hunt_nic::mac, MC_CMD_FILTER_OP, MC_CMD_FILTER_OP_IN_LEN, MC_CMD_FILTER_OP_IN_OP_INSERT, MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE, MC_CMD_FILTER_OP_IN_RX_DEST_HOST, MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT, MC_CMD_FILTER_OP_OUT_LEN, hunt_nic::mc_filter_id, MCDI_DECLARE_BUF, MCDI_POPULATE_DWORD_1, MCDI_PTR, MCDI_QWORD, MCDI_SET_DWORD, memcpy(), memset(), netdev, rc, and hunt_nic::uc_filter_id.

Referenced by hunt_rx_filter_init().

◆ hunt_rx_filter_remove()

int hunt_rx_filter_remove ( struct hunt_nic * hunt,
int multicast )
static

Definition at line 812 of file sfc_hunt.c.

814{
815 struct efx_mcdi_req_s req;
817
818 req.emr_cmd = MC_CMD_FILTER_OP;
819 req.emr_in_buf = inbuf;
820 req.emr_in_length = sizeof(inbuf);
821 req.emr_out_buf = NULL;
822 req.emr_out_length = 0;
823
824 MCDI_SET_DWORD(req.emr_in_buf, FILTER_OP_IN_OP,
827 MCDI_SET_QWORD(req.emr_in_buf, FILTER_OP_IN_HANDLE,
828 multicast ? hunt->mc_filter_id :
829 hunt->uc_filter_id);
830 return hunt_mcdi(hunt, &req);
831}
#define MC_CMD_FILTER_OP_IN_OP_REMOVE
#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE
#define MCDI_SET_QWORD(_buf, _field, _value)
Definition mcdi.h:109

References efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi(), MC_CMD_FILTER_OP, MC_CMD_FILTER_OP_IN_LEN, MC_CMD_FILTER_OP_IN_OP_REMOVE, MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE, hunt_nic::mc_filter_id, MCDI_DECLARE_BUF, MCDI_SET_DWORD, MCDI_SET_QWORD, NULL, and hunt_nic::uc_filter_id.

Referenced by hunt_rx_filter_fini(), and hunt_rx_filter_init().

◆ hunt_get_mac()

int hunt_get_mac ( struct hunt_nic * hunt)
static

Definition at line 833 of file sfc_hunt.c.

834{
835 struct efx_mcdi_req_s req;
837 int rc;
838
839 req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
840 req.emr_in_buf = NULL;
841 req.emr_in_length = 0;
842 req.emr_out_buf = outbuf;
843 req.emr_out_length = sizeof(outbuf);
844
845 rc = hunt_mcdi(hunt, &req);
846 if (rc != 0)
847 return rc;
848
849 if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN)
850 return -EMSGSIZE;
851
852 memcpy(hunt->mac, MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE),
853 ETH_ALEN);
854 return 0;
855}
#define MC_CMD_INIT_EVQ_OUT_LEN

References efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_mcdi_req_s::emr_out_length_used, EMSGSIZE, ETH_ALEN, hunt_mcdi(), hunt_nic::mac, MC_CMD_GET_MAC_ADDRESSES, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN, MC_CMD_INIT_EVQ_OUT_LEN, MCDI_DECLARE_BUF, MCDI_PTR, memcpy(), NULL, and rc.

Referenced by hunt_rx_filter_init().

◆ hunt_rx_filter_init()

int hunt_rx_filter_init ( struct net_device * netdev,
struct hunt_nic * hunt )
static

Definition at line 857 of file sfc_hunt.c.

859{
860 int rc = hunt_get_mac(hunt);
861
862 if (rc != 0)
863 return rc;
864
865 rc = hunt_rx_filter_insert(netdev, hunt, 0);
866 if (rc != 0)
867 return rc;
868
869 rc = hunt_rx_filter_insert(netdev, hunt, 1);
870 if (rc != 0)
871 hunt_rx_filter_remove(hunt, 0);
872
873 return rc;
874}
static int hunt_rx_filter_remove(struct hunt_nic *hunt, int multicast)
Definition sfc_hunt.c:812
static int hunt_get_mac(struct hunt_nic *hunt)
Definition sfc_hunt.c:833
static int hunt_rx_filter_insert(struct net_device *netdev, struct hunt_nic *hunt, int multicast)
Definition sfc_hunt.c:758

References hunt_get_mac(), hunt_rx_filter_insert(), hunt_rx_filter_remove(), netdev, and rc.

Referenced by hunt_open().

◆ hunt_rx_init()

int hunt_rx_init ( struct net_device * netdev,
struct hunt_nic * hunt )
static

Definition at line 877 of file sfc_hunt.c.

879{
880 struct efx_mcdi_req_s req;
881 dma_addr_t dma_addr;
883 MCDI_DECLARE_BUF(inbuf,
885 int rc, npages;
886
887 rc = efx_hunt_rx_init(netdev, &dma_addr);
888 if (rc != 0)
889 return rc;
890
891 npages = EFX_RXQ_NBUFS(EFX_RXD_SIZE);
892
893 req.emr_cmd = MC_CMD_INIT_RXQ;
894 req.emr_in_buf = inbuf;
895 req.emr_in_length = MC_CMD_INIT_RXQ_IN_LEN(npages);
896 req.emr_out_buf = NULL;
897 req.emr_out_length = 0;
898
899 MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_SIZE, EFX_RXD_SIZE);
900 MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_TARGET_EVQ, 0);
901 MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_LABEL, 0);
902 MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_INSTANCE, 0);
903 MCDI_POPULATE_DWORD_5(req.emr_in_buf, INIT_RXQ_IN_FLAGS,
904 INIT_RXQ_IN_FLAG_BUFF_MODE, 0,
905 INIT_RXQ_IN_FLAG_HDR_SPLIT, 0,
906 INIT_RXQ_IN_FLAG_TIMESTAMP, 0,
907 INIT_RXQ_IN_CRC_MODE, 0,
908 INIT_RXQ_IN_FLAG_PREFIX, 1);
909 MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_OWNER_ID, 0);
910 MCDI_SET_DWORD(req.emr_in_buf, INIT_RXQ_IN_PORT_ID,
912
913 addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_RXQ_IN_DMA_ADDR);
914
916 EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
917 EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
918 return hunt_mcdi(hunt, &req);
919}
#define EFX_RXD_SIZE
Definition efx_common.h:56
int efx_hunt_rx_init(struct net_device *netdev, dma_addr_t *dma_addr)
Definition efx_hunt.c:272
#define EFX_RXQ_NBUFS(_ndescs)
Definition efx_hunt.h:38
#define MC_CMD_INIT_RXQ
#define MC_CMD_INIT_RXQ_IN_LEN(num)
#define MCDI_POPULATE_DWORD_5(_buf, _field, _name1, _value1, _name2, _value2, _name3, _value3, _name4, _value4, _name5, _value5)
Definition mcdi.h:77

References addr, dma_addr_t, efx_hunt_rx_init(), EFX_POPULATE_QWORD_2, EFX_RXD_SIZE, EFX_RXQ_NBUFS, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, EVB_PORT_ID_ASSIGNED, hunt_mcdi(), MC_CMD_INIT_RXQ, MC_CMD_INIT_RXQ_IN_LEN, MCDI_DECLARE_BUF, MCDI_POPULATE_DWORD_5, MCDI_PTR, MCDI_SET_DWORD, netdev, NULL, and rc.

Referenced by hunt_open().

◆ hunt_rx_filter_fini()

void hunt_rx_filter_fini ( struct hunt_nic * hunt)
static

Definition at line 921 of file sfc_hunt.c.

922{
923 hunt_rx_filter_remove(hunt, 0);
924 hunt_rx_filter_remove(hunt, 1);
925}

References hunt_rx_filter_remove().

Referenced by hunt_close(), and hunt_open().

◆ hunt_rx_fini()

void hunt_rx_fini ( struct hunt_nic * hunt)
static

Definition at line 927 of file sfc_hunt.c.

928{
930 struct efx_mcdi_req_s req;
931 struct efx_nic *efx = &hunt->efx;
932 struct efx_rx_queue *rxq = &efx->rxq;
933 int rc;
934
935 req.emr_cmd = MC_CMD_FINI_RXQ;
936 req.emr_in_buf = inbuf;
937 req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN;
938 req.emr_out_buf = NULL;
939 req.emr_out_length = 0;
940
941 MCDI_SET_DWORD(req.emr_in_buf, FINI_RXQ_IN_INSTANCE, 0);
942
943 rc = hunt_mcdi(hunt, &req);
944 if (rc != 0)
945 DBGC(hunt, "MC_CMD_FINI_RXQ Failed\n");
946
948 sizeof(efx_rx_desc_t) * EFX_RXD_SIZE);
949 rxq->ring = NULL;
950}
efx_qword_t efx_rx_desc_t
Definition efx_common.h:51
#define MC_CMD_FINI_RXQ_IN_LEN
#define MC_CMD_FINI_RXQ
struct efx_rx_queue rxq
Definition efx_common.h:164
A receive queue.
Definition efx_common.h:107
efx_rx_desc_t * ring
Definition efx_common.h:109

References DBGC, hunt_nic::efx, efx_hunt_free_special_buffer(), EFX_RXD_SIZE, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, hunt_mcdi(), MC_CMD_FINI_RXQ, MC_CMD_FINI_RXQ_IN_LEN, MCDI_DECLARE_BUF, MCDI_SET_DWORD, NULL, rc, efx_rx_queue::ring, and efx_nic::rxq.

Referenced by hunt_close(), and hunt_open().

◆ hunt_ev_init()

int hunt_ev_init ( struct net_device * netdev,
struct hunt_nic * hunt )
static

Definition at line 960 of file sfc_hunt.c.

962{
963 struct efx_mcdi_req_s req;
964 dma_addr_t dma_addr;
966 MCDI_DECLARE_BUF(inbuf,
969 int rc, npages;
970
971 rc = efx_hunt_ev_init(netdev, &dma_addr);
972 if (rc != 0)
973 return rc;
974
975 npages = EFX_EVQ_NBUFS(EFX_EVQ_SIZE);
976
977 req.emr_cmd = MC_CMD_INIT_EVQ;
978 req.emr_in_buf = inbuf;
979 req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
980 req.emr_out_buf = outbuf;
981 req.emr_out_length = sizeof(outbuf);
982
983 MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_SIZE, EFX_EVQ_SIZE);
984 MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_INSTANCE, 0);
985 MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_IRQ_NUM, 0);
986
987 MCDI_POPULATE_DWORD_6(req.emr_in_buf, INIT_EVQ_IN_FLAGS,
988 INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
989 INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
990 INIT_EVQ_IN_FLAG_INT_ARMD, 0,
991 INIT_EVQ_IN_FLAG_CUT_THRU, 0,
992 INIT_EVQ_IN_FLAG_RX_MERGE, 0,
993 INIT_EVQ_IN_FLAG_TX_MERGE, 0);
994
995 MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_MODE,
997 MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_LOAD, 0);
998 MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_TMR_RELOAD, 0);
999
1000 MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_COUNT_MODE,
1002 MCDI_SET_DWORD(req.emr_in_buf, INIT_EVQ_IN_COUNT_THRSHLD, 0);
1003
1004 addr = (efx_qword_t *) MCDI_PTR(req.emr_in_buf, INIT_EVQ_IN_DMA_ADDR);
1005
1007 EFX_DWORD_1, (uint32_t)(dma_addr >> 32),
1008 EFX_DWORD_0, (uint32_t)(dma_addr & 0xffffffff));
1009 rc = hunt_mcdi(hunt, &req);
1010 if (rc != 0)
1011 return rc;
1012
1013 if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN)
1014 return -EMSGSIZE;
1015
1016 return 0;
1017}
#define EFX_EVQ_SIZE
Definition efx_common.h:60
int efx_hunt_ev_init(struct net_device *netdev, dma_addr_t *dma_addr)
Definition efx_hunt.c:296
#define EFX_EVQ_NBUFS(_nevs)
Definition efx_hunt.h:35
#define MC_CMD_INIT_EVQ
#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS
#define MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS
#define MC_CMD_INIT_EVQ_IN_LEN(num)

References addr, dma_addr_t, EFX_EVQ_NBUFS, EFX_EVQ_SIZE, efx_hunt_ev_init(), EFX_POPULATE_QWORD_2, efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_mcdi_req_s::emr_out_length_used, EMSGSIZE, hunt_mcdi(), MC_CMD_INIT_EVQ, MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS, MC_CMD_INIT_EVQ_IN_LEN, MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS, MC_CMD_INIT_EVQ_OUT_LEN, MCDI_DECLARE_BUF, MCDI_POPULATE_DWORD_6, MCDI_PTR, MCDI_SET_DWORD, netdev, and rc.

Referenced by hunt_open().

◆ hunt_ev_fini()

void hunt_ev_fini ( struct hunt_nic * hunt)
static

Definition at line 1019 of file sfc_hunt.c.

1020{
1022 struct efx_mcdi_req_s req;
1023 struct efx_nic *efx = &hunt->efx;
1024 struct efx_ev_queue *evq = &efx->evq;
1025 int rc;
1026
1027 req.emr_cmd = MC_CMD_FINI_EVQ;
1028 req.emr_in_buf = inbuf;
1029 req.emr_in_length = sizeof(inbuf);
1030 req.emr_out_buf = NULL;
1031 req.emr_out_length = 0;
1032
1033 MCDI_SET_DWORD(req.emr_in_buf, FINI_EVQ_IN_INSTANCE, 0);
1034
1035 rc = hunt_mcdi(hunt, &req);
1036 if (rc != 0)
1037 DBGC(hunt, "MC_CMD_FINI_EVQ Failed\n");
1038
1040 sizeof(efx_event_t) * EFX_EVQ_SIZE);
1041 evq->ring = NULL;
1042}
efx_qword_t efx_event_t
Definition efx_common.h:53
#define MC_CMD_FINI_EVQ_IN_LEN
#define MC_CMD_FINI_EVQ
An event queue.
Definition efx_common.h:128
efx_event_t * ring
Definition efx_common.h:132
struct efx_ev_queue evq
Definition efx_common.h:166

References DBGC, hunt_nic::efx, EFX_EVQ_SIZE, efx_hunt_free_special_buffer(), efx_mcdi_req_s::emr_cmd, efx_mcdi_req_s::emr_in_buf, efx_mcdi_req_s::emr_in_length, efx_mcdi_req_s::emr_out_buf, efx_mcdi_req_s::emr_out_length, efx_nic::evq, hunt_mcdi(), MC_CMD_FINI_EVQ, MC_CMD_FINI_EVQ_IN_LEN, MCDI_DECLARE_BUF, MCDI_SET_DWORD, NULL, rc, and efx_ev_queue::ring.

Referenced by hunt_close(), and hunt_open().

◆ hunt_poll()

void hunt_poll ( struct net_device * netdev)
static

Definition at line 1045 of file sfc_hunt.c.

1046{
1047 struct hunt_nic *hunt = netdev->priv;
1048
1049 /* If called while already polling, return immediately */
1050 if (hunt->efx.state & EFX_STATE_POLLING)
1051 return;
1052 hunt->efx.state |= EFX_STATE_POLLING;
1053
1054 /* Poll link state */
1055 if (hunt->link_poll_timer + TICKS_PER_SEC < currticks()) {
1056 hunt->link_poll_timer = currticks();
1057 hunt_check_link(hunt);
1058 }
1059
1060 /* Poll data path */
1062
1063 hunt->efx.state &= ~EFX_STATE_POLLING;
1064}
#define EFX_STATE_POLLING
Definition efx_common.h:78
void efx_hunt_poll(struct net_device *netdev)
Definition efx_hunt.c:406
static int hunt_check_link(struct hunt_nic *hunt)
Definition sfc_hunt.c:616
u32 state
Definition efx_common.h:153
unsigned long link_poll_timer
Definition sfc_hunt.c:60

References currticks(), hunt_nic::efx, efx_hunt_poll(), EFX_STATE_POLLING, hunt_check_link(), hunt_nic::link_poll_timer, netdev, efx_nic::state, and TICKS_PER_SEC.

◆ hunt_open()

int hunt_open ( struct net_device * netdev)
static

Definition at line 1073 of file sfc_hunt.c.

1074{
1075 struct hunt_nic *hunt = netdev->priv;
1076 int rc;
1077
1078 /* Allocate VIs */
1079 rc = hunt_alloc_vis(hunt);
1080 if (rc != 0)
1081 goto fail2;
1082
1083 /* Initialize data path */
1084 rc = hunt_ev_init(netdev, hunt);
1085 if (rc != 0)
1086 goto fail3;
1087
1088 rc = hunt_rx_init(netdev, hunt);
1089 if (rc != 0)
1090 goto fail4;
1091
1092 rc = hunt_rx_filter_init(netdev, hunt);
1093 if (rc != 0)
1094 goto fail5;
1095
1096 rc = hunt_tx_init(netdev, hunt);
1097 if (rc != 0)
1098 goto fail6;
1099
1101 if (rc)
1102 goto fail7;
1103
1104 rc = hunt_set_mac(hunt);
1105 if (rc)
1106 goto fail8;
1107
1108 /* Mark the link as down before checking the link state because the
1109 * latter might fail.
1110 */
1112 hunt_check_link(hunt);
1113
1114 DBGC2(hunt, "%s: open ok\n", netdev->name);
1115 return 0;
1116
1117fail8:
1119fail7:
1120 hunt_tx_fini(hunt);
1121fail6:
1122 hunt_rx_filter_fini(hunt);
1123fail5:
1124 hunt_rx_fini(hunt);
1125fail4:
1126 hunt_ev_fini(hunt);
1127fail3:
1128 hunt_free_vis(hunt);
1129fail2:
1130 DBGC2(hunt, "%s: %s\n", netdev->name, strerror(rc));
1131 return rc;
1132}
int efx_hunt_open(struct net_device *netdev)
Definition efx_hunt.c:467
void efx_hunt_close(struct net_device *netdev)
Definition efx_hunt.c:488
static void hunt_rx_filter_fini(struct hunt_nic *hunt)
Definition sfc_hunt.c:921
static int hunt_rx_filter_init(struct net_device *netdev, struct hunt_nic *hunt)
Definition sfc_hunt.c:857
static void hunt_free_vis(struct hunt_nic *hunt)
Definition sfc_hunt.c:593
static int hunt_alloc_vis(struct hunt_nic *hunt)
Definition sfc_hunt.c:576
static int hunt_ev_init(struct net_device *netdev, struct hunt_nic *hunt)
Definition sfc_hunt.c:960
static void hunt_tx_fini(struct hunt_nic *hunt)
Definition sfc_hunt.c:726
static int hunt_tx_init(struct net_device *netdev, struct hunt_nic *hunt)
Definition sfc_hunt.c:679
static int hunt_rx_init(struct net_device *netdev, struct hunt_nic *hunt)
Definition sfc_hunt.c:877
static void hunt_rx_fini(struct hunt_nic *hunt)
Definition sfc_hunt.c:927
static void hunt_ev_fini(struct hunt_nic *hunt)
Definition sfc_hunt.c:1019
static int hunt_set_mac(struct hunt_nic *hunt)
Definition sfc_hunt.c:538

References DBGC2, efx_hunt_close(), efx_hunt_open(), hunt_alloc_vis(), hunt_check_link(), hunt_ev_fini(), hunt_ev_init(), hunt_free_vis(), hunt_rx_filter_fini(), hunt_rx_filter_init(), hunt_rx_fini(), hunt_rx_init(), hunt_set_mac(), hunt_tx_fini(), hunt_tx_init(), netdev, netdev_link_down(), rc, and strerror().

◆ hunt_close()

void hunt_close ( struct net_device * netdev)
static

Definition at line 1135 of file sfc_hunt.c.

1136{
1137 struct hunt_nic *hunt = netdev->priv;
1138
1139 /* Stop datapath */
1141
1142 hunt_tx_fini(hunt);
1143 hunt_rx_fini(hunt);
1144 hunt_rx_filter_fini(hunt);
1145 hunt_ev_fini(hunt);
1146
1147 hunt_free_vis(hunt);
1148
1149 /* Reset hardware and detach */
1150 hunt_reset(hunt);
1151}
static int hunt_reset(struct hunt_nic *hunt)
Definition sfc_hunt.c:492

References efx_hunt_close(), hunt_ev_fini(), hunt_free_vis(), hunt_reset(), hunt_rx_filter_fini(), hunt_rx_fini(), hunt_tx_fini(), and netdev.

◆ hunt_probe()

int hunt_probe ( struct pci_device * pci)
static

Definition at line 1171 of file sfc_hunt.c.

1172{
1173 struct net_device *netdev;
1174 struct hunt_nic *hunt;
1175 struct efx_nic *efx;
1176 int rc = 0;
1177
1178 /* Create the network adapter */
1179 netdev = alloc_etherdev(sizeof(struct hunt_nic));
1180 if (!netdev) {
1181 rc = -ENOMEM;
1182 goto fail1;
1183 }
1184
1185 /* Initialise the network adapter, and initialise private storage */
1187 pci_set_drvdata(pci, netdev);
1188 netdev->dev = &pci->dev;
1190
1191 hunt = netdev->priv;
1192 memset(hunt, 0, sizeof(*hunt));
1193 efx = &hunt->efx;
1194
1195 efx->type = &hunt_nic_type;
1196
1197 /* Initialise efx datapath */
1199
1200 /* Initialise MCDI. In case we are recovering from a crash, first
1201 * cancel any outstanding request by sending a special message using the
1202 * least significant bits of the 'high' (doorbell) register.
1203 */
1205 rc = hunt_mcdi_init(hunt);
1206 if (rc != 0)
1207 goto fail2;
1208
1209 /* Reset (most) configuration for this function */
1210 rc = hunt_reset(hunt);
1211 if (rc != 0)
1212 goto fail3;
1213
1214 /* Medford has a list of UDP tunnel ports that is populated by the
1215 * driver. Avoid dropping any unencapsulated packets. This may cause
1216 * an MC reboot.
1217 */
1219
1220 /* Enable the workaround for bug35388, if supported */
1222
1223 /* Set the RX packet prefix size */
1225
1227 if (rc != 0)
1228 goto fail3;
1229
1230 rc = hunt_mac_addr(hunt, netdev->ll_addr);
1231 if (rc != 0)
1232 goto fail4;
1233
1234 rc = hunt_get_phy_cfg(hunt);
1235 if (rc != 0)
1236 goto fail5;
1237
1238 rc = hunt_driver_attach(hunt, 1);
1239 if (rc != 0)
1240 goto fail5;
1241
1242 /* If not exposing this network device, return successfully here */
1244 return 0;
1245
1246 if (hunt_nic_is_primary(hunt)) {
1247 hunt->next_primary = primary_nics;
1248 primary_nics = hunt;
1249 hunt->primary = hunt;
1250 } else {
1251 struct hunt_nic *other_hunt = primary_nics;
1252
1253 while (other_hunt && !hunt->primary) {
1254 struct pci_device *other_pci = (struct pci_device *)
1255 other_hunt->efx.netdev->dev;
1256 /* Check if the seg:bus:dev parts match. */
1257 if (PCI_FIRST_FUNC(other_pci->busdevfn) ==
1259 hunt->primary = other_hunt;
1260
1261 other_hunt = other_hunt->next_primary;
1262 }
1263 if (!hunt->primary) {
1264 rc = -EIO;
1265 goto fail6;
1266 }
1267 }
1268
1270 if (rc != 0)
1271 goto fail8;
1272
1273 DBG2("%s " PCI_FMT " ok\n", __func__, PCI_ARGS(pci));
1274 return 0;
1275
1276fail8:
1277fail6:
1278 (void) hunt_driver_attach(hunt, 0);
1279fail5:
1280fail4:
1281fail3:
1282 hunt_mcdi_fini(hunt);
1283fail2:
1286fail1:
1287 DBG2("%s " PCI_FMT " rc=%d\n", __func__, PCI_ARGS(pci), rc);
1288 return rc;
1289}
#define ES_DZ_RX_PREFIX_SIZE
Definition ef10_regs.h:362
void efx_remove(struct net_device *netdev)
Definition efx_common.c:98
void efx_probe(struct net_device *netdev, enum efx_revision revision)
Definition efx_common.c:71
const struct efx_nic_type hunt_nic_type
Definition sfc_hunt.c:1314
@ EFX_HUNTINGTON
Definition efx_common.h:143
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
#define DBG2(...)
Definition compiler.h:515
#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
#define NETDEV_IRQ_UNSUPPORTED
Network device interrupts are unsupported.
Definition netdevice.h:453
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
#define PCI_FMT
PCI device debug message format.
Definition pci.h:312
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition pci.h:315
#define PCI_FIRST_FUNC(busdevfn)
Definition pci.h:287
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:366
static void hunt_mcdi_fini(struct hunt_nic *hunt)
Definition sfc_hunt.c:256
static struct net_device_operations hunt_operations
Definition sfc_hunt.c:1162
static int hunt_mcdi_init(struct hunt_nic *hunt)
Definition sfc_hunt.c:98
static int hunt_driver_attach(struct hunt_nic *hunt, int attach)
Definition sfc_hunt.c:456
static int hunt_mac_addr(struct hunt_nic *hunt, uint8_t *ll_addr)
Definition sfc_hunt.c:405
static int hunt_workaround_35388(struct hunt_nic *hunt)
Definition sfc_hunt.c:365
static void hunt_clear_udp_tunnel_ports(struct hunt_nic *hunt)
Definition sfc_hunt.c:508
static int hunt_get_phy_cfg(struct hunt_nic *hunt)
Definition sfc_hunt.c:431
static int hunt_get_port_assignment(struct hunt_nic *hunt)
Definition sfc_hunt.c:384
struct hunt_nic * primary_nics
Definition sfc_hunt.c:52
static int hunt_nic_is_primary(struct hunt_nic *hunt)
Definition sfc_hunt.c:83
const struct efx_nic_type * type
Definition efx_common.h:150
unsigned int rx_prefix_size
Definition efx_common.h:168
bool workaround_35388
Definition efx_common.h:175
struct hunt_nic * next_primary
Definition sfc_hunt.c:79
struct hunt_nic * primary
Definition sfc_hunt.c:78
struct device * dev
Underlying hardware device.
Definition netdevice.h:365
A PCI device.
Definition pci.h:211
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition pci.h:238
struct device dev
Generic device.
Definition pci.h:213

References _efx_writel(), alloc_etherdev(), pci_device::busdevfn, cpu_to_le32, DBG2, net_device::dev, pci_device::dev, hunt_nic::efx, EFX_HUNTINGTON, efx_probe(), efx_remove(), EIO, ENOMEM, ER_DZ_MC_DB_HWRD, ES_DZ_RX_PREFIX_SIZE, hunt_nic::flags, hunt_clear_udp_tunnel_ports(), hunt_driver_attach(), hunt_get_phy_cfg(), hunt_get_port_assignment(), hunt_mac_addr(), hunt_mcdi_fini(), hunt_mcdi_init(), hunt_nic_is_primary(), hunt_nic_type, hunt_operations, hunt_reset(), hunt_workaround_35388(), MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT, memset(), efx_nic::netdev, netdev, netdev_init(), NETDEV_IRQ_UNSUPPORTED, netdev_put(), hunt_nic::next_primary, PCI_ARGS, PCI_FIRST_FUNC, PCI_FMT, pci_set_drvdata(), hunt_nic::primary, primary_nics, rc, register_netdev(), efx_nic::rx_prefix_size, efx_nic::type, and efx_nic::workaround_35388.

◆ hunt_remove()

void hunt_remove ( struct pci_device * pci)
static

Definition at line 1291 of file sfc_hunt.c.

1292{
1293 struct net_device *netdev = pci_get_drvdata(pci);
1294 struct hunt_nic *hunt = netdev->priv;
1295
1296 if (!(hunt->flags &
1298 /* The netdevice might still be open, so unregister it now
1299 * before ripping stuff out from underneath.
1300 */
1302 }
1303
1304 (void)hunt_driver_attach(hunt, 0);
1305 hunt_mcdi_fini(hunt);
1306
1307 /* Destroy data path */
1309
1312}
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition pci.h:376

References efx_remove(), hunt_nic::flags, hunt_driver_attach(), hunt_mcdi_fini(), MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT, netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), and unregister_netdev().

Variable Documentation

◆ primary_nics

struct hunt_nic* primary_nics = NULL

Definition at line 52 of file sfc_hunt.c.

Referenced by hunt_probe().

◆ hunt_operations

struct net_device_operations hunt_operations
static
Initial value:
= {
.open = hunt_open,
.close = hunt_close,
.transmit = efx_hunt_transmit,
.poll = hunt_poll,
.irq = efx_hunt_irq,
}
int efx_hunt_transmit(struct net_device *netdev, struct io_buffer *iob)
Definition efx_hunt.c:102
void efx_hunt_irq(struct net_device *netdev, int enable)
Definition efx_hunt.c:445
static void hunt_close(struct net_device *netdev)
Definition sfc_hunt.c:1135
static int hunt_open(struct net_device *netdev)
Definition sfc_hunt.c:1073
static void hunt_poll(struct net_device *netdev)
Definition sfc_hunt.c:1045

Definition at line 1162 of file sfc_hunt.c.

1162 {
1163 .open = hunt_open,
1164 .close = hunt_close,
1165 .transmit = efx_hunt_transmit,
1166 .poll = hunt_poll,
1167 .irq = efx_hunt_irq,
1168};

Referenced by hunt_probe().

◆ hunt_nic_type

const struct efx_nic_type hunt_nic_type
Initial value:
= {
.mcdi_rpc = _hunt_mcdi,
}

Definition at line 1314 of file sfc_hunt.c.

1314 {
1315 .mcdi_rpc = _hunt_mcdi,
1316};

Referenced by hunt_probe().

◆ hunt_nics

struct pci_device_id hunt_nics[]
static
Initial value:
= {
PCI_ROM(0x1924, 0x0903, "SFC9120", "Solarflare SFC9120 Adapter", 0),
PCI_ROM(0x1924, 0x0923, "SFC9140", "Solarflare SFC9140 Adapter", 0),
PCI_ROM(0x1924, 0x0a03, "SFC9220", "Solarflare SFN8xxx Adapter", 0),
PCI_ROM(0x1924, 0x0b03, "SFC9250", "Solarflare X25xx Adapter", 0),
}
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition pci.h:308

Definition at line 1318 of file sfc_hunt.c.

1318 {
1319 PCI_ROM(0x1924, 0x0903, "SFC9120", "Solarflare SFC9120 Adapter", 0),
1320 PCI_ROM(0x1924, 0x0923, "SFC9140", "Solarflare SFC9140 Adapter", 0),
1321 PCI_ROM(0x1924, 0x0a03, "SFC9220", "Solarflare SFN8xxx Adapter", 0),
1322 PCI_ROM(0x1924, 0x0b03, "SFC9250", "Solarflare X25xx Adapter", 0),
1323};

◆ __pci_driver

struct pci_driver hunt_driver __pci_driver
Initial value:
= {
.ids = hunt_nics,
.id_count = ARRAY_SIZE(hunt_nics),
.probe = hunt_probe,
.remove = hunt_remove,
}
#define ARRAY_SIZE(x)
Definition efx_common.h:43
static int hunt_probe(struct pci_device *pci)
Definition sfc_hunt.c:1171
static struct pci_device_id hunt_nics[]
Definition sfc_hunt.c:1318
static void hunt_remove(struct pci_device *pci)
Definition sfc_hunt.c:1291

Definition at line 1325 of file sfc_hunt.c.

1325 {
1326 .ids = hunt_nics,
1327 .id_count = ARRAY_SIZE(hunt_nics),
1328 .probe = hunt_probe,
1329 .remove = hunt_remove,
1330};