diff options
author | Luigi Rizzo <luigi@FreeBSD.org> | 2012-01-12 17:28:00 +0000 |
---|---|---|
committer | Luigi Rizzo <luigi@FreeBSD.org> | 2012-01-12 17:28:00 +0000 |
commit | 467bd5c2cbcc07e3cbdd4f20a94fa4e1b48fc81d (patch) | |
tree | cde155e8fdf71898bbe16e67ae0399befa3a384f /sys/dev/e1000 | |
parent | a8c104fbb0feae30333ba287f5a98b6b5a8e813e (diff) | |
download | src-467bd5c2cbcc07e3cbdd4f20a94fa4e1b48fc81d.tar.gz src-467bd5c2cbcc07e3cbdd4f20a94fa4e1b48fc81d.zip |
fix the initialization of the rings when netmap is used,
to adapt it to the changes in 228387 .
Now the code is similar to the one used in other drivers.
Not applicable to stable/9 and stable/8
Notes
Notes:
svn path=/head/; revision=230023
Diffstat (limited to 'sys/dev/e1000')
-rw-r--r-- | sys/dev/e1000/if_em.c | 87 |
1 files changed, 25 insertions, 62 deletions
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 9f090bac46aa..0102517be5b4 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -4019,6 +4019,10 @@ em_setup_receive_ring(struct rx_ring *rxr) struct em_buffer *rxbuf; bus_dma_segment_t seg[1]; int rsize, nsegs, error; +#ifdef DEV_NETMAP + struct netmap_adapter *na = NA(adapter->ifp); + struct netmap_slot *slot; +#endif /* Clear the ring contents */ @@ -4026,6 +4030,9 @@ em_setup_receive_ring(struct rx_ring *rxr) rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc), EM_DBA_ALIGN); bzero((void *)rxr->rx_base, rsize); +#ifdef DEV_NETMAP + slot = netmap_reset(na, NR_RX, 0, 0); +#endif /* ** Free current RX buffer structs and their mbufs @@ -4043,6 +4050,22 @@ em_setup_receive_ring(struct rx_ring *rxr) /* Now replenish the mbufs */ for (int j = 0; j != adapter->num_rx_desc; ++j) { rxbuf = &rxr->rx_buffers[j]; +#ifdef DEV_NETMAP + if (slot) { + /* slot si is mapped to the j-th NIC-ring entry */ + int si = j + na->rx_rings[0].nkr_hwofs; + uint64_t paddr; + void *addr; + + if (si > na->num_rx_desc) + si -= na->num_rx_desc; + addr = PNMB(slot + si, &paddr); + netmap_load_map(rxr->rxtag, rxbuf->map, addr); + /* Update descriptor */ + rxr->rx_base[j].buffer_addr = htole64(paddr); + continue; + } +#endif /* DEV_NETMAP */ rxbuf->m_head = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, adapter->rx_mbuf_sz); if (rxbuf->m_head == NULL) { @@ -4073,63 +4096,6 @@ em_setup_receive_ring(struct rx_ring *rxr) bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); -#ifdef DEV_NETMAP - { - /* - * This driver is slightly different from the standard: - * it refills the rings in blocks of 8, so the while() - * above completes any leftover work. Also, after if_init() - * the ring starts at rxr->next_to_check instead of 0. - * - * Currently: we leave the mbufs allocated even in netmap - * mode, and simply make the NIC ring point to the - * correct buffer (netmap_buf or mbuf) depending on - * the mode. To avoid mbuf leaks, when in netmap mode we - * must make sure that next_to_refresh == next_to_check - 1 - * so that the above while() loop is never run on init. - * - * A better way would be to free the mbufs when entering - * netmap mode, and set next_to_refresh/check in - * a way that the mbufs are completely reallocated - * when going back to standard mode. - */ - struct netmap_adapter *na = NA(adapter->ifp); - struct netmap_slot *slot = netmap_reset(na, - NR_RX, rxr->me, rxr->next_to_check); - int sj = slot ? na->rx_rings[rxr->me].nkr_hwofs : 0; - - /* slot sj corresponds to entry j in the NIC ring */ - if (sj < 0) - sj += adapter->num_rx_desc; - - for (int j = 0; j != adapter->num_rx_desc; j++, sj++) { - rxbuf = &rxr->rx_buffers[j]; - /* no mbuf and regular mode -> skip this entry */ - if (rxbuf->m_head == NULL && !slot) - continue; - /* Handle wrap. Cannot use "na" here, could be NULL */ - if (sj >= adapter->num_rx_desc) - sj -= adapter->num_rx_desc; - /* see comment, set slot addr and map */ - if (slot) { - uint64_t paddr; - void *addr = PNMB(slot + sj, &paddr); - netmap_load_map(rxr->rxtag, rxbuf->map, addr); - /* Update descriptor */ - rxr->rx_base[j].buffer_addr = htole64(paddr); - } else { - /* Get the memory mapping */ - bus_dmamap_load_mbuf_sg(rxr->rxtag, - rxbuf->map, rxbuf->m_head, seg, - &nsegs, BUS_DMA_NOWAIT); - /* Update descriptor */ - rxr->rx_base[j].buffer_addr = htole64(seg[0].ds_addr); - } - bus_dmamap_sync(rxr->rxtag, rxbuf->map, BUS_DMASYNC_PREREAD); - } - } -#endif /* DEV_NETMAP */ - fail: EM_RX_UNLOCK(rxr); return (error); @@ -4313,21 +4279,18 @@ em_initialize_receive_unit(struct adapter *adapter) E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr); /* Setup the Head and Tail Descriptor Pointers */ E1000_WRITE_REG(hw, E1000_RDH(i), 0); - E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1); #ifdef DEV_NETMAP /* * an init() while a netmap client is active must * preserve the rx buffers passed to userspace. * In this driver it means we adjust RDT to - * something different from next_to_refresh. + * something different from na->num_rx_desc - 1. */ if (ifp->if_capenable & IFCAP_NETMAP) { struct netmap_adapter *na = NA(adapter->ifp); struct netmap_kring *kring = &na->rx_rings[i]; - int t = rxr->next_to_refresh - kring->nr_hwavail; + int t = na->num_rx_desc - 1 - kring->nr_hwavail; - if (t < 0) - t += na->num_rx_desc; E1000_WRITE_REG(hw, E1000_RDT(i), t); } else #endif /* DEV_NETMAP */ |