iPXE
Functions
efx_hunt.c File Reference
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/io.h>
#include <ipxe/pci.h>
#include <ipxe/malloc.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include "efx_hunt.h"
#include "efx_bitfield.h"
#include "ef10_regs.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
void efx_hunt_free_special_buffer (void *buf, int bytes)
 
static void * efx_hunt_alloc_special_buffer (int bytes, struct efx_special_buffer *entry)
 
static void efx_hunt_build_tx_desc (efx_tx_desc_t *txd, struct io_buffer *iob)
 
static void efx_hunt_notify_tx_desc (struct efx_nic *efx)
 
int efx_hunt_transmit (struct net_device *netdev, struct io_buffer *iob)
 
static void efx_hunt_transmit_done (struct efx_nic *efx, int id)
 
int efx_hunt_tx_init (struct net_device *netdev, dma_addr_t *dma_addr)
 
static void efx_hunt_build_rx_desc (efx_rx_desc_t *rxd, struct io_buffer *iob)
 
static void efx_hunt_notify_rx_desc (struct efx_nic *efx)
 
static void efx_hunt_rxq_fill (struct efx_nic *efx)
 
static void efx_hunt_receive (struct efx_nic *efx, unsigned int id, int len, int drop)
 
int efx_hunt_rx_init (struct net_device *netdev, dma_addr_t *dma_addr)
 
int efx_hunt_ev_init (struct net_device *netdev, dma_addr_t *dma_addr)
 
static void efx_hunt_clear_interrupts (struct efx_nic *efx)
 
static int efx_hunt_event_present (efx_event_t *event)
 See if an event is present. More...
 
static void efx_hunt_evq_read_ack (struct efx_nic *efx)
 
static unsigned int efx_hunt_handle_event (struct efx_nic *efx, efx_event_t *evt)
 
void efx_hunt_poll (struct net_device *netdev)
 
void efx_hunt_irq (struct net_device *netdev, int enable)
 
int efx_hunt_open (struct net_device *netdev)
 
void efx_hunt_close (struct net_device *netdev)
 

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ efx_hunt_free_special_buffer()

void efx_hunt_free_special_buffer ( void *  buf,
int  bytes 
)

Definition at line 40 of file efx_hunt.c.

41 {
42  free_phys(buf, bytes);
43 }
void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition: malloc.c:722
uint8_t bytes[64]
Definition: ib_mad.h:16

References bytes, and free_phys().

Referenced by hunt_ev_fini(), hunt_rx_fini(), and hunt_tx_fini().

◆ efx_hunt_alloc_special_buffer()

static void* efx_hunt_alloc_special_buffer ( int  bytes,
struct efx_special_buffer entry 
)
static

Definition at line 45 of file efx_hunt.c.

47 {
48  void *buffer;
49  dma_addr_t dma_addr;
50 
51  /* Allocate the buffer, aligned on a buffer address boundary. This
52  * buffer will be passed into an MC_CMD_INIT_*Q command to setup the
53  * appropriate type of queue via MCDI.
54  */
56  if (!buffer)
57  return NULL;
58 
59  entry->dma_addr = dma_addr = virt_to_bus(buffer);
60  assert((dma_addr & (EFX_BUF_ALIGN - 1)) == 0);
61 
62  /* Buffer table entries aren't allocated, so set id to zero */
63  entry->id = 0;
64  DBGP("Allocated 0x%x bytes at %p\n", bytes, buffer);
65 
66  return buffer;
67 }
dma_addr_t dma_addr
Definition: efx_common.h:84
unsigned long dma_addr_t
Definition: bnx2.h:20
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
#define DBGP(...)
Definition: compiler.h:532
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define EFX_BUF_ALIGN
Definition: efx_common.h:55
uint8_t bytes[64]
Definition: ib_mad.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition: malloc.c:706

References assert(), buffer, bytes, DBGP, efx_special_buffer::dma_addr, EFX_BUF_ALIGN, efx_special_buffer::id, malloc_phys(), NULL, and virt_to_bus().

Referenced by efx_hunt_ev_init(), efx_hunt_rx_init(), and efx_hunt_tx_init().

◆ efx_hunt_build_tx_desc()

static void efx_hunt_build_tx_desc ( efx_tx_desc_t txd,
struct io_buffer iob 
)
static

Definition at line 77 of file efx_hunt.c.

78 {
79  dma_addr_t dma_addr;
80 
81  dma_addr = virt_to_bus(iob->data);
82 
84  ESF_DZ_TX_KER_TYPE, 0,
85  ESF_DZ_TX_KER_CONT, 0,
86  ESF_DZ_TX_KER_BYTE_CNT, iob_len(iob),
87  ESF_DZ_TX_KER_BUF_ADDR, dma_addr);
88 }
unsigned long dma_addr_t
Definition: bnx2.h:20
#define EFX_POPULATE_QWORD_4(qword,...)
Definition: efx_bitfield.h:390
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
#define txd
Definition: davicom.c:144
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
void * data
Start of data.
Definition: iobuf.h:52

References io_buffer::data, EFX_POPULATE_QWORD_4, iob_len(), txd, and virt_to_bus().

