Module Name:    src
Committed By:   msaitoh
Date:           Thu Mar 19 14:22:23 UTC 2015

Modified Files:
        src/sys/dev/pci/ixgbe: ixgbe.c ixv.c

Log Message:
Sync ixg(4) up to FreeBSD r230572.

 - Fix in the interrupt handler to make sure the stack TX queue is processed.
   (FreeBSD r222588)
 - The maximum read size of incoming packets is done in 1024-byte increments.
   The current code was rounding down the maximum frame size instead of
   routing up, resulting in a read size of 1024 bytes, in the non-jumbo
   frame case, and splitting the packets across multiple mbufs.
   (FreeBSD r225045)
 - Consequently the above problem exposed another issue, which is when
   packets were splitted across multiple mbufs, and all of the mbufs in the
   chain have the M_PKTHDR flag set. (FreeBSD r225045)
 - Use the correct constant for conversion between interrupt rate
   and EITR values (the previous values were off by a factor of 2)
   (FreeBSD r230572)
 - Make dev.ix.N.queueM.interrupt_rate a RW sysctl variable. Changing
   individual values affects the queue immediately, and propagates to all
   interfaces at the next reinit. (FreeBSD r230572)
 - Add dev.ix.N.queueM.irqs rdonly sysctl, to export the actual interrupt
   counts. (FreeBSD r230572)
 - Some netmap related changes.


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/pci/ixgbe/ixv.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.21 src/sys/dev/pci/ixgbe/ixgbe.c:1.22
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.21	Tue Feb 24 14:49:28 2015
+++ src/sys/dev/pci/ixgbe/ixgbe.c	Thu Mar 19 14:22:23 2015
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -59,9 +59,10 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 /*$FreeBSD: src/sys/dev/ixgbe/ixgbe.c,v 1.51 2011/04/25 23:34:21 jfv Exp $*/
-/*$NetBSD: ixgbe.c,v 1.21 2015/02/24 14:49:28 msaitoh Exp $*/
+/*$NetBSD: ixgbe.c,v 1.22 2015/03/19 14:22:23 msaitoh Exp $*/
 
 #include "opt_inet.h"
+#include "opt_inet6.h"
 
 #include "ixgbe.h"
 
@@ -73,7 +74,7 @@ int             ixgbe_display_debug_stat
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixgbe_driver_version[] = "2.3.10";
+char ixgbe_driver_version[] = "2.3.11";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -269,7 +270,7 @@ static int ixgbe_enable_aim = TRUE;
 #define TUNABLE_INT(__x, __y)
 TUNABLE_INT("hw.ixgbe.enable_aim", &ixgbe_enable_aim);
 
-static int ixgbe_max_interrupt_rate = (8000000 / IXGBE_LOW_LATENCY);
+static int ixgbe_max_interrupt_rate = (4000000 / IXGBE_LOW_LATENCY);
 TUNABLE_INT("hw.ixgbe.max_interrupt_rate", &ixgbe_max_interrupt_rate);
 
 /* How many packets rxeof tries to clean at a time */
@@ -302,7 +303,7 @@ TUNABLE_INT("hw.ixgbe.enable_msix", &ixg
  * it can be a performance win in some workloads, but
  * in others it actually hurts, its off by default. 
  */
-static bool ixgbe_header_split = FALSE;
+static int ixgbe_header_split = FALSE;
 TUNABLE_INT("hw.ixgbe.hdr_split", &ixgbe_header_split);
 
 #if defined(NETBSD_MSI_OR_MSIX)
@@ -352,6 +353,18 @@ static int atr_sample_rate = 20;
 static int fdir_pballoc = 1;
 #endif
 
+#ifdef DEV_NETMAP
+/*
+ * The #ifdef DEV_NETMAP / #endif blocks in this file are meant to
+ * be a reference on how to implement netmap support in a driver.
+ * Additional comments are in ixgbe_netmap.h .
+ *
+ * <dev/netma/ixgbe_netmap.h> contains functions for netmap support
+ * that extend the standard driver.
+ */
+#include <dev/netmap/ixgbe_netmap.h>
+#endif /* DEV_NETMAP */
+
 /*********************************************************************
  *  Device identification routine
  *
@@ -649,6 +662,9 @@ ixgbe_attach(device_t parent, device_t d
 
 	ixgbe_add_hw_stats(adapter);
 
+#ifdef DEV_NETMAP
+	ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
 	INIT_DEBUGOUT("ixgbe_attach: end");
 	return;
 err_late:
@@ -719,6 +735,9 @@ ixgbe_detach(device_t dev, int flags)
 
 	ether_ifdetach(adapter->ifp);
 	callout_halt(&adapter->timer, NULL);
+#ifdef DEV_NETMAP
+	netmap_detach(adapter->ifp);
+#endif /* DEV_NETMAP */
 	ixgbe_free_pci_resources(adapter);
 #if 0	/* XXX the NetBSD port is probably missing something here */
 	bus_generic_detach(dev);
@@ -1291,6 +1310,31 @@ ixgbe_init_locked(struct adapter *adapte
 				msec_delay(1);
 		}
 		wmb();
+#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 - kring->nr_hwavail;
+
+			IXGBE_WRITE_REG(hw, IXGBE_RDT(i), t);
+		} else
+#endif /* DEV_NETMAP */
 		IXGBE_WRITE_REG(hw, IXGBE_RDT(i), adapter->num_rx_desc - 1);
 	}
 
