Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Jul 2015 01:02:02 +0000 (UTC)
From:      Patrick Kelsey <pkelsey@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r285592 - in head/sys: amd64/conf dev/ixgbe dev/netmap
Message-ID:  <201507150102.t6F122jE050275@svnmir.geo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pkelsey
Date: Wed Jul 15 01:02:01 2015
New Revision: 285592
URL: https://svnweb.freebsd.org/changeset/base/285592

Log:
  Add netmap support for ixgbe SRIOV VFs (that is, to if_ixv).
  
  Differential Revision: https://reviews.freebsd.org/D2923
  Reviewed by: erj, gnn
  Approved by: jmallett (mentor)
  Sponsored by: Norse Corp, Inc.

Modified:
  head/sys/amd64/conf/GENERIC
  head/sys/dev/ixgbe/if_ix.c
  head/sys/dev/ixgbe/if_ixv.c
  head/sys/dev/ixgbe/ixgbe.h
  head/sys/dev/netmap/ixgbe_netmap.h

Modified: head/sys/amd64/conf/GENERIC
==============================================================================
--- head/sys/amd64/conf/GENERIC	Wed Jul 15 01:01:17 2015	(r285591)
+++ head/sys/amd64/conf/GENERIC	Wed Jul 15 01:02:01 2015	(r285592)
@@ -362,7 +362,7 @@ device		xenpci			# Xen HVM Hypervisor se
 device		vmx			# VMware VMXNET3 Ethernet
 
 # Netmap provides direct access to TX/RX rings on supported NICs
-device		netmap			# netmap(4) support
+# device		netmap			# netmap(4) support
 
 # The crypto framework is required by IPSEC
 device		crypto			# Required by IPSEC

Modified: head/sys/dev/ixgbe/if_ix.c
==============================================================================
--- head/sys/dev/ixgbe/if_ix.c	Wed Jul 15 01:01:17 2015	(r285591)
+++ head/sys/dev/ixgbe/if_ix.c	Wed Jul 15 01:02:01 2015	(r285592)
@@ -442,6 +442,11 @@ ixgbe_attach(device_t dev)
 	adapter->dev = adapter->osdep.dev = dev;
 	hw = &adapter->hw;
 
+#ifdef DEV_NETMAP
+	adapter->init_locked = ixgbe_init_locked;
+	adapter->stop_locked = ixgbe_stop;
+#endif
+
 	/* Core Lock Init*/
 	IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
 

Modified: head/sys/dev/ixgbe/if_ixv.c
==============================================================================
--- head/sys/dev/ixgbe/if_ixv.c	Wed Jul 15 01:01:17 2015	(r285591)
+++ head/sys/dev/ixgbe/if_ixv.c	Wed Jul 15 01:02:01 2015	(r285592)
@@ -124,6 +124,18 @@ static void	ixv_msix_mbx(void *);
 static void	ixv_handle_que(void *, int);
 static void	ixv_handle_mbx(void *, int);
 
+#ifdef DEV_NETMAP
+/*
+ * This is defined in <dev/netmap/ixgbe_netmap.h>, which is included by
+ * if_ix.c.
+ */
+extern void ixgbe_netmap_attach(struct adapter *adapter);
+
+#include <net/netmap.h>
+#include <sys/selinfo.h>
+#include <dev/netmap/netmap_kern.h>
+#endif /* DEV_NETMAP */
+
 /*********************************************************************
  *  FreeBSD Device Interface Entry Points
  *********************************************************************/
@@ -145,6 +157,9 @@ devclass_t ixv_devclass;
 DRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0);
 MODULE_DEPEND(ixv, pci, 1, 1, 1);
 MODULE_DEPEND(ixv, ether, 1, 1, 1);
+#ifdef DEV_NETMAP
+MODULE_DEPEND(ix, netmap, 1, 1, 1);
+#endif /* DEV_NETMAP */
 /* XXX depend on 'ix' ? */
 
 /*
@@ -278,6 +293,11 @@ ixv_attach(device_t dev)
 	adapter->dev = adapter->osdep.dev = dev;
 	hw = &adapter->hw;
 
+#ifdef DEV_NETMAP
+	adapter->init_locked = ixv_init_locked;
+	adapter->stop_locked = ixv_stop;
+#endif
+
 	/* Core Lock Init*/
 	IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
 
@@ -381,6 +401,9 @@ ixv_attach(device_t dev)
 	adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
 	    ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
 
+#ifdef DEV_NETMAP
+	ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
 	INIT_DEBUGOUT("ixv_attach: end");
 	return (0);
 
@@ -444,6 +467,9 @@ ixv_detach(device_t dev)
 
 	ether_ifdetach(adapter->ifp);
 	callout_drain(&adapter->timer);
+#ifdef DEV_NETMAP
+	netmap_detach(adapter->ifp);
+#endif /* DEV_NETMAP */
 	ixv_free_pci_resources(adapter);
 	bus_generic_detach(dev);
 	if_free(adapter->ifp);
@@ -1685,8 +1711,33 @@ ixv_initialize_receive_units(struct adap
 		wmb();
 
 		/* Set the Tail Pointer */
-		IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me),
-		    adapter->num_rx_desc - 1);
+#ifdef DEV_NETMAP
+		/*
+		 * In netmap mode, we must preserve the buffers made
+		 * available to userspace before the if_init()
+		 * (this is true by default on the TX side, because
+		 * init makes all buffers available to userspace).
+		 *
+		 * netmap_reset() and the device specific routines
+		 * (e.g. ixgbe_setup_receive_rings()) map these
+		 * buffers at the end of the NIC ring, so here we
+		 * must set the RDT (tail) register to make sure
+		 * they are not overwritten.
+		 *
+		 * In this driver the NIC ring starts at RDH = 0,
+		 * RDT points to the last slot available for reception (?),
+		 * so RDT = num_rx_desc - 1 means the whole ring is available.
+		 */
+		if (ifp->if_capenable & IFCAP_NETMAP) {
+			struct netmap_adapter *na = NA(adapter->ifp);
+			struct netmap_kring *kring = &na->rx_rings[i];
+			int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring);
+
+			IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), t);
+		} else
+#endif /* DEV_NETMAP */
+			IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me),
+			    adapter->num_rx_desc - 1);
 	}
 
 	rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);

