Skip site navigation (1)Skip section navigation (2)
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>