Referenced by efx_hunt_transmit().

◆ efx_hunt_notify_tx_desc()

static void efx_hunt_notify_tx_desc ( struct efx_nic efx)
static

Definition at line 91 of file efx_hunt.c.

92 {
93  struct efx_tx_queue *txq = &efx->txq;
94  int ptr = txq->write_ptr & EFX_TXD_MASK;
96 
97  EFX_POPULATE_DWORD_1(reg, ERF_DZ_TX_DESC_WPTR_DWORD, ptr);
99 }
#define EFX_TXD_MASK
Definition: efx_common.h:59
static unsigned int unsigned int reg
Definition: myson.h:162
A transmit queue.
Definition: efx_common.h:89
#define efx_writel_page(efx, value, index, reg)
Definition: efx_common.h:219
A doubleword (4 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:87
unsigned int write_ptr
Definition: efx_common.h:100
#define EFX_POPULATE_DWORD_1(dword,...)
Definition: efx_bitfield.h:423
#define ER_DZ_TX_DESC_UPD_DWORD
Definition: ef10_regs.h:325
struct efx_tx_queue txq
Definition: efx_common.h:165

References EFX_POPULATE_DWORD_1, EFX_TXD_MASK, efx_writel_page, ER_DZ_TX_DESC_UPD_DWORD, reg, efx_nic::txq, and efx_tx_queue::write_ptr.

Referenced by efx_hunt_transmit().

◆ efx_hunt_transmit()

int efx_hunt_transmit ( struct net_device netdev,
struct io_buffer iob 
)

Definition at line 102 of file efx_hunt.c.

103 {
104  struct efx_nic *efx = netdev->priv;
105  struct efx_tx_queue *txq = &efx->txq;
106  int fill_level, space;
108  int buf_id;
109 
110  fill_level = txq->write_ptr - txq->read_ptr;
111  space = EFX_TXD_SIZE - fill_level - 1;
112  if (space < 1)
113  return -ENOBUFS;
114 
115  /* Save the iobuffer for later completion */
116  buf_id = txq->write_ptr & EFX_TXD_MASK;
117  assert(txq->buf[buf_id] == NULL);
118  txq->buf[buf_id] = iob;
119 
120  DBGCIO(efx, "tx_buf[%d] for iob %p data %p len %zd\n",
121  buf_id, iob, iob->data, iob_len(iob));
122 
123  /* Form the descriptor, and push it to hardware */
124  txd = txq->ring + buf_id;
126  ++txq->write_ptr;
128 
129  return 0;
130 }
#define EFX_TXD_MASK
Definition: efx_common.h:59
Hardware access.
Definition: efx_common.h:147
A transmit queue.
Definition: efx_common.h:89
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
efx_tx_desc_t * ring
Definition: efx_common.h:91
void * priv
Driver private data.
Definition: netdevice.h:431
static void efx_hunt_build_tx_desc(efx_tx_desc_t *txd, struct io_buffer *iob)
Definition: efx_hunt.c:77
static struct net_device * netdev
Definition: gdbudp.c:52
unsigned int read_ptr
Definition: efx_common.h:103
unsigned int write_ptr
Definition: efx_common.h:100
#define txd
Definition: davicom.c:144
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
#define DBGCIO(...)
Definition: compiler.h:556
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
struct efx_tx_queue txq
Definition: efx_common.h:165
void * data
Start of data.
Definition: iobuf.h:52
struct io_buffer * buf[EFX_TXD_SIZE]
Definition: efx_common.h:94
#define EFX_TXD_SIZE
Definition: efx_common.h:58
static void efx_hunt_notify_tx_desc(struct efx_nic *efx)
Definition: efx_hunt.c:91
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
A quadword (8 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:92

References assert(), efx_tx_queue::buf, io_buffer::data, DBGCIO, efx_hunt_build_tx_desc(), efx_hunt_notify_tx_desc(), EFX_TXD_MASK, EFX_TXD_SIZE, ENOBUFS, iob_len(), netdev, NULL, net_device::priv, efx_tx_queue::read_ptr, efx_tx_queue::ring, txd, efx_nic::txq, and efx_tx_queue::write_ptr.

◆ efx_hunt_transmit_done()

static void efx_hunt_transmit_done ( struct efx_nic efx,
int  id 
)
static

Definition at line 133 of file efx_hunt.c.

134 {
135  struct efx_tx_queue *txq = &efx->txq;
136  unsigned int read_ptr, stop;
137 
138  /* Complete all buffers from read_ptr up to and including id */
139  read_ptr = txq->read_ptr & EFX_TXD_MASK;
140  stop = (id + 1) & EFX_TXD_MASK;
141 
142  while (read_ptr != stop) {
143  struct io_buffer *iob = txq->buf[read_ptr];
144 
145  assert(iob);
146  /* Complete the tx buffer */
147  if (iob)
148  netdev_tx_complete(efx->netdev, iob);
149  DBGCIO(efx, "tx_buf[%d] for iob %p done\n", read_ptr, iob);
150  txq->buf[read_ptr] = NULL;
151 
152  ++txq->read_ptr;
153  read_ptr = txq->read_ptr & EFX_TXD_MASK;
154  }
155 }
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition: netdevice.h:766
#define EFX_TXD_MASK
Definition: efx_common.h:59
A transmit queue.
Definition: efx_common.h:89
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int read_ptr
Definition: efx_common.h:103
#define DBGCIO(...)
Definition: compiler.h:556
struct efx_tx_queue txq
Definition: efx_common.h:165
struct io_buffer * buf[EFX_TXD_SIZE]
Definition: efx_common.h:94
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct net_device * netdev
Definition: efx_common.h:148
A persistent I/O buffer.
Definition: iobuf.h:37

References assert(), efx_tx_queue::buf, DBGCIO, EFX_TXD_MASK, efx_nic::netdev, netdev_tx_complete(), NULL, efx_tx_queue::read_ptr, and efx_nic::txq.

Referenced by efx_hunt_handle_event().

◆ efx_hunt_tx_init()

int efx_hunt_tx_init ( struct net_device netdev,
dma_addr_t dma_addr 
)

Definition at line 157 of file efx_hunt.c.

158 {
159  struct efx_nic *efx = netdev->priv;
160  struct efx_tx_queue *txq = &efx->txq;
161  size_t bytes;
162 
163  /* Allocate hardware transmit queue */
164  bytes = sizeof(efx_tx_desc_t) * EFX_TXD_SIZE;
166  if (!txq->ring)
167  return -ENOMEM;
168 
169  txq->read_ptr = txq->write_ptr = 0;
170  *dma_addr = txq->entry.dma_addr;
171  return 0;
172 }
dma_addr_t dma_addr
Definition: efx_common.h:84
Hardware access.
Definition: efx_common.h:147
A transmit queue.
Definition: efx_common.h:89
#define ENOMEM
Not enough space.
Definition: errno.h:534
efx_tx_desc_t * ring
Definition: efx_common.h:91
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
efx_qword_t efx_tx_desc_t
Definition: efx_common.h:52
unsigned int read_ptr
Definition: efx_common.h:103
unsigned int write_ptr
Definition: efx_common.h:100
struct efx_tx_queue txq
Definition: efx_common.h:165
#define EFX_TXD_SIZE
Definition: efx_common.h:58
struct efx_special_buffer entry
Definition: efx_common.h:97
static void * efx_hunt_alloc_special_buffer(int bytes, struct efx_special_buffer *entry)
Definition: efx_hunt.c:45
uint8_t bytes[64]
Definition: ib_mad.h:16

References bytes, efx_special_buffer::dma_addr, efx_hunt_alloc_special_buffer(), EFX_TXD_SIZE, ENOMEM, efx_tx_queue::entry, netdev, net_device::priv, efx_tx_queue::read_ptr, efx_tx_queue::ring, efx_nic::txq, and efx_tx_queue::write_ptr.

Referenced by hunt_tx_init().

◆ efx_hunt_build_rx_desc()

static void efx_hunt_build_rx_desc ( efx_rx_desc_t rxd,
struct io_buffer iob 
)
static

Definition at line 182 of file efx_hunt.c.

183 {
184  dma_addr_t dma_addr = virt_to_bus(iob->data);
185 
187  ESF_DZ_RX_KER_BYTE_CNT, EFX_RX_BUF_SIZE,
188  ESF_DZ_RX_KER_BUF_ADDR, dma_addr);
189 }
unsigned long dma_addr_t
Definition: bnx2.h:20
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
#define EFX_POPULATE_QWORD_2(qword,...)
Definition: efx_bitfield.h:394
#define EFX_RX_BUF_SIZE
Definition: efx_common.h:74
void * data
Start of data.
Definition: iobuf.h:52
#define rxd
Definition: davicom.c:146

References io_buffer::data, EFX_POPULATE_QWORD_2, EFX_RX_BUF_SIZE, rxd, and virt_to_bus().

Referenced by efx_hunt_rxq_fill().

◆ efx_hunt_notify_rx_desc()

static void efx_hunt_notify_rx_desc ( struct efx_nic efx)
static

Definition at line 192 of file efx_hunt.c.

193 {
194  struct efx_rx_queue *rxq = &efx->rxq;
195  int ptr = rxq->write_ptr & EFX_RXD_MASK;
197 
198  EFX_POPULATE_DWORD_1(reg, ERF_DZ_RX_DESC_WPTR, ptr);
200 }
static unsigned int unsigned int reg
Definition: myson.h:162
A receive queue.
Definition: efx_common.h:107
#define efx_writel_page(efx, value, index, reg)
Definition: efx_common.h:219
A doubleword (4 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:87
#define ER_DZ_RX_DESC_UPD
Definition: ef10_regs.h:98
#define EFX_RXD_MASK
Definition: efx_common.h:57
#define EFX_POPULATE_DWORD_1(dword,...)
Definition: efx_bitfield.h:423
struct efx_rx_queue rxq
Definition: efx_common.h:164
unsigned int write_ptr
Definition: efx_common.h:118

References EFX_POPULATE_DWORD_1, EFX_RXD_MASK, efx_writel_page, ER_DZ_RX_DESC_UPD, reg, efx_nic::rxq, and efx_rx_queue::write_ptr.

Referenced by efx_hunt_rxq_fill().

◆ efx_hunt_rxq_fill()

static void efx_hunt_rxq_fill ( struct efx_nic efx)
static

Definition at line 203 of file efx_hunt.c.

204 {
205  struct efx_rx_queue *rxq = &efx->rxq;
206  int fill_level = rxq->write_ptr - rxq->read_ptr;
207  int space = EFX_NUM_RX_DESC - fill_level - 1;
208  int pushed = 0;
209 
210  while (space) {
211  int buf_id = rxq->write_ptr & (EFX_NUM_RX_DESC - 1);
212  int desc_id = rxq->write_ptr & EFX_RXD_MASK;
213  struct io_buffer *iob;
215 
216  assert(rxq->buf[buf_id] == NULL);
217  iob = alloc_iob(EFX_RX_BUF_SIZE);
218  if (!iob)
219  break;
220 
221  DBGCP(efx, "pushing rx_buf[%d] iob %p data %p\n",
222  buf_id, iob, iob->data);
223 
224  rxq->buf[buf_id] = iob;
225  rxd = rxq->ring + desc_id;
227  ++rxq->write_ptr;
228  ++pushed;
229  --space;
230  }
231 
232  /* Push the ptr to hardware */
233  if (pushed > 0) {
235 
236  DBGCP(efx, "pushed %d rx buffers to fill level %d\n",
237  pushed, rxq->write_ptr - rxq->read_ptr);
238  }
239 }
A receive queue.
Definition: efx_common.h:107
unsigned int read_ptr
Definition: efx_common.h:121
static void efx_hunt_build_rx_desc(efx_rx_desc_t *rxd, struct io_buffer *iob)
Definition: efx_hunt.c:182
efx_rx_desc_t * ring
Definition: efx_common.h:109
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:130
static void efx_hunt_notify_rx_desc(struct efx_nic *efx)
Definition: efx_hunt.c:192
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define EFX_NUM_RX_DESC
Definition: efx_common.h:68
#define EFX_RXD_MASK
Definition: efx_common.h:57
#define EFX_RX_BUF_SIZE
Definition: efx_common.h:74
struct efx_rx_queue rxq
Definition: efx_common.h:164
void * data
Start of data.
Definition: iobuf.h:52
#define DBGCP(...)
Definition: compiler.h:539
struct io_buffer * buf[EFX_NUM_RX_DESC]
Definition: efx_common.h:112
unsigned int write_ptr
Definition: efx_common.h:118
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
A quadword (8 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:92
#define rxd
Definition: davicom.c:146
A persistent I/O buffer.
Definition: iobuf.h:37

References alloc_iob(), assert(), efx_rx_queue::buf, io_buffer::data, DBGCP, efx_hunt_build_rx_desc(), efx_hunt_notify_rx_desc(), EFX_NUM_RX_DESC, EFX_RX_BUF_SIZE, EFX_RXD_MASK, NULL, efx_rx_queue::read_ptr, efx_rx_queue::ring, rxd, efx_nic::rxq, and efx_rx_queue::write_ptr.

Referenced by efx_hunt_open(), and efx_hunt_poll().

◆ efx_hunt_receive()

static void efx_hunt_receive ( struct efx_nic efx,
unsigned int  id,
int  len,
int  drop 
)
static

Definition at line 242 of file efx_hunt.c.

243 {
244  struct efx_rx_queue *rxq = &efx->rxq;
245  unsigned int read_ptr = rxq->read_ptr & EFX_RXD_MASK;
246  unsigned int buf_ptr = rxq->read_ptr & EFX_NUM_RX_DESC_MASK;
247  struct io_buffer *iob;
248 
249  /* id is the lower 4 bits of the desc index + 1 in huntington*/
250  /* hence anding with 15 */
251  assert((id & 15) == ((read_ptr + (len != 0)) & 15));
252 
253  /* Pop this rx buffer out of the software ring */
254  iob = rxq->buf[buf_ptr];
255  rxq->buf[buf_ptr] = NULL;
256 
257  DBGCIO(efx, "popping rx_buf[%d] iob %p data %p with %d bytes %s %x\n",
258  read_ptr, iob, iob->data, len, drop ? "bad" : "ok", drop);
259 
260  /* Pass the packet up if required */
261  if (drop)
262  netdev_rx_err(efx->netdev, iob, EBADMSG);
263  else {
264  iob_put(iob, len);
265  iob_pull(iob, efx->rx_prefix_size);
266  netdev_rx(efx->netdev, iob);
267  }
268 
269  ++rxq->read_ptr;
270 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
#define iob_put(iobuf, len)
Definition: iobuf.h:124
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:586
A receive queue.
Definition: efx_common.h:107
unsigned int read_ptr
Definition: efx_common.h:121
#define EFX_NUM_RX_DESC_MASK
Definition: efx_common.h:69
#define EBADMSG
Bad message.
Definition: errno.h:333
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
#define EFX_RXD_MASK
Definition: efx_common.h:57
#define DBGCIO(...)
Definition: compiler.h:556
struct efx_rx_queue rxq
Definition: efx_common.h:164
unsigned int rx_prefix_size
Definition: efx_common.h:168
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:548
void * data
Start of data.
Definition: iobuf.h:52
struct io_buffer * buf[EFX_NUM_RX_DESC]
Definition: efx_common.h:112
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct net_device * netdev
Definition: efx_common.h:148
A persistent I/O buffer.
Definition: iobuf.h:37

References assert(), efx_rx_queue::buf, io_buffer::data, DBGCIO, EBADMSG, EFX_NUM_RX_DESC_MASK, EFX_RXD_MASK, iob_pull, iob_put, len, efx_nic::netdev, netdev_rx(), netdev_rx_err(), NULL, efx_rx_queue::read_ptr, efx_nic::rx_prefix_size, and efx_nic::rxq.

Referenced by efx_hunt_handle_event().

◆ efx_hunt_rx_init()

int efx_hunt_rx_init ( struct net_device netdev,
dma_addr_t dma_addr 
)

Definition at line 272 of file efx_hunt.c.

273 {
274  struct efx_nic *efx = netdev->priv;
275  struct efx_rx_queue *rxq = &efx->rxq;
276  size_t bytes;
277 
278  /* Allocate hardware receive queue */
279  bytes = sizeof(efx_rx_desc_t) * EFX_RXD_SIZE;
281  if (rxq->ring == NULL)
282  return -ENOMEM;
283 
284  rxq->read_ptr = rxq->write_ptr = 0;
285  *dma_addr = rxq->entry.dma_addr;
286  return 0;
287 }
struct efx_special_buffer entry
Definition: efx_common.h:115
dma_addr_t dma_addr
Definition: efx_common.h:84
Hardware access.
Definition: efx_common.h:147
A receive queue.
Definition: efx_common.h:107
unsigned int read_ptr
Definition: efx_common.h:121
efx_rx_desc_t * ring
Definition: efx_common.h:109
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
#define EFX_RXD_SIZE
Definition: efx_common.h:56
struct efx_rx_queue rxq
Definition: efx_common.h:164
efx_qword_t efx_rx_desc_t
Definition: efx_common.h:51
unsigned int write_ptr
Definition: efx_common.h:118
static void * efx_hunt_alloc_special_buffer(int bytes, struct efx_special_buffer *entry)
Definition: efx_hunt.c:45
uint8_t bytes[64]
Definition: ib_mad.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References bytes, efx_special_buffer::dma_addr, efx_hunt_alloc_special_buffer(), EFX_RXD_SIZE, ENOMEM, efx_rx_queue::entry, netdev, NULL, net_device::priv, efx_rx_queue::read_ptr, efx_rx_queue::ring, efx_nic::rxq, and efx_rx_queue::write_ptr.

Referenced by hunt_rx_init().

◆ efx_hunt_ev_init()

int efx_hunt_ev_init ( struct net_device netdev,
dma_addr_t dma_addr 
)

Definition at line 296 of file efx_hunt.c.

297 {
298  struct efx_nic *efx = netdev->priv;
299  struct efx_ev_queue *evq = &efx->evq;
300  size_t bytes;
301 
302  /* Allocate the hardware event queue */
303  bytes = sizeof(efx_event_t) * EFX_EVQ_SIZE;
305  if (evq->ring == NULL)
306  return -ENOMEM;
307 
308  memset(evq->ring, 0xff, bytes);
309  evq->read_ptr = 0;
310  *dma_addr = evq->entry.dma_addr;
311  return 0;
312 }
dma_addr_t dma_addr
Definition: efx_common.h:84
Hardware access.
Definition: efx_common.h:147
#define EFX_EVQ_SIZE
Definition: efx_common.h:60
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
struct efx_special_buffer entry
Definition: efx_common.h:135
efx_qword_t efx_event_t
Definition: efx_common.h:53
efx_event_t * ring
Definition: efx_common.h:132
struct efx_ev_queue evq
Definition: efx_common.h:166
An event queue.
Definition: efx_common.h:128
static void * efx_hunt_alloc_special_buffer(int bytes, struct efx_special_buffer *entry)
Definition: efx_hunt.c:45
unsigned int read_ptr
Definition: efx_common.h:138
uint8_t bytes[64]
Definition: ib_mad.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * memset(void *dest, int character, size_t len) __nonnull

References bytes, efx_special_buffer::dma_addr, EFX_EVQ_SIZE, efx_hunt_alloc_special_buffer(), ENOMEM, efx_ev_queue::entry, efx_nic::evq, memset(), netdev, NULL, net_device::priv, efx_ev_queue::read_ptr, and efx_ev_queue::ring.

Referenced by hunt_ev_init().

◆ efx_hunt_clear_interrupts()

static void efx_hunt_clear_interrupts ( struct efx_nic efx)
static

Definition at line 315 of file efx_hunt.c.

316 {
318  /* read the ISR */
320 }
#define ER_DZ_BIU_INT_ISR
Definition: ef10_regs.h:65
static unsigned int unsigned int reg
Definition: myson.h:162
A doubleword (4 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:87
void efx_readl(struct efx_nic *efx, efx_dword_t *value, unsigned int reg)
Definition: efx_common.c:57

References efx_readl(), ER_DZ_BIU_INT_ISR, and reg.

Referenced by efx_hunt_close(), efx_hunt_irq(), and efx_hunt_poll().

◆ efx_hunt_event_present()

static int efx_hunt_event_present ( efx_event_t event)
inlinestatic

See if an event is present.

Parameters
eventEFX event structure
Return values
TrueAn event is pending
FalseNo event is pending

We check both the high and low dword of the event for all ones. We wrote all ones when we cleared the event, and no valid event can have all ones in either its high or low dwords. This approach is robust against reordering.

Note that using a single 64-bit comparison is incorrect; even though the CPU read will be atomic, the DMA write may not be.

Definition at line 338 of file efx_hunt.c.

339 {
340  return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
341  EFX_DWORD_IS_ALL_ONES(event->dword[1])));
342 }
efx_dword_t dword[2]
Definition: efx_bitfield.h:95
#define EFX_DWORD_IS_ALL_ONES(dword)
Definition: efx_bitfield.h:230

References efx_qword::dword, and EFX_DWORD_IS_ALL_ONES.

Referenced by efx_hunt_poll().

◆ efx_hunt_evq_read_ack()

static void efx_hunt_evq_read_ack ( struct efx_nic efx)
static

Definition at line 345 of file efx_hunt.c.

346 {
347  struct efx_ev_queue *evq = &efx->evq;
349 
350  if (efx->workaround_35388) {
351  EFX_POPULATE_DWORD_2(reg, ERF_DD_EVQ_IND_RPTR_FLAGS,
353  ERF_DD_EVQ_IND_RPTR,
356  EFX_POPULATE_DWORD_2(reg, ERF_DD_EVQ_IND_RPTR_FLAGS,
358  ERF_DD_EVQ_IND_RPTR, evq->read_ptr &
359  ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
361  } else {
362  EFX_POPULATE_DWORD_1(reg, ERF_DZ_EVQ_RPTR, evq->read_ptr);
364  }
365 }
#define EFE_DD_EVQ_IND_RPTR_FLAGS_LOW
Definition: ef10_regs.h:339
#define efx_writel_table(efx, value, index, reg)
Definition: efx_common.h:216
static unsigned int unsigned int reg
Definition: myson.h:162
#define EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH
Definition: ef10_regs.h:338
bool workaround_35388
Definition: efx_common.h:175
#define ER_DD_EVQ_INDIRECT
Definition: ef10_regs.h:335
#define efx_writel_page(efx, value, index, reg)
Definition: efx_common.h:219
A doubleword (4 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:87
#define ER_DZ_EVQ_RPTR
Definition: ef10_regs.h:80
#define EFX_POPULATE_DWORD_1(dword,...)
Definition: efx_bitfield.h:423
#define EFX_POPULATE_DWORD_2(dword,...)
Definition: efx_bitfield.h:421
struct efx_ev_queue evq
Definition: efx_common.h:166
An event queue.
Definition: efx_common.h:128
unsigned int read_ptr
Definition: efx_common.h:138
#define ERF_DD_EVQ_IND_RPTR_WIDTH
Definition: ef10_regs.h:341

References EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH, EFE_DD_EVQ_IND_RPTR_FLAGS_LOW, EFX_POPULATE_DWORD_1, EFX_POPULATE_DWORD_2, efx_writel_page, efx_writel_table, ER_DD_EVQ_INDIRECT, ER_DZ_EVQ_RPTR, ERF_DD_EVQ_IND_RPTR_WIDTH, efx_nic::evq, efx_ev_queue::read_ptr, reg, and efx_nic::workaround_35388.

Referenced by efx_hunt_irq(), efx_hunt_open(), and efx_hunt_poll().

◆ efx_hunt_handle_event()

static unsigned int efx_hunt_handle_event ( struct efx_nic efx,
efx_event_t evt 
)
static

Definition at line 368 of file efx_hunt.c.

369 {
370  struct efx_rx_queue *rxq = &efx->rxq;
371  int ev_code, desc_ptr, len;
372  int next_ptr_lbits, packet_drop;
373  int rx_cont;
374 
375  /* Decode event */
376  ev_code = EFX_QWORD_FIELD(*evt, ESF_DZ_EV_CODE);
377 
378  switch (ev_code) {
380  desc_ptr = EFX_QWORD_FIELD(*evt, ESF_DZ_TX_DESCR_INDX);
381  efx_hunt_transmit_done(efx, desc_ptr);
382  break;
383 
385  len = EFX_QWORD_FIELD(*evt, ESF_DZ_RX_BYTES);
386  next_ptr_lbits = EFX_QWORD_FIELD(*evt, ESF_DZ_RX_DSC_PTR_LBITS);
387  rx_cont = EFX_QWORD_FIELD(*evt, ESF_DZ_RX_CONT);
388 
389  /* We don't expect to receive scattered packets, so drop the
390  * packet if RX_CONT is set on the current or previous event, or
391  * if len is zero.
392  */
393  packet_drop = (len == 0) | (rx_cont << 1) |
394  (rxq->rx_cont_prev << 2);
395  efx_hunt_receive(efx, next_ptr_lbits, len, packet_drop);
396  rxq->rx_cont_prev = rx_cont;
397  return 1;
398 
399  default:
400  DBGCP(efx, "Unknown event type %d\n", ev_code);
401  break;
402  }
403  return 0;
404 }
#define EFX_QWORD_FIELD
Definition: efx_bitfield.h:242
A receive queue.
Definition: efx_common.h:107
unsigned int rx_cont_prev
Definition: efx_common.h:124
#define ESE_DZ_EV_CODE_RX_EV
Definition: ef10_regs.h:138
static void efx_hunt_receive(struct efx_nic *efx, unsigned int id, int len, int drop)
Definition: efx_hunt.c:242
ring len
Length.
Definition: dwmac.h:231
static void efx_hunt_transmit_done(struct efx_nic *efx, int id)
Definition: efx_hunt.c:133
struct efx_rx_queue rxq
Definition: efx_common.h:164
#define ESE_DZ_EV_CODE_TX_EV
Definition: ef10_regs.h:137
#define DBGCP(...)
Definition: compiler.h:539

References DBGCP, efx_hunt_receive(), efx_hunt_transmit_done(), EFX_QWORD_FIELD, ESE_DZ_EV_CODE_RX_EV, ESE_DZ_EV_CODE_TX_EV, len, efx_rx_queue::rx_cont_prev, and efx_nic::rxq.

Referenced by efx_hunt_poll().

◆ efx_hunt_poll()

void efx_hunt_poll ( struct net_device netdev)

Definition at line 406 of file efx_hunt.c.

407 {
408  struct efx_nic *efx = netdev->priv;
409  struct efx_ev_queue *evq = &efx->evq;
410  efx_event_t *evt;
411  int budget = 10;
412 
413  /* Read the event queue by directly looking for events
414  * (we don't even bother to read the eventq write ptr)
415  */
416  evt = evq->ring + evq->read_ptr;
417  while (efx_hunt_event_present(evt) && (budget > 0)) {
418  DBGCP(efx, "Event at index 0x%x address %p is "
419  EFX_QWORD_FMT "\n", evq->read_ptr,
420  evt, EFX_QWORD_VAL(*evt));
421 
422  budget -= efx_hunt_handle_event(efx, evt);
423 
424  /* Clear the event */
425  EFX_SET_QWORD(*evt);
426 
427  /* Move to the next event. We don't ack the event
428  * queue until the end
429  */
430  evq->read_ptr = ((evq->read_ptr + 1) & EFX_EVQ_MASK);
431  evt = evq->ring + evq->read_ptr;
432  }
433 
434  /* Push more rx buffers if needed */
435  efx_hunt_rxq_fill(efx);
436 
437  /* Clear any pending interrupts */
439 
440  /* Ack the event queue if interrupts are enabled */
441  if (efx->int_en)
443 }
static int efx_hunt_event_present(efx_event_t *event)
See if an event is present.
Definition: efx_hunt.c:338
Hardware access.
Definition: efx_common.h:147
#define EFX_EVQ_MASK
Definition: efx_common.h:61
static void efx_hunt_rxq_fill(struct efx_nic *efx)
Definition: efx_hunt.c:203
int int_en
INT_REG_KER.
Definition: efx_common.h:171
void * priv
Driver private data.
Definition: netdevice.h:431
#define EFX_SET_QWORD(qword)
Definition: efx_bitfield.h:400
static void efx_hunt_clear_interrupts(struct efx_nic *efx)
Definition: efx_hunt.c:315
static struct net_device * netdev
Definition: gdbudp.c:52
#define EFX_QWORD_VAL(qword)
Definition: efx_bitfield.h:112
efx_event_t * ring
Definition: efx_common.h:132
struct efx_ev_queue evq
Definition: efx_common.h:166
#define EFX_QWORD_FMT
Definition: efx_bitfield.h:108
static unsigned int efx_hunt_handle_event(struct efx_nic *efx, efx_event_t *evt)
Definition: efx_hunt.c:368
#define DBGCP(...)
Definition: compiler.h:539
An event queue.
Definition: efx_common.h:128
unsigned int read_ptr
Definition: efx_common.h:138
static void efx_hunt_evq_read_ack(struct efx_nic *efx)
Definition: efx_hunt.c:345
A quadword (8 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:92

References DBGCP, EFX_EVQ_MASK, efx_hunt_clear_interrupts(), efx_hunt_event_present(), efx_hunt_evq_read_ack(), efx_hunt_handle_event(), efx_hunt_rxq_fill(), EFX_QWORD_FMT, EFX_QWORD_VAL, EFX_SET_QWORD, efx_nic::evq, efx_nic::int_en, netdev, net_device::priv, efx_ev_queue::read_ptr, and efx_ev_queue::ring.

Referenced by hunt_poll().

◆ efx_hunt_irq()

void efx_hunt_irq ( struct net_device netdev,
int  enable 
)

Definition at line 445 of file efx_hunt.c.

446 {
447  struct efx_nic *efx = netdev->priv;
448 
449  efx->int_en = enable;
450 
451  /* If interrupts are enabled, prime the event queue. Otherwise ack any
452  * pending interrupts
453  */
454  if (enable)
456  else if (efx->netdev->state & NETDEV_OPEN)
458 }
Hardware access.
Definition: efx_common.h:147
#define NETDEV_OPEN
Network device is open.
Definition: netdevice.h:438
unsigned int state
Current device state.
Definition: netdevice.h:395
int int_en
INT_REG_KER.
Definition: efx_common.h:171
void * priv
Driver private data.
Definition: netdevice.h:431
static void efx_hunt_clear_interrupts(struct efx_nic *efx)
Definition: efx_hunt.c:315
static struct net_device * netdev
Definition: gdbudp.c:52
static void efx_hunt_evq_read_ack(struct efx_nic *efx)
Definition: efx_hunt.c:345
struct net_device * netdev
Definition: efx_common.h:148

References efx_hunt_clear_interrupts(), efx_hunt_evq_read_ack(), efx_nic::int_en, netdev, efx_nic::netdev, NETDEV_OPEN, net_device::priv, and net_device::state.

◆ efx_hunt_open()

int efx_hunt_open ( struct net_device netdev)

Definition at line 467 of file efx_hunt.c.

468 {
469  struct efx_nic *efx = netdev->priv;
471 
472  /* Set interrupt moderation to 0*/
474  ERF_DZ_TC_TIMER_MODE, 0,
475  ERF_DZ_TC_TIMER_VAL, 0);
476  efx_writel_page(efx, &cmd, 0, ER_DZ_EVQ_TMR);
477 
478  /* Ack the eventq */
479  if (efx->int_en)
481 
482  /* Push receive buffers */
483  efx_hunt_rxq_fill(efx);
484 
485  return 0;
486 }
Hardware access.
Definition: efx_common.h:147
#define ER_DZ_EVQ_TMR
Definition: ef10_regs.h:89
static void efx_hunt_rxq_fill(struct efx_nic *efx)
Definition: efx_hunt.c:203
#define efx_writel_page(efx, value, index, reg)
Definition: efx_common.h:219
A doubleword (4 byte) datatype - little-endian in HW.
Definition: efx_bitfield.h:87
int int_en
INT_REG_KER.
Definition: efx_common.h:171
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
#define EFX_POPULATE_DWORD_2(dword,...)
Definition: efx_bitfield.h:421
static void efx_hunt_evq_read_ack(struct efx_nic *efx)
Definition: efx_hunt.c:345
struct golan_eqe_cmd cmd
Definition: CIB_PRM.h:29

References cmd, efx_hunt_evq_read_ack(), efx_hunt_rxq_fill(), EFX_POPULATE_DWORD_2, efx_writel_page, ER_DZ_EVQ_TMR, efx_nic::int_en, netdev, and net_device::priv.

Referenced by hunt_open().

◆ efx_hunt_close()

void efx_hunt_close ( struct net_device netdev)

Definition at line 488 of file efx_hunt.c.

489 {
490  struct efx_nic *efx = netdev->priv;
491  struct efx_rx_queue *rxq = &efx->rxq;
492  struct efx_tx_queue *txq = &efx->txq;
493  int i;
494 
495  /* Complete outstanding descriptors */
496  for (i = 0; i < EFX_NUM_RX_DESC; i++) {
497  if (rxq->buf[i]) {
498  free_iob(rxq->buf[i]);
499  rxq->buf[i] = NULL;
500  }
501  }
502 
503  for (i = 0; i < EFX_TXD_SIZE; i++) {
504  if (txq->buf[i]) {
505  netdev_tx_complete(efx->netdev, txq->buf[i]);
506  txq->buf[i] = NULL;
507  }
508  }
509 
510  /* Clear interrupts */
512 }
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition: netdevice.h:766
Hardware access.
Definition: efx_common.h:147
A transmit queue.
Definition: efx_common.h:89
A receive queue.
Definition: efx_common.h:107
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
void * priv
Driver private data.
Definition: netdevice.h:431
static void efx_hunt_clear_interrupts(struct efx_nic *efx)
Definition: efx_hunt.c:315
static struct net_device * netdev
Definition: gdbudp.c:52
#define EFX_NUM_RX_DESC
Definition: efx_common.h:68
struct efx_rx_queue rxq
Definition: efx_common.h:164
struct efx_tx_queue txq
Definition: efx_common.h:165
struct io_buffer * buf[EFX_TXD_SIZE]
Definition: efx_common.h:94
#define EFX_TXD_SIZE
Definition: efx_common.h:58
struct io_buffer * buf[EFX_NUM_RX_DESC]
Definition: efx_common.h:112
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct net_device * netdev
Definition: efx_common.h:148

References efx_tx_queue::buf, efx_rx_queue::buf, efx_hunt_clear_interrupts(), EFX_NUM_RX_DESC, EFX_TXD_SIZE, free_iob(), netdev, efx_nic::netdev, netdev_tx_complete(), NULL, net_device::priv, efx_nic::rxq, and efx_nic::txq.

Referenced by hunt_close(), and hunt_open().