iPXE
Data Structures | Defines | Functions
efx_hunt.h File Reference
#include "efx_common.h"

Go to the source code of this file.

Data Structures

struct  efx_mcdi_req_s
 MCDI request structure. More...

Defines

#define EFX_EV_SIZE(_nevs)   ((_nevs) * sizeof(efx_qword_t))
#define EFX_EVQ_NBUFS(_nevs)   (EFX_EV_SIZE(_nevs) / EFX_BUF_ALIGN)
#define EFX_RXQ_SIZE(_ndescs)   ((_ndescs) * sizeof(efx_qword_t))
#define EFX_RXQ_NBUFS(_ndescs)   (EFX_RXQ_SIZE(_ndescs) / EFX_BUF_ALIGN)
#define EFX_TXQ_SIZE(_ndescs)   ((_ndescs) * sizeof(efx_qword_t))
#define EFX_TXQ_NBUFS(_ndescs)   (EFX_TXQ_SIZE(_ndescs) / EFX_BUF_ALIGN)

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
void efx_hunt_free_special_buffer (void *buf, int bytes)
int efx_hunt_transmit (struct net_device *netdev, struct io_buffer *iob)
void efx_hunt_poll (struct net_device *netdev)
void efx_hunt_irq (struct net_device *netdev, int enable)
int efx_hunt_ev_init (struct net_device *netdev, dma_addr_t *dma_addr)
int efx_hunt_rx_init (struct net_device *netdev, dma_addr_t *dma_addr)
int efx_hunt_tx_init (struct net_device *netdev, dma_addr_t *dma_addr)
int efx_hunt_open (struct net_device *netdev)
void efx_hunt_close (struct net_device *netdev)

Define Documentation

#define EFX_EV_SIZE (   _nevs)    ((_nevs) * sizeof(efx_qword_t))

Definition at line 33 of file efx_hunt.h.

#define EFX_EVQ_NBUFS (   _nevs)    (EFX_EV_SIZE(_nevs) / EFX_BUF_ALIGN)

Definition at line 34 of file efx_hunt.h.

Referenced by hunt_ev_init().

#define EFX_RXQ_SIZE (   _ndescs)    ((_ndescs) * sizeof(efx_qword_t))

Definition at line 36 of file efx_hunt.h.

#define EFX_RXQ_NBUFS (   _ndescs)    (EFX_RXQ_SIZE(_ndescs) / EFX_BUF_ALIGN)

Definition at line 37 of file efx_hunt.h.

Referenced by hunt_rx_init().

#define EFX_TXQ_SIZE (   _ndescs)    ((_ndescs) * sizeof(efx_qword_t))

Definition at line 39 of file efx_hunt.h.

#define EFX_TXQ_NBUFS (   _ndescs)    (EFX_TXQ_SIZE(_ndescs) / EFX_BUF_ALIGN)

Definition at line 40 of file efx_hunt.h.

Referenced by hunt_tx_init().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
void efx_hunt_free_special_buffer ( void *  buf,
int  bytes 
)

Definition at line 38 of file efx_hunt.c.

References free_dma().

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

int efx_hunt_transmit ( struct net_device netdev,
struct io_buffer iob 
)

Definition at line 100 of file efx_hunt.c.

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_priv(), NULL, efx_tx_queue::read_ptr, efx_tx_queue::ring, txd, efx_nic::txq, and efx_tx_queue::write_ptr.

{
        struct efx_nic *efx = netdev_priv(netdev);
        struct efx_tx_queue *txq = &efx->txq;
        int fill_level, space;
        efx_tx_desc_t *txd;
        int buf_id;

        fill_level = txq->write_ptr - txq->read_ptr;
        space = EFX_TXD_SIZE - fill_level - 1;
        if (space < 1)
                return -ENOBUFS;

        /* Save the iobuffer for later completion */
        buf_id = txq->write_ptr & EFX_TXD_MASK;
        assert(txq->buf[buf_id] == NULL);
        txq->buf[buf_id] = iob;

        DBGCIO(efx, "tx_buf[%d] for iob %p data %p len %zd\n",
               buf_id, iob, iob->data, iob_len(iob));

        /* Form the descriptor, and push it to hardware */
        txd = txq->ring + buf_id;
        efx_hunt_build_tx_desc(txd, iob);
        ++txq->write_ptr;
        efx_hunt_notify_tx_desc(efx);

        return 0;
}
void efx_hunt_poll ( struct net_device netdev)

Definition at line 404 of file efx_hunt.c.

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_priv(), efx_ev_queue::read_ptr, and efx_ev_queue::ring.

Referenced by hunt_poll().

{
        struct efx_nic *efx = netdev_priv(netdev);
        struct efx_ev_queue *evq = &efx->evq;
        efx_event_t *evt;
        int budget = 10;

        /* Read the event queue by directly looking for events
         * (we don't even bother to read the eventq write ptr)
         */
        evt = evq->ring + evq->read_ptr;
        while (efx_hunt_event_present(evt) && (budget > 0)) {
                DBGCP(efx, "Event at index 0x%x address %p is "
                      EFX_QWORD_FMT "\n", evq->read_ptr,
                      evt, EFX_QWORD_VAL(*evt));

                budget -= efx_hunt_handle_event(efx, evt);

                /* Clear the event */
                EFX_SET_QWORD(*evt);

                /* Move to the next event. We don't ack the event
                 * queue until the end
                 */
                evq->read_ptr = ((evq->read_ptr + 1) & EFX_EVQ_MASK);
                evt = evq->ring + evq->read_ptr;
        }

        /* Push more rx buffers if needed */
        efx_hunt_rxq_fill(efx);

        /* Clear any pending interrupts */
        efx_hunt_clear_interrupts(efx);

        /* Ack the event queue if interrupts are enabled */
        if (efx->int_en)
                efx_hunt_evq_read_ack(efx);
}
void efx_hunt_irq ( struct net_device netdev,
int  enable 
)

