reduce the differences between these three files.

The three drivers (em, lem and igb) are extremely similar, too bad
that the structures use different names and we cannot share the code.
This commit is contained in:
Luigi Rizzo 2012-02-15 18:59:26 +00:00
parent 601e0f587d
commit 4b0a800988
3 changed files with 88 additions and 72 deletions

View File

@ -27,7 +27,7 @@
* $FreeBSD$
* $Id: if_em_netmap.h 9802 2011-12-02 18:42:37Z luigi $
*
* netmap changes for if_em.
* netmap support for if_em.
*
* For structure and details on the individual functions please see
* ixgbe_netmap.h
@ -46,6 +46,7 @@ static int em_netmap_txsync(struct ifnet *, u_int, int);
static int em_netmap_rxsync(struct ifnet *, u_int, int);
static void em_netmap_lock_wrapper(struct ifnet *, int, u_int);
static void
em_netmap_attach(struct adapter *adapter)
{
@ -137,6 +138,7 @@ em_netmap_unblock_tasks(struct adapter *adapter)
}
}
/*
* register-unregister routine
*/
@ -170,7 +172,7 @@ em_netmap_reg(struct ifnet *ifp, int onoff)
}
} else {
fail:
/* restore if_transmit */
/* return to non-netmap mode */
ifp->if_transmit = na->if_transmit;
ifp->if_capenable &= ~IFCAP_NETMAP;
em_init_locked(adapter); /* also enable intr */
@ -179,6 +181,7 @@ em_netmap_reg(struct ifnet *ifp, int onoff)
return (error);
}
/*
* Reconcile hardware and user view of the transmit ring.
*/
@ -224,6 +227,7 @@ em_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
uint64_t paddr;
void *addr = PNMB(slot, &paddr);
int len = slot->len;
if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) {
if (do_lock)
EM_TX_UNLOCK(txr);
@ -262,9 +266,9 @@ em_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
if (n == 0 || kring->nr_hwavail < 1) {
int delta;
/* record completed transmissions using THD. */
/* record completed transmissions using TDH */
l = E1000_READ_REG(&adapter->hw, E1000_TDH(ring_nr));
if (l >= kring->nkr_num_slots) { /* XXX can happen */
if (l >= kring->nkr_num_slots) { /* XXX can it happen ? */
D("TDH wrap %d", l);
l -= kring->nkr_num_slots;
}
@ -285,6 +289,7 @@ em_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
return 0;
}
/*
* Reconcile kernel and user view of the receive ring.
*/
@ -304,6 +309,7 @@ em_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
if (do_lock)
EM_RX_LOCK(rxr);
/* XXX check sync modes */
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@ -317,7 +323,7 @@ em_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
*/
l = rxr->next_to_check;
j = l + kring->nkr_hwofs;
/* here nkr_hwofs can be negative so must check for j < 0 */
/* XXX here nkr_hwofs can be negative so must check for j < 0 */
if (j < 0)
j += lim + 1;
else if (j > lim)
@ -395,3 +401,4 @@ em_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
EM_RX_UNLOCK(rxr);
return 0;
}
/* end of file */

View File

@ -27,8 +27,7 @@
* $FreeBSD$
* $Id: if_igb_netmap.h 9802 2011-12-02 18:42:37Z luigi $
*
* netmap modifications for igb
* contribured by Ahmed Kooli
* netmap modifications for igb contributed by Ahmed Kooli
*/
#include <net/netmap.h>
@ -95,8 +94,7 @@ igb_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid)
/*
* support for netmap register/unregisted. We are already under core lock.
* only called on the first init or the last unregister.
* register-unregister routine
*/
static int
igb_netmap_reg(struct ifnet *ifp, int onoff)
@ -106,7 +104,7 @@ igb_netmap_reg(struct ifnet *ifp, int onoff)
int error = 0;
if (na == NULL)
return EINVAL;
return EINVAL; /* no netmap support here */
igb_disable_intr(adapter);
@ -116,7 +114,6 @@ igb_netmap_reg(struct ifnet *ifp, int onoff)
if (onoff) {
ifp->if_capenable |= IFCAP_NETMAP;
/* save if_transmit to restore it later */
na->if_transmit = ifp->if_transmit;
ifp->if_transmit = netmap_start;
@ -130,14 +127,14 @@ igb_netmap_reg(struct ifnet *ifp, int onoff)
/* restore if_transmit */
ifp->if_transmit = na->if_transmit;
ifp->if_capenable &= ~IFCAP_NETMAP;
igb_init_locked(adapter); /* also enables intr */
igb_init_locked(adapter); /* also enable intr */
}
return (error);
}
/*
* Reconcile kernel and user view of the transmit ring.
* Reconcile hardware and user view of the transmit ring.
*/
static int
igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
@ -161,30 +158,30 @@ igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
/* update avail to what the hardware knows */
ring->avail = kring->nr_hwavail;
/* check for new packets to send.
* j indexes the netmap ring, l indexes the nic ring, and
* j = kring->nr_hwcur, l = E1000_TDT (not tracked),
* j == (l + kring->nkr_hwofs) % ring_size
*/
j = kring->nr_hwcur;
if (j != k) { /* we have packets to send */
/* 82575 needs the queue index added */
u32 olinfo_status =
(adapter->hw.mac.type == e1000_82575) ? (txr->me << 4) : 0;
j = kring->nr_hwcur; /* netmap ring index */
if (j != k) { /* we have new packets to send */
u32 olinfo_status = 0;
l = j - kring->nkr_hwofs; /* NIC ring index */
l = j - kring->nkr_hwofs;
if (l < 0)
l += lim + 1;
/* 82575 needs the queue index added */
if (adapter->hw.mac.type == e1000_82575)
olinfo_status |= txr->me << 4;
while (j != k) {
struct netmap_slot *slot = &ring->slot[j];
struct igb_tx_buffer *txbuf = &txr->tx_buffers[l];
union e1000_adv_tx_desc *curr =
(union e1000_adv_tx_desc *)&txr->tx_base[l];
uint64_t paddr;
void *addr = PNMB(slot, &paddr);
struct igb_tx_buffer *txbuf = &txr->tx_buffers[l];
int flags = ((slot->flags & NS_REPORT) ||
j == 0 || j == report_frequency) ?
E1000_ADVTXD_DCMD_RS : 0;
uint64_t paddr;
void *addr = PNMB(slot, &paddr);
int len = slot->len;
if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) {
@ -194,7 +191,7 @@ igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
}
slot->flags &= ~NS_REPORT;
// XXX do we need to set the address ?
// XXX set the address unconditionally
curr->read.buffer_addr = htole64(paddr);
curr->read.olinfo_status =
htole32(olinfo_status |
@ -220,7 +217,6 @@ igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
/* decrease avail by number of sent packets */
kring->nr_hwavail -= n;
ring->avail = kring->nr_hwavail;
/* Set the watchdog XXX ? */
txr->queue_status = IGB_QUEUE_WORKING;
@ -231,23 +227,28 @@ igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
E1000_WRITE_REG(&adapter->hw, E1000_TDT(txr->me), l);
}
if (n == 0 || kring->nr_hwavail < 1) {
int delta;
/* record completed transmission using TDH */
/* record completed transmissions using TDH */
l = E1000_READ_REG(&adapter->hw, E1000_TDH(ring_nr));
if (l >= kring->nkr_num_slots) /* XXX can it happen ? */
if (l >= kring->nkr_num_slots) { /* XXX can it happen ? */
D("TDH wrap %d", l);
l -= kring->nkr_num_slots;
}
delta = l - txr->next_to_clean;
if (delta) {
/* new tx were completed */
/* some completed, increment hwavail. */
if (delta < 0)
delta += kring->nkr_num_slots;
txr->next_to_clean = l;
kring->nr_hwavail += delta;
ring->avail = kring->nr_hwavail;
}
}
/* update avail to what the hardware knows */
ring->avail = kring->nr_hwavail;
if (do_lock)
IGB_TX_UNLOCK(txr);
return 0;
@ -274,10 +275,17 @@ igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
if (do_lock)
IGB_RX_LOCK(rxr);
/* Sync the ring. */
/* XXX check sync modes */
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/* import newly received packets into the netmap ring.
* j is an index in the netmap ring, l in the NIC ring, and
* j = (kring->nr_hwcur + kring->nr_hwavail) % ring_size
* l = rxr->next_to_check;
* and
* j == (l + kring->nkr_hwofs) % ring_size
*/
l = rxr->next_to_check;
j = l + kring->nkr_hwofs;
if (j > lim)
@ -289,7 +297,6 @@ igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
if ((staterr & E1000_RXD_STAT_DD) == 0)
break;
ring->slot[j].len = le16toh(curr->wb.upper.length);
bus_dmamap_sync(rxr->ptag,
rxr->rx_buffers[l].pmap, BUS_DMASYNC_POSTREAD);
j = (j == lim) ? 0 : j + 1;
@ -300,18 +307,13 @@ igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
kring->nr_hwavail += n;
}
/* skip past packets that userspace has already processed,
* making them available for reception.
* advance nr_hwcur and issue a bus_dmamap_sync on the
* buffers so it is safe to write to them.
* Also increase nr_hwavail
*/
/* skip past packets that userspace has already processed */
j = kring->nr_hwcur;
l = kring->nr_hwcur - kring->nkr_hwofs;
if (l < 0)
l += lim + 1;
if (j != k) { /* userspace has read some packets. */
if (j != k) { /* userspace has read some packets. */
n = 0;
l = j - kring->nkr_hwofs;
if (l < 0)
l += lim + 1;
while (j != k) {
struct netmap_slot *slot = ring->slot + j;
union e1000_adv_rx_desc *curr = &rxr->rx_base[l];
@ -340,10 +342,11 @@ igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
n++;
}
kring->nr_hwavail -= n;
kring->nr_hwcur = ring->cur;
kring->nr_hwcur = k;
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* IMPORTANT: we must leave one free slot in the ring,
/*
* IMPORTANT: we must leave one free slot in the ring,
* so move l back by one unit
*/
l = (l == 0) ? lim : l - 1;
@ -355,3 +358,4 @@ igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
IGB_RX_UNLOCK(rxr);
return 0;
}
/* end of file */

View File

@ -96,7 +96,7 @@ lem_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int ringid)
/*
* Register/unregister routine
* register-unregister routine
*/
static int
lem_netmap_reg(struct ifnet *ifp, int onoff)
@ -106,14 +106,13 @@ lem_netmap_reg(struct ifnet *ifp, int onoff)
int error = 0;
if (na == NULL)
return EINVAL;
return EINVAL; /* no netmap support here */
lem_disable_intr(adapter);
/* Tell the stack that the interface is no longer active */
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
/* lem_netmap_block_tasks(adapter); */
#ifndef EM_LEGACY_IRQ // XXX do we need this ?
taskqueue_block(adapter->tq);
taskqueue_drain(adapter->tq, &adapter->rxtx_task);
@ -122,9 +121,6 @@ lem_netmap_reg(struct ifnet *ifp, int onoff)
if (onoff) {
ifp->if_capenable |= IFCAP_NETMAP;
/* save if_transmit to restore it when exiting.
* XXX what about if_start and if_qflush ?
*/
na->if_transmit = ifp->if_transmit;
ifp->if_transmit = netmap_start;
@ -135,10 +131,10 @@ lem_netmap_reg(struct ifnet *ifp, int onoff)
}
} else {
fail:
/* restore non-netmap mode */
/* return to non-netmap mode */
ifp->if_transmit = na->if_transmit;
ifp->if_capenable &= ~IFCAP_NETMAP;
lem_init_locked(adapter); /* also enables intr */
lem_init_locked(adapter); /* also enable intr */
}
#ifndef EM_LEGACY_IRQ
@ -150,7 +146,7 @@ lem_netmap_reg(struct ifnet *ifp, int onoff)
/*
* Reconcile kernel and user view of the transmit ring.
* Reconcile hardware and user view of the transmit ring.
*/
static int
lem_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
@ -173,23 +169,25 @@ lem_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
/* update avail to what the hardware knows */
ring->avail = kring->nr_hwavail;
j = kring->nr_hwcur; /* points into the netmap ring */
if (j != k) { /* we have new packets to send */
l = j - kring->nkr_hwofs; /* points into the NIC ring */
/* check for new packets to send.
* j indexes the netmap ring, l indexes the nic ring, and
* j = kring->nr_hwcur, l = E1000_TDT (not tracked),
* j == (l + kring->nkr_hwofs) % ring_size
*/
j = kring->nr_hwcur;
if (j != k) { /* we have packets to send */
l = j - kring->nkr_hwofs;
if (l < 0)
l += lim + 1;
while (j != k) {
struct netmap_slot *slot = &ring->slot[j];
struct e1000_tx_desc *curr = &adapter->tx_desc_base[l];
struct em_buffer *txbuf = &adapter->tx_buffer_area[l];
uint64_t paddr;
void *addr = PNMB(slot, &paddr);
int flags = ((slot->flags & NS_REPORT) ||
j == 0 || j == report_frequency) ?
E1000_TXD_CMD_RS : 0;
uint64_t paddr;
void *addr = PNMB(slot, &paddr);
int len = slot->len;
if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) {
@ -220,7 +218,6 @@ lem_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
/* decrease avail by number of sent packets */
kring->nr_hwavail -= n;
ring->avail = kring->nr_hwavail;
bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@ -233,19 +230,21 @@ lem_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
/* record completed transmissions using TDH */
l = E1000_READ_REG(&adapter->hw, E1000_TDH(0));
if (l >= kring->nkr_num_slots) { /* can it happen ? */
if (l >= kring->nkr_num_slots) { /* XXX can it happen ? */
D("bad TDH %d", l);
l -= kring->nkr_num_slots;
}
delta = l - adapter->next_tx_to_clean;
if (delta) {
/* some completed, increment hwavail. */
if (delta < 0)
delta += kring->nkr_num_slots;
adapter->next_tx_to_clean = l;
kring->nr_hwavail += delta;
ring->avail = kring->nr_hwavail;
}
}
/* update avail to what the hardware knows */
ring->avail = kring->nr_hwavail;
if (do_lock)
EM_TX_UNLOCK(adapter);
@ -271,13 +270,20 @@ lem_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
if (do_lock)
EM_RX_LOCK(adapter);
/* XXX check sync modes */
bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/* import newly received packets into the netmap ring */
l = adapter->next_rx_desc_to_check; /* points into the NIC ring */
j = l + kring->nkr_hwofs; /* points into the netmap ring */
/* import newly received packets into the netmap ring
* j is an index in the netmap ring, l in the NIC ring, and
* j = (kring->nr_hwcur + kring->nr_hwavail) % ring_size
* l = rxr->next_to_check;
* and
* j == (l + kring->nkr_hwofs) % ring_size
*/
l = adapter->next_rx_desc_to_check;
j = l + kring->nkr_hwofs;
if (j > lim)
j -= lim + 1;
for (n = 0; ; n++) {
@ -322,6 +328,7 @@ lem_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
EM_RX_UNLOCK(adapter);
return netmap_ring_reinit(kring);
}
curr->status = 0;
if (slot->flags & NS_BUF_CHANGED) {
curr->buffer_addr = htole64(paddr);
@ -348,10 +355,8 @@ lem_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
l = (l == 0) ? lim : l - 1;
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), l);
}
/* tell userspace that there are new packets */
ring->avail = kring->nr_hwavail ;
if (do_lock)
EM_RX_UNLOCK(adapter);
return 0;