@@ -1536,7 +1580,7 @@ ixgbe_legacy_irq(void *arg)
 #if defined(NETBSD_MSI_OR_MSIX)
 /*********************************************************************
  *
- *  MSI Queue Interrupt Service routine
+ *  MSIX Queue Interrupt Service routine
  *
  **********************************************************************/
 void
@@ -1555,6 +1599,17 @@ ixgbe_msix_que(void *arg)
 
 	IXGBE_TX_LOCK(txr);
 	more_tx = ixgbe_txeof(txr);
+	/*
+	** Make certain that if the stack 
+	** has anything queued the task gets
+	** scheduled to handle it.
+	*/
+#if __FreeBSD_version < 800000
+	if (!IFQ_DRV_IS_EMPTY(&adapter->ifp->if_snd))
+#else
+	if (!drbr_empty(adapter->ifp, txr->br))
+#endif
+		more_tx = 1;
 	IXGBE_TX_UNLOCK(txr);
 
 	/* Do AIM now? */
@@ -1891,11 +1946,7 @@ ixgbe_xmit(struct tx_ring *txr, struct m
 	txr->next_avail_desc = i;
 
 	txbuf->m_head = m_head;
-	/* We exchange the maps instead of copying because otherwise
-	 * we end up with many pointers to the same map and we free
-	 * one map twice in ixgbe_free_transmit_structures().  Who
-	 * knows what other problems this caused.  --dyoung
-	 */
+	/* Swap the dma map between the first and last descriptor */
 	txr->tx_buffers[first].map = txbuf->map;
 	txbuf->map = map;
 	bus_dmamap_sync(txr->txtag->dt_dmat, map, 0, m_head->m_pkthdr.len,
@@ -2497,7 +2548,9 @@ ixgbe_setup_msix(struct adapter *adapter
 msi:
        	msgs = pci_msi_count(dev);
        	if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0)
-               	device_printf(adapter->dev,"Using MSI interrupt\n");
+               	device_printf(adapter->dev,"Using an MSI interrupt\n");
+	else
+               	device_printf(adapter->dev,"Using a Legacy interrupt\n");
 	return (msgs);
 #endif
 }
@@ -2635,7 +2688,6 @@ ixgbe_setup_interface(device_t dev, stru
 
 	ifp = adapter->ifp = &ec->ec_if;
 	strlcpy(ifp->if_xname, device_xname(dev), IFNAMSIZ);
-	ifp->if_mtu = ETHERMTU;
 	ifp->if_baudrate = 1000000000;
 	ifp->if_init = ixgbe_init;
 	ifp->if_stop = ixgbe_ifstop;
@@ -2665,19 +2717,20 @@ ixgbe_setup_interface(device_t dev, stru
 	ifp->if_capenable = 0;
 
 	ec->ec_capabilities |= ETHERCAP_VLAN_HWCSUM;
-	ec->ec_capabilities |= ETHERCAP_VLAN_HWTAGGING | ETHERCAP_VLAN_MTU;
 	ec->ec_capabilities |= ETHERCAP_JUMBO_MTU;
+	ec->ec_capabilities |= ETHERCAP_VLAN_HWTAGGING
+	    		    | ETHERCAP_VLAN_MTU;
 	ec->ec_capenable = ec->ec_capabilities;
 
 	/* Don't enable LRO by default */
 	ifp->if_capabilities |= IFCAP_LRO;
 
 	/*
-	** Dont turn this on by default, if vlans are
+	** Don't turn this on by default, if vlans are
 	** created on another pseudo device (eg. lagg)
 	** then vlan events are not passed thru, breaking
 	** operation, but with HW FILTER off it works. If
-	** using vlans directly on the em driver you can
+	** using vlans directly on the ixgbe driver you can
 	** enable this and get full hardware tag filtering.
 	*/
 	ec->ec_capabilities |= ETHERCAP_VLAN_HWFILTER;
@@ -3052,9 +3105,20 @@ ixgbe_setup_transmit_ring(struct tx_ring
 	struct adapter *adapter = txr->adapter;
 	struct ixgbe_tx_buf *txbuf;
 	int i;
+#ifdef DEV_NETMAP
+	struct netmap_adapter *na = NA(adapter->ifp);
+	struct netmap_slot *slot;
+#endif /* DEV_NETMAP */
 
 	/* Clear the old ring contents */
 	IXGBE_TX_LOCK(txr);
+#ifdef DEV_NETMAP
+	/*
+	 * (under lock): if in netmap mode, do some consistency
+	 * checks and set slot to entry 0 of the netmap ring.
+	 */
+	slot = netmap_reset(na, NR_TX, txr->me, 0);
+#endif /* DEV_NETMAP */
 	bzero((void *)txr->tx_base,
 	      (sizeof(union ixgbe_adv_tx_desc)) * adapter->num_tx_desc);
 	/* Reset indices */
@@ -3072,6 +3136,25 @@ ixgbe_setup_transmit_ring(struct tx_ring
 			m_freem(txbuf->m_head);
 			txbuf->m_head = NULL;
 		}
+#ifdef DEV_NETMAP
+		/*
+		 * In netmap mode, set the map for the packet buffer.
+		 * NOTE: Some drivers (not this one) also need to set
+		 * the physical buffer address in the NIC ring.
+		 * Slots in the netmap ring (indexed by "si") are
+		 * kring->nkr_hwofs positions "ahead" wrt the
+		 * corresponding slot in the NIC ring. In some drivers
+		 * (not here) nkr_hwofs can be negative. When computing
+		 * si = i + kring->nkr_hwofs make sure to handle wraparounds.
+		 */
+		if (slot) {
+			int si = i + na->tx_rings[txr->me].nkr_hwofs;
+
+			if (si >= na->num_tx_desc)
+				si -= na->num_tx_desc;
+			netmap_load_map(txr->txtag, txbuf->map, NMB(slot + si));
+		}
+#endif /* DEV_NETMAP */
 		/* Clear the EOP index */
 		txbuf->eop_index = -1;
         }
@@ -3549,6 +3632,48 @@ ixgbe_txeof(struct tx_ring *txr)
 
 	KASSERT(mutex_owned(&txr->tx_mtx));
 
+#ifdef DEV_NETMAP
+	if (ifp->if_capenable & IFCAP_NETMAP) {
+		struct netmap_adapter *na = NA(ifp);
+		struct netmap_kring *kring = &na->tx_rings[txr->me];
+
+		tx_desc = (struct ixgbe_legacy_tx_desc *)txr->tx_base;
+
+		bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
+		    BUS_DMASYNC_POSTREAD);
+		/*
+		 * In netmap mode, all the work is done in the context
+		 * of the client thread. Interrupt handlers only wake up
+		 * clients, which may be sleeping on individual rings
+		 * or on a global resource for all rings.
+		 * To implement tx interrupt mitigation, we wake up the client
+		 * thread roughly every half ring, even if the NIC interrupts
+		 * more frequently. This is implemented as follows:
+		 * - ixgbe_txsync() sets kring->nr_kflags with the index of
+		 *   the slot that should wake up the thread (nkr_num_slots
+		 *   means the user thread should not be woken up);
+		 * - the driver ignores tx interrupts unless netmap_mitigate=0
+		 *   or the slot has the DD bit set.
+		 *
+		 * When the driver has separate locks, we need to
+		 * release and re-acquire txlock to avoid deadlocks.
+		 * XXX see if we can find a better way.
+		 */
+		if (!netmap_mitigate ||
+		    (kring->nr_kflags < kring->nkr_num_slots &&
+		     tx_desc[kring->nr_kflags].upper.fields.status & IXGBE_TXD_STAT_DD)) {
+			kring->nr_kflags = kring->nkr_num_slots;
+			selwakeuppri(&na->tx_rings[txr->me].si, PI_NET);
+			IXGBE_TX_UNLOCK(txr);
+			IXGBE_CORE_LOCK(adapter);
+			selwakeuppri(&na->tx_rings[na->num_queues + 1].si, PI_NET);
+			IXGBE_CORE_UNLOCK(adapter);
+			IXGBE_TX_LOCK(txr);
+		}
+		return FALSE;
+	}
+#endif /* DEV_NETMAP */
+
 	if (txr->tx_avail == adapter->num_tx_desc) {
 		txr->queue_status = IXGBE_QUEUE_IDLE;
 		return false;
@@ -3928,12 +4053,20 @@ ixgbe_setup_receive_ring(struct rx_ring 
 	struct lro_ctrl		*lro = &rxr->lro;
 #endif /* LRO */
 	int			rsize, error = 0;
+#ifdef DEV_NETMAP
+	struct netmap_adapter *na = NA(rxr->adapter->ifp);
+	struct netmap_slot *slot;
+#endif /* DEV_NETMAP */
 
 	adapter = rxr->adapter;
 	ifp = adapter->ifp;
 
 	/* Clear the ring contents */
 	IXGBE_RX_LOCK(rxr);
+#ifdef DEV_NETMAP
+	/* same as in ixgbe_setup_transmit_ring() */
+	slot = netmap_reset(na, NR_RX, rxr->me, 0);
+#endif /* DEV_NETMAP */
 	rsize = roundup2(adapter->num_rx_desc *
 	    sizeof(union ixgbe_adv_rx_desc), DBA_ALIGN);
 	bzero((void *)rxr->rx_base, rsize);
@@ -3960,6 +4093,28 @@ ixgbe_setup_receive_ring(struct rx_ring 
 		struct mbuf	*mh, *mp;
 
 		rxbuf = &rxr->rx_buffers[j];
+#ifdef DEV_NETMAP
+		/*
+		 * In netmap mode, fill the map and set the buffer
+		 * address in the NIC ring, considering the offset
+		 * between the netmap and NIC rings (see comment in
+		 * ixgbe_setup_transmit_ring() ). No need to allocate
+		 * an mbuf, so end the block with a continue;
+		 */
+		if (slot) {
+			int sj = j + na->rx_rings[rxr->me].nkr_hwofs;
+			uint64_t paddr;
+			void *addr;
+
+			if (sj >= na->num_rx_desc)
+				sj -= na->num_rx_desc;
+			addr = PNMB(slot + sj, &paddr);
+			netmap_load_map(rxr->ptag, rxbuf->pmap, addr);
+			/* Update descriptor */
+			rxr->rx_base[j].read.pkt_addr = htole64(paddr);
+			continue;
+		}
+#endif /* DEV_NETMAP */
 		/*
 		** Don't allocate mbufs if not
 		** doing header split, its wasteful
@@ -4091,6 +4246,8 @@ fail:
  **********************************************************************/
 #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
 
+#define BSIZEPKT_ROUNDUP ((1<<IXGBE_SRRCTL_BSIZEPKT_SHIFT)-1)
+	
 static void
 ixgbe_initialize_receive_units(struct adapter *adapter)
 {
@@ -4125,7 +4282,7 @@ ixgbe_initialize_receive_units(struct ad
 		hlreg &= ~IXGBE_HLREG0_JUMBOEN;
 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg);
 
-	bufsz = adapter->rx_mbuf_sz  >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+	bufsz = (adapter->rx_mbuf_sz + BSIZEPKT_ROUNDUP) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
 
 	for (i = 0; i < adapter->num_queues; i++, rxr++) {
 		u64 rdba = rxr->rxdma.dma_paddr;
@@ -4410,6 +4567,25 @@ ixgbe_rxeof(struct ix_queue *que, int co
 
 	IXGBE_RX_LOCK(rxr);
 
+#ifdef DEV_NETMAP
+	if (ifp->if_capenable & IFCAP_NETMAP) {
+		/*
+		 * Same as the txeof routine: only wakeup clients on intr.
+		 * NKR_PENDINTR in nr_kflags is used to implement interrupt
+		 * mitigation (ixgbe_rxsync() will not look for new packets
+		 * unless NKR_PENDINTR is set).
+		 */
+		struct netmap_adapter *na = NA(ifp);
+
+		na->rx_rings[rxr->me].nr_kflags |= NKR_PENDINTR;
+		selwakeuppri(&na->rx_rings[rxr->me].si, PI_NET);
+		IXGBE_RX_UNLOCK(rxr);
+		IXGBE_CORE_LOCK(adapter);
+		selwakeuppri(&na->rx_rings[na->num_queues + 1].si, PI_NET);
+		IXGBE_CORE_UNLOCK(adapter);
+		return (FALSE);
+	}
+#endif /* DEV_NETMAP */
 	for (i = rxr->next_to_check; count != 0;) {
 		struct mbuf	*sendmp, *mh, *mp;
 		u32		rsc, ptype;
@@ -4573,9 +4749,10 @@ ixgbe_rxeof(struct ix_queue *que, int co
 			sendmp = rbuf->fmp;
 			rbuf->m_pack = rbuf->fmp = NULL;
 
-			if (sendmp != NULL) /* secondary frag */
+			if (sendmp != NULL) {  /* secondary frag */
+				mp->m_flags &= ~M_PKTHDR;
 				sendmp->m_pkthdr.len += mp->m_len;
-			else {
+			} else {
 				/* first desc of a non-ps chain */
 				sendmp = mp;
 				sendmp->m_flags |= M_PKTHDR;
@@ -4975,7 +5152,7 @@ ixgbe_configure_ivars(struct adapter *ad
 	u32 newitr;
 
 	if (ixgbe_max_interrupt_rate > 0)
-		newitr = (8000000 / ixgbe_max_interrupt_rate) & 0x0FF8;
+		newitr = (4000000 / ixgbe_max_interrupt_rate) & 0x0FF8;
 	else
 		newitr = 0;
 
@@ -5338,6 +5515,7 @@ ixgbe_sysctl_rdt_handler(SYSCTLFN_ARGS)
 static int
 ixgbe_sysctl_interrupt_rate_handler(SYSCTLFN_ARGS)
 {
+	int error;
 	struct sysctlnode node;
 	struct ix_queue *que;
 	uint32_t reg, usec, rate;
@@ -5349,11 +5527,23 @@ ixgbe_sysctl_interrupt_rate_handler(SYSC
 	reg = IXGBE_READ_REG(&que->adapter->hw, IXGBE_EITR(que->msix));
 	usec = ((reg & 0x0FF8) >> 3);
 	if (usec > 0)
-		rate = 1000000 / usec;
+		rate = 500000 / usec;
 	else
 		rate = 0;
 	node.sysctl_data = &rate;
-	return sysctl_lookup(SYSCTLFN_CALL(&node));
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error)
+		return error;
+	reg &= ~0xfff; /* default, no limitation */
+	ixgbe_max_interrupt_rate = 0;
+	if (rate > 0 && rate < 500000) {
+		if (rate < 1000)
+			rate = 1000;
+		ixgbe_max_interrupt_rate = rate;
+		reg |= ((4000000/rate) & 0xff8 );
+	}
+	IXGBE_WRITE_REG(&que->adapter->hw, IXGBE_EITR(que->msix), reg);
+	return 0;
 }
 
 const struct sysctlnode *
@@ -5462,13 +5652,20 @@ ixgbe_add_hw_stats(struct adapter *adapt
 			break;
 
 		if (sysctl_createv(log, 0, &rnode, &cnode,
-		    CTLFLAG_READONLY, CTLTYPE_INT,
+		    CTLFLAG_READWRITE, CTLTYPE_INT,
 		    "interrupt_rate", SYSCTL_DESCR("Interrupt Rate"),
 		    ixgbe_sysctl_interrupt_rate_handler, 0,
 		    (void *)&adapter->queues[i], 0, CTL_CREATE, CTL_EOL) != 0)
 			break;
 
 		if (sysctl_createv(log, 0, &rnode, &cnode,
+		    CTLFLAG_READONLY, CTLTYPE_QUAD,
+		    "irqs", SYSCTL_DESCR("irqs on this queue"),
+			NULL, 0, &(adapter->queues[i].irqs),
+		    0, CTL_CREATE, CTL_EOL) != 0)
+			break;
+
+		if (sysctl_createv(log, 0, &rnode, &cnode,
 		    CTLFLAG_READONLY, CTLTYPE_INT,
 		    "txd_head", SYSCTL_DESCR("Transmit Descriptor Head"),
 		    ixgbe_sysctl_tdh_handler, 0, (void *)txr,
@@ -5769,7 +5966,7 @@ static int
 ixgbe_set_advertise(SYSCTLFN_ARGS)
 {
 	struct sysctlnode	node;
-	int			t, error;
+	int			t, error = 0;
 	struct adapter		*adapter;
 	struct ixgbe_hw		*hw;
 	ixgbe_link_speed	speed, last;

Index: src/sys/dev/pci/ixgbe/ixv.c
diff -u src/sys/dev/pci/ixgbe/ixv.c:1.3 src/sys/dev/pci/ixgbe/ixv.c:1.4
--- src/sys/dev/pci/ixgbe/ixv.c:1.3	Tue Mar 10 09:26:49 2015
+++ src/sys/dev/pci/ixgbe/ixv.c	Thu Mar 19 14:22:23 2015
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2010, Intel Corporation 
+  Copyright (c) 2001-2011, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -31,16 +31,17 @@
 
 ******************************************************************************/
 /*$FreeBSD: src/sys/dev/ixgbe/ixv.c,v 1.2 2011/03/23 13:10:15 jhb Exp $*/
-/*$NetBSD: ixv.c,v 1.3 2015/03/10 09:26:49 msaitoh Exp $*/
+/*$NetBSD: ixv.c,v 1.4 2015/03/19 14:22:23 msaitoh Exp $*/
 
 #include "opt_inet.h"
+#include "opt_inet6.h"
 
 #include "ixv.h"
 
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixv_driver_version[] = "1.0.0";
+char ixv_driver_version[] = "1.0.1";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -223,7 +224,7 @@ TUNABLE_INT("hw.ixv.flow_control", &ixv_
  * it can be a performance win in some workloads, but
  * in others it actually hurts, its off by default.
  */
-static bool ixv_header_split = FALSE;
+static int ixv_header_split = FALSE;
 TUNABLE_INT("hw.ixv.hdr_split", &ixv_header_split);
 
 /*
@@ -254,7 +255,7 @@ static int ixv_total_ports;
  *  ixv_probe determines if the driver should be loaded on
  *  adapter based on PCI vendor/device id of the adapter.
  *
- *  return 0 on success, positive on failure
+ *  return 1 on success, 0 on failure
  *********************************************************************/
 
 static int
@@ -1355,11 +1356,8 @@ ixv_xmit(struct tx_ring *txr, struct mbu
 	txr->next_avail_desc = i;
 
 	txbuf->m_head = m_head;
-	/* We exchange the maps instead of copying because otherwise
-	 * we end up with many pointers to the same map and we free
-	 * one map twice in ixgbe_free_transmit_structures().  Who
-	 * knows what other problems this caused.  --dyoung
-	 */
+	/* Swap the dma map between the first and last descriptor */
+	txr->tx_buffers[first].map = txbuf->map;
 	txbuf->map = map;
 	bus_dmamap_sync(txr->txtag->dt_dmat, map, 0, m_head->m_pkthdr.len,
 	    BUS_DMASYNC_PREWRITE);
@@ -1918,7 +1916,6 @@ ixv_setup_interface(device_t dev, struct
 
 	ifp = adapter->ifp = &ec->ec_if;
 	strlcpy(ifp->if_xname, device_xname(dev), IFNAMSIZ);
-	ifp->if_mtu = ETHERMTU;
 	ifp->if_baudrate = 1000000000;
 	ifp->if_init = ixv_init;
 	ifp->if_stop = ixv_ifstop;
@@ -1949,8 +1946,9 @@ ixv_setup_interface(device_t dev, struct
 	ifp->if_capenable = 0;
 
 	ec->ec_capabilities |= ETHERCAP_VLAN_HWCSUM;
-	ec->ec_capabilities |= ETHERCAP_VLAN_HWTAGGING | ETHERCAP_VLAN_MTU;
 	ec->ec_capabilities |= ETHERCAP_JUMBO_MTU;
+	ec->ec_capabilities |= ETHERCAP_VLAN_HWTAGGING
+	    		| ETHERCAP_VLAN_MTU;
 	ec->ec_capenable = ec->ec_capabilities;
 
 	/* Don't enable LRO by default */

Reply via email to