#include <stdint.h>
#include <stdlib.h>
#include <stdio.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.
|
| 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) |
|
◆ FILE_LICENCE()
FILE_LICENCE |
( |
GPL2_OR_LATER_OR_UBDL |
| ) |
|
◆ efx_hunt_free_special_buffer()
void efx_hunt_free_special_buffer |
( |
void * |
buf, |
|
|
int |
bytes |
|
) |
| |
◆ efx_hunt_alloc_special_buffer()
static void* efx_hunt_alloc_special_buffer |
( |
int |
bytes, |
|
|
struct efx_special_buffer * |
entry |
|
) |
| |
|
static |
Definition at line 44 of file efx_hunt.c.
static void *__malloc malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
union aes_table_entry entry[256]
Table entries, indexed by S(N)
#define NULL
NULL pointer (VOID *)
References assert(), buffer, bytes, DBGP, EFX_BUF_ALIGN, entry, 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()
Definition at line 76 of file efx_hunt.c.
83 ESF_DZ_TX_KER_TYPE, 0,
84 ESF_DZ_TX_KER_CONT, 0,
85 ESF_DZ_TX_KER_BYTE_CNT,
iob_len(iob),
86 ESF_DZ_TX_KER_BUF_ADDR, dma_addr);
#define EFX_POPULATE_QWORD_4(qword,...)
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
void * data
Start of data.
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 90 of file efx_hunt.c.
static unsigned int unsigned int reg
#define efx_writel_page(efx, value, index, reg)
A doubleword (4 byte) datatype - little-endian in HW.
#define EFX_POPULATE_DWORD_1(dword,...)
#define ER_DZ_TX_DESC_UPD_DWORD
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()
Definition at line 101 of file efx_hunt.c.
105 int fill_level, space;
117 txq->
buf[buf_id] = iob;
119 DBGCIO(efx,
"tx_buf[%d] for iob %p data %p len %zd\n",
static void * netdev_priv(struct net_device *netdev)
Get driver private area for this network device.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void efx_hunt_build_tx_desc(efx_tx_desc_t *txd, struct io_buffer *iob)
static struct net_device * netdev
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
#define ENOBUFS
No buffer space available.
void * data
Start of data.
struct io_buffer * buf[EFX_TXD_SIZE]
static void efx_hunt_notify_tx_desc(struct efx_nic *efx)
#define NULL
NULL pointer (VOID *)
A quadword (8 byte) datatype - little-endian in HW.
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, netdev_priv(), NULL, 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 132 of file efx_hunt.c.
148 DBGCIO(efx,
"tx_buf[%d] for iob %p done\n", read_ptr, iob);
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct io_buffer * buf[EFX_TXD_SIZE]
#define NULL
NULL pointer (VOID *)
struct net_device * netdev
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()
Definition at line 156 of file efx_hunt.c.
static void * netdev_priv(struct net_device *netdev)
Get driver private area for this network device.
#define ENOMEM
Not enough space.
static struct net_device * netdev
efx_qword_t efx_tx_desc_t
struct efx_special_buffer entry
static void * efx_hunt_alloc_special_buffer(int bytes, struct efx_special_buffer *entry)
References bytes, efx_special_buffer::dma_addr, efx_hunt_alloc_special_buffer(), EFX_TXD_SIZE, ENOMEM, efx_tx_queue::entry, netdev, netdev_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()
◆ efx_hunt_notify_rx_desc()
static void efx_hunt_notify_rx_desc |
( |
struct efx_nic * |
efx | ) |
|
|
static |
Definition at line 191 of file efx_hunt.c.
static unsigned int unsigned int reg
#define efx_writel_page(efx, value, index, reg)
A doubleword (4 byte) datatype - little-endian in HW.
#define ER_DZ_RX_DESC_UPD
#define EFX_POPULATE_DWORD_1(dword,...)
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 202 of file efx_hunt.c.
220 DBGCP(efx,
"pushing rx_buf[%d] iob %p data %p\n",
221 buf_id, iob, iob->
data);
223 rxq->
buf[buf_id] = iob;
235 DBGCP(efx,
"pushed %d rx buffers to fill level %d\n",
static void efx_hunt_build_rx_desc(efx_rx_desc_t *rxd, struct io_buffer *iob)
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
static void efx_hunt_notify_rx_desc(struct efx_nic *efx)
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * data
Start of data.
struct io_buffer * buf[EFX_NUM_RX_DESC]
#define NULL
NULL pointer (VOID *)
A quadword (8 byte) datatype - little-endian in HW.
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 241 of file efx_hunt.c.
250 assert((
id & 15) == ((read_ptr + (
len != 0)) & 15));
253 iob = rxq->
buf[buf_ptr];
256 DBGCIO(efx,
"popping rx_buf[%d] iob %p data %p with %d bytes %s %x\n",
257 read_ptr, iob, iob->
data,
len, drop ?
"bad" :
"ok", drop);
#define iob_pull(iobuf, len)
#define iob_put(iobuf, len)
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
#define EFX_NUM_RX_DESC_MASK
#define EBADMSG
Bad message.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int rx_prefix_size
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
void * data
Start of data.
struct io_buffer * buf[EFX_NUM_RX_DESC]
#define NULL
NULL pointer (VOID *)
struct net_device * netdev
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()
Definition at line 271 of file efx_hunt.c.
static void * netdev_priv(struct net_device *netdev)
Get driver private area for this network device.
struct efx_special_buffer entry
#define ENOMEM
Not enough space.
static struct net_device * netdev
efx_qword_t efx_rx_desc_t
static void * efx_hunt_alloc_special_buffer(int bytes, struct efx_special_buffer *entry)
#define NULL
NULL pointer (VOID *)
References bytes, efx_special_buffer::dma_addr, efx_hunt_alloc_special_buffer(), EFX_RXD_SIZE, ENOMEM, efx_rx_queue::entry, netdev, netdev_priv(), NULL, 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()
Definition at line 295 of file efx_hunt.c.
static void * netdev_priv(struct net_device *netdev)
Get driver private area for this network device.
#define ENOMEM
Not enough space.
static struct net_device * netdev
struct efx_special_buffer entry
static void * efx_hunt_alloc_special_buffer(int bytes, struct efx_special_buffer *entry)
#define NULL
NULL pointer (VOID *)
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, netdev_priv(), NULL, 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 |
◆ efx_hunt_event_present()
static int efx_hunt_event_present |
( |
efx_event_t * |
event | ) |
|
|
inlinestatic |
See if an event is present.
- Parameters
-
- Return values
-
True | An event is pending |
False | No 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 337 of file efx_hunt.c.
#define EFX_DWORD_IS_ALL_ONES(dword)
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 344 of file efx_hunt.c.
357 ERF_DD_EVQ_IND_RPTR, evq->
read_ptr &
#define EFE_DD_EVQ_IND_RPTR_FLAGS_LOW
#define efx_writel_table(efx, value, index, reg)
static unsigned int unsigned int reg
#define EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH
#define ER_DD_EVQ_INDIRECT
#define efx_writel_page(efx, value, index, reg)
A doubleword (4 byte) datatype - little-endian in HW.
#define EFX_POPULATE_DWORD_1(dword,...)
#define EFX_POPULATE_DWORD_2(dword,...)
#define ERF_DD_EVQ_IND_RPTR_WIDTH
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()
Definition at line 367 of file efx_hunt.c.
370 int ev_code, desc_ptr,
len;
371 int next_ptr_lbits, packet_drop;
392 packet_drop = (
len == 0) | (rx_cont << 1) |
399 DBGCP(efx,
"Unknown event type %d\n", ev_code);
unsigned int rx_cont_prev
#define ESE_DZ_EV_CODE_RX_EV
static void efx_hunt_receive(struct efx_nic *efx, unsigned int id, int len, int drop)
static void efx_hunt_transmit_done(struct efx_nic *efx, int id)
#define ESE_DZ_EV_CODE_TX_EV
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()
Definition at line 405 of file efx_hunt.c.
417 DBGCP(efx,
"Event at index 0x%x address %p is " static void * netdev_priv(struct net_device *netdev)
Get driver private area for this network device.
static int efx_hunt_event_present(efx_event_t *event)
See if an event is present.
static void efx_hunt_rxq_fill(struct efx_nic *efx)
#define EFX_SET_QWORD(qword)
static void efx_hunt_clear_interrupts(struct efx_nic *efx)
static struct net_device * netdev
#define EFX_QWORD_VAL(qword)
static unsigned int efx_hunt_handle_event(struct efx_nic *efx, efx_event_t *evt)
static void efx_hunt_evq_read_ack(struct efx_nic *efx)
A quadword (8 byte) datatype - little-endian in HW.
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, netdev_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 |
|
) |
| |
◆ efx_hunt_open()
Definition at line 466 of file efx_hunt.c.
473 ERF_DZ_TC_TIMER_MODE, 0,
474 ERF_DZ_TC_TIMER_VAL, 0);
static void * netdev_priv(struct net_device *netdev)
Get driver private area for this network device.
static void efx_hunt_rxq_fill(struct efx_nic *efx)
#define efx_writel_page(efx, value, index, reg)
A doubleword (4 byte) datatype - little-endian in HW.
static struct net_device * netdev
#define EFX_POPULATE_DWORD_2(dword,...)
static void efx_hunt_evq_read_ack(struct efx_nic *efx)
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 netdev_priv().
Referenced by hunt_open().
◆ efx_hunt_close()
Definition at line 487 of file efx_hunt.c.
static void * netdev_priv(struct net_device *netdev)
Get driver private area for this network device.
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
static void efx_hunt_clear_interrupts(struct efx_nic *efx)
static struct net_device * netdev
struct io_buffer * buf[EFX_TXD_SIZE]
struct io_buffer * buf[EFX_NUM_RX_DESC]
#define NULL
NULL pointer (VOID *)
struct net_device * netdev
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_priv(), netdev_tx_complete(), NULL, efx_nic::rxq, and efx_nic::txq.
Referenced by hunt_close(), and hunt_open().