Definition at line 443 of file efx_hunt.c.

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

{
        struct efx_nic *efx = netdev_priv(netdev);

        efx->int_en = enable;

        /* If interrupts are enabled, prime the event queue.  Otherwise ack any
         * pending interrupts
         */
        if (enable)
                efx_hunt_evq_read_ack(efx);
        else if (efx->netdev->state & NETDEV_OPEN)
                efx_hunt_clear_interrupts(efx);
}
int efx_hunt_ev_init ( struct net_device netdev,
dma_addr_t dma_addr 
)

Definition at line 294 of file efx_hunt.c.

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_priv(), NULL, efx_ev_queue::read_ptr, and efx_ev_queue::ring.

Referenced by hunt_ev_init().

{
        struct efx_nic *efx = netdev_priv(netdev);
        struct efx_ev_queue *evq = &efx->evq;
        size_t bytes;

        /* Allocate the hardware event queue */
        bytes = sizeof(efx_event_t) * EFX_EVQ_SIZE;
        evq->ring = efx_hunt_alloc_special_buffer(bytes, &evq->entry);
        if (evq->ring == NULL)
                return -ENOMEM;

        memset(evq->ring, 0xff, bytes);
        evq->read_ptr = 0;
        *dma_addr = evq->entry.dma_addr;
        return 0;
}
int efx_hunt_rx_init ( struct net_device netdev,
dma_addr_t dma_addr 
)

Definition at line 270 of file efx_hunt.c.

References bytes, efx_special_buffer::dma_addr, efx_hunt_alloc_special_buffer(), EFX_RXD_SIZE, ENOMEM, efx_rx_queue::entry, 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().

{
        struct efx_nic *efx = netdev_priv(netdev);
        struct efx_rx_queue *rxq = &efx->rxq;
        size_t bytes;

        /* Allocate hardware receive queue */
        bytes = sizeof(efx_rx_desc_t) * EFX_RXD_SIZE;
        rxq->ring = efx_hunt_alloc_special_buffer(bytes, &rxq->entry);
        if (rxq->ring == NULL)
                return -ENOMEM;

        rxq->read_ptr = rxq->write_ptr = 0;
        *dma_addr = rxq->entry.dma_addr;
        return 0;
}
int efx_hunt_tx_init ( struct net_device netdev,
dma_addr_t dma_addr 
)

Definition at line 155 of file efx_hunt.c.

References bytes, efx_special_buffer::dma_addr, efx_hunt_alloc_special_buffer(), EFX_TXD_SIZE, ENOMEM, efx_tx_queue::entry, 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().

{
        struct efx_nic *efx = netdev_priv(netdev);
        struct efx_tx_queue *txq = &efx->txq;
        size_t bytes;

        /* Allocate hardware transmit queue */
        bytes = sizeof(efx_tx_desc_t) * EFX_TXD_SIZE;
        txq->ring = efx_hunt_alloc_special_buffer(bytes, &txq->entry);
        if (!txq->ring)
                return -ENOMEM;

        txq->read_ptr = txq->write_ptr = 0;
        *dma_addr = txq->entry.dma_addr;
        return 0;
}
int efx_hunt_open ( struct net_device netdev)

Definition at line 465 of file efx_hunt.c.

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, and netdev_priv().

Referenced by hunt_open().

{
        struct efx_nic *efx = netdev_priv(netdev);
        efx_dword_t cmd;

        /* Set interrupt moderation to 0*/
        EFX_POPULATE_DWORD_2(cmd,
                             ERF_DZ_TC_TIMER_MODE, 0,
                             ERF_DZ_TC_TIMER_VAL, 0);
        efx_writel_page(efx, &cmd, 0, ER_DZ_EVQ_TMR);

        /* Ack the eventq */
        if (efx->int_en)
                efx_hunt_evq_read_ack(efx);

        /* Push receive buffers */
        efx_hunt_rxq_fill(efx);

        return 0;
}
void efx_hunt_close ( struct net_device netdev)

Definition at line 486 of file efx_hunt.c.

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

Referenced by hunt_close(), and hunt_open().

{
        struct efx_nic *efx = netdev_priv(netdev);
        struct efx_rx_queue *rxq = &efx->rxq;
        struct efx_tx_queue *txq = &efx->txq;
        int i;

        /* Complete outstanding descriptors */
        for (i = 0; i < EFX_NUM_RX_DESC; i++) {
                if (rxq->buf[i]) {
                        free_iob(rxq->buf[i]);
                        rxq->buf[i] = NULL;
                }
        }

        for (i = 0; i < EFX_TXD_SIZE; i++) {
                if (txq->buf[i]) {
                        netdev_tx_complete(efx->netdev, txq->buf[i]);
                        txq->buf[i] = NULL;
                }
        }

        /* Clear interrupts */
        efx_hunt_clear_interrupts(efx);
}