Date: Wed, 15 Feb 2012 18:59:27 +0000 (UTC) From: Luigi Rizzo <luigi@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r231778 - head/sys/dev/netmap Message-ID: <201202151859.q1FIxRLo076411@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: luigi Date: Wed Feb 15 18:59:26 2012 New Revision: 231778 URL: http://svn.freebsd.org/changeset/base/231778 Log: 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. Modified: head/sys/dev/netmap/if_em_netmap.h head/sys/dev/netmap/if_igb_netmap.h head/sys/dev/netmap/if_lem_netmap.h Modified: head/sys/dev/netmap/if_em_netmap.h ============================================================================== --- head/sys/dev/netmap/if_em_netmap.h Wed Feb 15 18:34:57 2012 (r231777) +++ head/sys/dev/netmap/if_em_netmap.h Wed Feb 15 18:59:26 2012 (r231778) @@ -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 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 * } } + /* * register-unregister routine */ @@ -170,7 +172,7 @@ em_netmap_reg(struct ifnet *ifp, int ono } } 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 @@ fail: return (error); } + /* * Reconcile hardware and user view of the transmit ring. */ @@ -224,6 +227,7 @@ em_netmap_txsync(struct ifnet *ifp, u_in 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_in 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_in return 0; } + /* * Reconcile kernel and user view of the receive ring. */ @@ -304,6 +309,7 @@ em_netmap_rxsync(struct ifnet *ifp, u_in 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_in */ 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_in EM_RX_UNLOCK(rxr); return 0; } +/* end of file */ Modified: head/sys/dev/netmap/if_igb_netmap.h ============================================================================== --- head/sys/dev/netmap/if_igb_netmap.h Wed Feb 15 18:34:57 2012 (r231777) +++ head/sys/dev/netmap/if_igb_netmap.h Wed Feb 15 18:59:26 2012 (r231778) @@ -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 *if /* - * 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 on 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 on 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 @@ fail: /* 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_i 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; - - j = kring->nr_hwcur; /* netmap ring index */ - if (j != k) { /* we have new packets to send */ - u32 olinfo_status = 0; + /* 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; - 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_i } 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_i /* 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_i 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_i 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_i 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_i 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_i 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_i IGB_RX_UNLOCK(rxr); return 0; } +/* end of file */ Modified: head/sys/dev/netmap/if_lem_netmap.h ============================================================================== --- head/sys/dev/netmap/if_lem_netmap.h Wed Feb 15 18:34:57 2012 (r231777) +++ head/sys/dev/netmap/if_lem_netmap.h Wed Feb 15 18:59:26 2012 (r231778) @@ -96,7 +96,7 @@ lem_netmap_lock_wrapper(struct ifnet *if /* - * 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 on 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 on 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 on } } 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 @@ fail: /* - * 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_i 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_i /* 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_i /* 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_i 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_i 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_i 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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202151859.q1FIxRLo076411>