Modified: head/sys/dev/ixgbe/ixgbe.h
==============================================================================
--- head/sys/dev/ixgbe/ixgbe.h	Wed Jul 15 01:01:17 2015	(r285591)
+++ head/sys/dev/ixgbe/ixgbe.h	Wed Jul 15 01:02:01 2015	(r285592)
@@ -555,6 +555,10 @@ struct adapter {
 #ifdef PCI_IOV
 	struct ixgbe_vf		*vfs;
 #endif
+#ifdef DEV_NETMAP
+	void 			(*init_locked)(struct adapter *);
+	void 			(*stop_locked)(void *);
+#endif
 
 	/* Misc stats maintained by the driver */
 	unsigned long   	dropped_pkts;

Modified: head/sys/dev/netmap/ixgbe_netmap.h
==============================================================================
--- head/sys/dev/netmap/ixgbe_netmap.h	Wed Jul 15 01:01:17 2015	(r285591)
+++ head/sys/dev/netmap/ixgbe_netmap.h	Wed Jul 15 01:02:01 2015	(r285592)
@@ -26,7 +26,7 @@
 /*
  * $FreeBSD$
  *
- * netmap support for: ixgbe
+ * netmap support for: ixgbe (both ix and ixv)
  *
  * This file is meant to be a reference on how to implement
  * netmap support for a network driver.
@@ -48,6 +48,7 @@
  */
 #include <dev/netmap/netmap_kern.h>
 
+void ixgbe_netmap_attach(struct adapter *adapter);
 
 /*
  * device-specific sysctl variables:
@@ -120,20 +121,19 @@ ixgbe_netmap_reg(struct netmap_adapter *
 	struct adapter *adapter = ifp->if_softc;
 
 	IXGBE_CORE_LOCK(adapter);
-	ixgbe_disable_intr(adapter); // XXX maybe ixgbe_stop ?
+	adapter->stop_locked(adapter);
 
-	/* Tell the stack that the interface is no longer active */
-	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
-	set_crcstrip(&adapter->hw, onoff);
+	if (!IXGBE_IS_VF(adapter))
+		set_crcstrip(&adapter->hw, onoff);
 	/* enable or disable flags and callbacks in na and ifp */
 	if (onoff) {
 		nm_set_native_flags(na);
 	} else {
 		nm_clear_native_flags(na);
 	}
-	ixgbe_init_locked(adapter);	/* also enables intr */
-	set_crcstrip(&adapter->hw, onoff); // XXX why twice ?
+	adapter->init_locked(adapter);	/* also enables intr */
+	if (!IXGBE_IS_VF(adapter))
+		set_crcstrip(&adapter->hw, onoff); // XXX why twice ?
 	IXGBE_CORE_UNLOCK(adapter);
 	return (ifp->if_drv_flags & IFF_DRV_RUNNING ? 0 : 1);
 }
@@ -266,7 +266,7 @@ ixgbe_netmap_txsync(struct netmap_kring 
 			BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 		/* (re)start the tx unit up to slot nic_i (excluded) */
-		IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(txr->me), nic_i);
+		IXGBE_WRITE_REG(&adapter->hw, txr->tail, nic_i);
 	}
 
 	/*
@@ -310,7 +310,8 @@ ixgbe_netmap_txsync(struct netmap_kring 
 		 * REPORT_STATUS in a few slots so TDH is the only
 		 * good way.
 		 */
-		nic_i = IXGBE_READ_REG(&adapter->hw, IXGBE_TDH(kring->ring_id));
+		nic_i = IXGBE_READ_REG(&adapter->hw, IXGBE_IS_VF(adapter) ?
+				       IXGBE_VFTDH(kring->ring_id) : IXGBE_TDH(kring->ring_id));
 		if (nic_i >= kring->nkr_num_slots) { /* XXX can it happen ? */
 			D("TDH wrap %d", nic_i);
 			nic_i -= kring->nkr_num_slots;
@@ -379,7 +380,7 @@ ixgbe_netmap_rxsync(struct netmap_kring 
 	 * rxr->next_to_check is set to 0 on a ring reinit
 	 */
 	if (netmap_no_pendintr || force_update) {
-		int crclen = ix_crcstrip ? 0 : 4;
+		int crclen = (ix_crcstrip || IXGBE_IS_VF(adapter) ) ? 0 : 4;
 		uint16_t slot_flags = kring->nkr_slot_flags;
 
 		nic_i = rxr->next_to_check; // or also k2n(kring->nr_hwtail)
@@ -453,7 +454,7 @@ ixgbe_netmap_rxsync(struct netmap_kring 
 		 * so move nic_i back by one unit
 		 */
 		nic_i = nm_prev(nic_i, lim);
-		IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(rxr->me), nic_i);
+		IXGBE_WRITE_REG(&adapter->hw, rxr->tail, nic_i);
 	}
 
 	return 0;
@@ -470,7 +471,7 @@ ring_reset:
  * netmap mode will be disabled and the driver will only
  * operate in standard mode.
  */
-static void
+void
 ixgbe_netmap_attach(struct adapter *adapter)
 {
 	struct netmap_adapter na;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507150102.t6F122jE050275>