Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Dec 2009 21:30:54 +0000 (UTC)
From:      Jack F Vogel <jfv@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r200239 - head/sys/dev/ixgbe
Message-ID:  <200912072130.nB7LUsX1066653@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jfv
Date: Mon Dec  7 21:30:54 2009
New Revision: 200239
URL: http://svn.freebsd.org/changeset/base/200239

Log:
  Update driver to Intel version 2.0.7:
  
  This adds new feature support for the 82599, a hardware
  assist to LRO, doing this required a large revamp to the
  RX cleanup code because the descriptor ring may not be
  processed out of order, this necessitated the elimination
  of global pointers.
  
  Additionally, the RX routine now does not refresh mbufs
  on every descriptor, rather it will do a range, and then
  update the hardware pointer at that time. These are
  performance oriented changes.
  
  The TX side now has a cleaner simpler watchdog algorithm
  as well, in TX cleanup a read of ticks is stored, that
  can then be compared in local_timer to determine if
  there is a hang.
  
  Various other cleanups along the way, thanks to all who
  have provided input and testing.

Modified:
  head/sys/dev/ixgbe/ixgbe.c
  head/sys/dev/ixgbe/ixgbe.h
  head/sys/dev/ixgbe/ixgbe_82598.c
  head/sys/dev/ixgbe/ixgbe_82599.c
  head/sys/dev/ixgbe/ixgbe_api.c
  head/sys/dev/ixgbe/ixgbe_api.h
  head/sys/dev/ixgbe/ixgbe_common.c
  head/sys/dev/ixgbe/ixgbe_common.h
  head/sys/dev/ixgbe/ixgbe_osdep.h
  head/sys/dev/ixgbe/ixgbe_phy.c
  head/sys/dev/ixgbe/ixgbe_phy.h
  head/sys/dev/ixgbe/ixgbe_type.h

Modified: head/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- head/sys/dev/ixgbe/ixgbe.c	Mon Dec  7 21:24:07 2009	(r200238)
+++ head/sys/dev/ixgbe/ixgbe.c	Mon Dec  7 21:30:54 2009	(r200239)
@@ -46,7 +46,7 @@ int             ixgbe_display_debug_stat
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixgbe_driver_version[] = "1.8.9";
+char ixgbe_driver_version[] = "2.0.7";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -64,16 +64,19 @@ static ixgbe_vendor_info_t ixgbe_vendor_
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_SINGLE_PORT, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_CX4, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT, 0, 0, 0},
+	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT2, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_DA_DUAL_PORT, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_CX4_DUAL_PORT, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_XF_LR, 0, 0, 0},
-	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_SFP_LOM, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4, 0, 0, 0},
+	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4_MEZZ, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_XAUI_LOM, 0, 0, 0},
+	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_CX4, 0, 0, 0},
+	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_COMBO_BACKPLANE, 0, 0, 0},
 	/* required last entry */
 	{0, 0, 0, 0, 0}
 };
@@ -102,7 +105,6 @@ static int	ixgbe_mq_start_locked(struct 
 static void	ixgbe_qflush(struct ifnet *);
 #endif
 static int      ixgbe_ioctl(struct ifnet *, u_long, caddr_t);
-static void     ixgbe_watchdog(struct adapter *);
 static void     ixgbe_init(void *);
 static void     ixgbe_init_locked(struct adapter *);
 static void     ixgbe_stop(void *);
@@ -116,8 +118,8 @@ static int	ixgbe_allocate_queues(struct 
 static int	ixgbe_setup_msix(struct adapter *);
 static void	ixgbe_free_pci_resources(struct adapter *);
 static void     ixgbe_local_timer(void *);
-static int      ixgbe_hardware_init(struct adapter *);
 static void     ixgbe_setup_interface(device_t, struct adapter *);
+static void     ixgbe_config_link(struct adapter *);
 
 static int      ixgbe_allocate_transmit_buffers(struct tx_ring *);
 static int	ixgbe_setup_transmit_structures(struct adapter *);
@@ -132,6 +134,7 @@ static int	ixgbe_setup_receive_ring(stru
 static void     ixgbe_initialize_receive_units(struct adapter *);
 static void     ixgbe_free_receive_structures(struct adapter *);
 static void     ixgbe_free_receive_buffers(struct rx_ring *);
+static void	ixgbe_setup_hw_rsc(struct rx_ring *);
 
 static void	ixgbe_init_moderation(struct adapter *);
 static void     ixgbe_enable_intr(struct adapter *);
@@ -146,7 +149,7 @@ static void     ixgbe_set_multi(struct a
 static void     ixgbe_print_hw_stats(struct adapter *);
 static void	ixgbe_print_debug_info(struct adapter *);
 static void     ixgbe_update_link_status(struct adapter *);
-static int	ixgbe_get_buf(struct rx_ring *, int, u8);
+static int	ixgbe_get_buf(struct rx_ring *, int, int);
 static int      ixgbe_xmit(struct tx_ring *, struct mbuf **);
 static int      ixgbe_sysctl_stats(SYSCTL_HANDLER_ARGS);
 static int	ixgbe_sysctl_debug(SYSCTL_HANDLER_ARGS);
@@ -186,6 +189,10 @@ static void	ixgbe_handle_link(void *, in
 static void	ixgbe_handle_msf(void *, int);
 static void	ixgbe_handle_mod(void *, int);
 
+#ifdef IXGBE_FDIR
+static void	ixgbe_atr(struct tx_ring *, struct mbuf *);
+static void	ixgbe_reinit_fdir(void *, int);
+#endif
 
 /*********************************************************************
  *  FreeBSD Device Interface Entry Points
@@ -239,6 +246,15 @@ static int ixgbe_flow_control = ixgbe_fc
 TUNABLE_INT("hw.ixgbe.flow_control", &ixgbe_flow_control);
 
 /*
+** Smart speed setting, default to on
+** this only works as a compile option
+** right now as its during attach, set
+** this to 'ixgbe_smart_speed_off' to
+** disable.
+*/
+static int ixgbe_smart_speed = ixgbe_smart_speed_on;
+
+/*
  * MSIX should be the default for best performance,
  * but this allows it to be forced off for testing.
  */
@@ -271,7 +287,7 @@ TUNABLE_INT("hw.ixgbe.txd", &ixgbe_txd);
 static int ixgbe_rxd = DEFAULT_RXD;
 TUNABLE_INT("hw.ixgbe.rxd", &ixgbe_rxd);
 
-/* Total number of Interfaces - need for config sanity check */
+/* Keep running tab on them for sanity check */
 static int ixgbe_total_ports;
 
 /*
@@ -288,6 +304,27 @@ static u32 ixgbe_shadow_vfta[IXGBE_VFTA_
 */
 static int ixgbe_num_segs = IXGBE_82598_SCATTER;
 
+#ifdef IXGBE_FDIR
+/*
+** For Flow Director: this is the
+** number of TX packets we sample
+** for the filter pool, this means
+** every 20th packet will be probed.
+**
+** This feature can be disabled by 
+** setting this to 0.
+*/
+static int atr_sample_rate = 20;
+/* 
+** Flow Director actually 'steals'
+** part of the packet buffer as its
+** filter pool, this variable controls
+** how much it uses:
+**  0 = 64K, 1 = 128K, 2 = 256K
+*/
+static int fdir_pballoc = 1;
+#endif
+
 /*********************************************************************
  *  Device identification routine
  *
@@ -356,7 +393,7 @@ ixgbe_attach(device_t dev)
 	struct adapter *adapter;
 	struct ixgbe_hw *hw;
 	int             error = 0;
-	u16		pci_device_id;
+	u16		pci_device_id, csum;
 	u32		ctrl_ext;
 
 	INIT_DEBUGOUT("ixgbe_attach: begin");
@@ -376,10 +413,14 @@ ixgbe_attach(device_t dev)
 		case IXGBE_DEV_ID_82598EB_CX4 :
 			adapter->optics = IFM_10G_CX4;
 			break;
+		case IXGBE_DEV_ID_82598 :
 		case IXGBE_DEV_ID_82598AF_DUAL_PORT :
 		case IXGBE_DEV_ID_82598_DA_DUAL_PORT :
 		case IXGBE_DEV_ID_82598AF_SINGLE_PORT :
+		case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM :
+		case IXGBE_DEV_ID_82598EB_SFP_LOM :
 		case IXGBE_DEV_ID_82598AT :
+		case IXGBE_DEV_ID_82598AT2 :
 			adapter->optics = IFM_10G_SR;
 			break;
 		case IXGBE_DEV_ID_82598EB_XF_LR :
@@ -390,10 +431,13 @@ ixgbe_attach(device_t dev)
 			ixgbe_num_segs = IXGBE_82599_SCATTER;
 			break;
 		case IXGBE_DEV_ID_82599_KX4 :
+		case IXGBE_DEV_ID_82599_KX4_MEZZ:
+		case IXGBE_DEV_ID_82599_CX4 :
 			adapter->optics = IFM_10G_CX4;
 			ixgbe_num_segs = IXGBE_82599_SCATTER;
 			break;
 		case IXGBE_DEV_ID_82599_XAUI_LOM :
+		case IXGBE_DEV_ID_82599_COMBO_BACKPLANE :
 			ixgbe_num_segs = IXGBE_82599_SCATTER;
 		default:
 			break;
@@ -504,13 +548,40 @@ ixgbe_attach(device_t dev)
 		goto err_late;
 	}
 
-	/* Initialize the hardware */
-	if (ixgbe_hardware_init(adapter)) {
-		device_printf(dev,"Unable to initialize the hardware\n");
+	/* Make sure we have a good EEPROM before we read from it */
+	if (ixgbe_validate_eeprom_checksum(&adapter->hw, &csum) < 0) {
+		device_printf(dev,"The EEPROM Checksum Is Not Valid\n");
 		error = EIO;
 		goto err_late;
 	}
 
+	/* Pick up the smart speed setting */
+	if (hw->mac.type == ixgbe_mac_82599EB)
+		hw->phy.smart_speed = ixgbe_smart_speed;
+
+	/* Get Hardware Flow Control setting */
+	hw->fc.requested_mode = ixgbe_fc_full;
+	hw->fc.pause_time = IXGBE_FC_PAUSE;
+	hw->fc.low_water = IXGBE_FC_LO;
+	hw->fc.high_water = IXGBE_FC_HI;
+	hw->fc.send_xon = TRUE;
+
+	error = ixgbe_init_hw(hw);
+	if (error == IXGBE_ERR_EEPROM_VERSION) {
+		device_printf(dev, "This device is a pre-production adapter/"
+		    "LOM.  Please be aware there may be issues associated "
+		    "with your hardware.\n If you are experiencing problems "
+		    "please contact your Intel or hardware representative "
+		    "who provided you with this hardware.\n");
+	} else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED)
+		device_printf(dev,"Unsupported SFP+ Module\n");
+
+	if (error) {
+		error = EIO;
+		device_printf(dev,"Hardware Initialization Failure\n");
+		goto err_late;
+	}
+
 	if ((adapter->msix > 1) && (ixgbe_enable_msix))
 		error = ixgbe_allocate_msix(adapter); 
 	else
@@ -529,10 +600,10 @@ ixgbe_attach(device_t dev)
 	adapter->cycles.mask = (u64)-1;
 	adapter->cycles.mult = 1;
 	adapter->cycles.shift = IXGBE_TSYNC_SHIFT;
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TIMINCA, (1<<24) |
+	IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, (1<<24) |
 	    IXGBE_TSYNC_CYCLE_TIME * IXGBE_TSYNC_SHIFT);
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_SYSTIML, 0x00000000);
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_SYSTIMH, 0xFF800000);
+	IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000);
+	IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0xFF800000);
 
         // JFV - this is not complete yet
 #endif
@@ -551,6 +622,24 @@ ixgbe_attach(device_t dev)
 	adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
 	    ixgbe_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
 
+        /* Print PCIE bus type/speed/width info */
+	ixgbe_get_bus_info(hw);
+	device_printf(dev,"PCI Express Bus: Speed %s %s\n",
+	    ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
+	    (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"),
+	    (hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" :
+	    (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" :
+	    (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
+	    ("Unknown"));
+
+	if (hw->bus.width <= ixgbe_bus_width_pcie_x4) {
+		device_printf(dev, "PCI-Express bandwidth available"
+		    " for this card\n     is not sufficient for"
+		    " optimal performance.\n");
+		device_printf(dev, "For optimal performance a x8 "
+		    "PCI-Express slot is required.\n");
+        }
+
 	/* let hardware know driver is loaded */
 	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
 	ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD;
@@ -616,6 +705,9 @@ ixgbe_detach(device_t dev)
 		taskqueue_drain(adapter->tq, &adapter->link_task);
 		taskqueue_drain(adapter->tq, &adapter->mod_task);
 		taskqueue_drain(adapter->tq, &adapter->msf_task);
+#ifdef IXGBE_FDIR
+		taskqueue_drain(adapter->tq, &adapter->fdir_task);
+#endif
 		taskqueue_free(adapter->tq);
 	}
 
@@ -700,8 +792,8 @@ ixgbe_start_locked(struct tx_ring *txr, 
 		/* Send a copy of the frame to the BPF listener */
 		ETHER_BPF_MTAP(ifp, m_head);
 
-		/* Set timeout in case hardware has problems transmitting */
-		txr->watchdog_timer = IXGBE_TX_TIMEOUT;
+		/* Set watchdog on */
+		txr->watchdog_check = TRUE;
 
 	}
 	return;
@@ -770,16 +862,17 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
 
 	/* If nothing queued go right to xmit */
 	if (drbr_empty(ifp, txr->br)) {
-		if (ixgbe_xmit(txr, &m)) {
-			if (m && (err = drbr_enqueue(ifp, txr->br, m)) != 0)
-                                return (err);
+		if ((err = ixgbe_xmit(txr, &m)) != 0) {
+			if (m != NULL)
+				err = drbr_enqueue(ifp, txr->br, m);
+			return (err);
 		} else {
 			/* Success, update stats */
 			drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags);
 			/* Send a copy of the frame to the BPF listener */
 			ETHER_BPF_MTAP(ifp, m);
 			/* Set the watchdog */
-			txr->watchdog_timer = IXGBE_TX_TIMEOUT;
+			txr->watchdog_check = TRUE;
                 }
 
         } else if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
@@ -796,11 +889,15 @@ process:
 		next = drbr_dequeue(ifp, txr->br);
 		if (next == NULL)
 			break;
-		if (ixgbe_xmit(txr, &next))
+		if ((err = ixgbe_xmit(txr, &next)) != 0) {
+			if (next != NULL)
+				err = drbr_enqueue(ifp, txr->br, next);
 			break;
+		}
+		drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
 		ETHER_BPF_MTAP(ifp, next);
 		/* Set the watchdog */
-		txr->watchdog_timer = IXGBE_TX_TIMEOUT;
+		txr->watchdog_check = TRUE;
 	}
 		
 	if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD)
@@ -843,27 +940,10 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 {
 	struct adapter *adapter = ifp->if_softc;
 	struct ifreq   *ifr = (struct ifreq *) data;
-#ifdef INET
-	struct ifaddr   *ifa = (struct ifaddr *) data;
-#endif
 	int             error = 0;
 
 	switch (command) {
-	case SIOCSIFADDR:
-#ifdef INET
-		IOCTL_DEBUGOUT("ioctl: SIOCxIFADDR (Get/Set Interface Addr)");
-		if (ifa->ifa_addr->sa_family == AF_INET) {
-			ifp->if_flags |= IFF_UP;
-			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-				IXGBE_CORE_LOCK(adapter);
-				ixgbe_init_locked(adapter);
-				IXGBE_CORE_UNLOCK(adapter);
-			}
-			arp_ifinit(ifp, ifa);
-                } else
-#endif
-			ether_ioctl(ifp, command, data);
-		break;
+
 	case SIOCSIFMTU:
 		IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
 		if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - ETHER_HDR_LEN) {
@@ -919,7 +999,8 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 			ifp->if_capenable ^= IFCAP_HWCSUM;
 		if (mask & IFCAP_TSO4)
 			ifp->if_capenable ^= IFCAP_TSO4;
-		if (mask & IFCAP_LRO)
+		/* Only allow changing when using header split */
+		if ((mask & IFCAP_LRO) && (ixgbe_header_split))
 			ifp->if_capenable ^= IFCAP_LRO;
 		if (mask & IFCAP_VLAN_HWTAGGING)
 			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
@@ -948,84 +1029,6 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 }
 
 /*********************************************************************
- *  Watchdog entry point
- *
- *  This routine is called by the local timer
- *  to detect hardware hangs .
- *
- **********************************************************************/
-
-static void
-ixgbe_watchdog(struct adapter *adapter)
-{
-	device_t 	dev = adapter->dev;
-	struct tx_ring *txr = adapter->tx_rings;
-	struct ixgbe_hw *hw = &adapter->hw;
-	bool		tx_hang = FALSE;
-
-	IXGBE_CORE_LOCK_ASSERT(adapter);
-
-        /*
-         * The timer is set to 5 every time ixgbe_start() queues a packet.
-         * Then ixgbe_txeof() keeps resetting to 5 as long as it cleans at
-         * least one descriptor.
-         * Finally, anytime all descriptors are clean the timer is
-         * set to 0.
-         */
-	for (int i = 0; i < adapter->num_queues; i++, txr++) {
-		u32 head, tail;
-
-		IXGBE_TX_LOCK(txr);
-        	if (txr->watchdog_timer == 0 || --txr->watchdog_timer) {
-			IXGBE_TX_UNLOCK(txr);
-                	continue;
-		} else {
-			head = IXGBE_READ_REG(hw, IXGBE_TDH(i));
-			tail = IXGBE_READ_REG(hw, IXGBE_TDT(i));
-			if (head == tail) { /* last minute check */
-				IXGBE_TX_UNLOCK(txr);
-				continue;
-			}
-			/* Well, seems something is really hung */
-			tx_hang = TRUE;
-			IXGBE_TX_UNLOCK(txr);
-			break;
-		}
-	}
-	if (tx_hang == FALSE)
-		return;
-
-	/*
-	 * If we are in this routine because of pause frames, then don't
-	 * reset the hardware.
-	 */
-	if (IXGBE_READ_REG(hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF) {
-		txr = adapter->tx_rings;	/* reset pointer */
-		for (int i = 0; i < adapter->num_queues; i++, txr++) {
-			IXGBE_TX_LOCK(txr);
-			txr->watchdog_timer = IXGBE_TX_TIMEOUT;
-			IXGBE_TX_UNLOCK(txr);
-		}
-		return;
-	}
-
-
-	device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
-	for (int i = 0; i < adapter->num_queues; i++, txr++) {
-		device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", i,
-		    IXGBE_READ_REG(hw, IXGBE_TDH(i)),
-		    IXGBE_READ_REG(hw, IXGBE_TDT(i)));
-		device_printf(dev,"TX(%d) desc avail = %d,"
-		    "Next TX to Clean = %d\n",
-		    i, txr->tx_avail, txr->next_tx_to_clean);
-	}
-	adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-	adapter->watchdog_events++;
-
-	ixgbe_init_locked(adapter);
-}
-
-/*********************************************************************
  *  Init entry point
  *
  *  This routine is used in two ways. It is used by the stack as
@@ -1052,19 +1055,14 @@ ixgbe_init_locked(struct adapter *adapte
 	hw = &adapter->hw;
 	mtx_assert(&adapter->core_mtx, MA_OWNED);
 
-	ixgbe_stop(adapter);
-
 	/* Get the latest mac address, User can use a LAA */
-	bcopy(IF_LLADDR(adapter->ifp), adapter->hw.mac.addr,
+	bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr,
 	      IXGBE_ETH_LENGTH_OF_ADDRESS);
-	ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, 1);
-	adapter->hw.addr_ctrl.rar_used_count = 1;
+	ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1);
+	hw->addr_ctrl.rar_used_count = 1;
 
-	/* Initialize the hardware */
-	if (ixgbe_hardware_init(adapter)) {
-		device_printf(dev, "Unable to initialize the hardware\n");
-		return;
-	}
+	/* Do a warm reset */
+	ixgbe_reset_hw(hw);
 
 	/* Prepare transmit descriptors and buffers */
 	if (ixgbe_setup_transmit_structures(adapter)) {
@@ -1102,7 +1100,7 @@ ixgbe_init_locked(struct adapter *adapte
 
 	gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE);
 
-	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+	if (hw->mac.type == ixgbe_mac_82599EB) {
 		gpie |= IXGBE_SDP1_GPIEN;
 		gpie |= IXGBE_SDP2_GPIEN;
 	}
@@ -1117,7 +1115,7 @@ ixgbe_init_locked(struct adapter *adapte
 		gpie |= IXGBE_GPIE_EIAME | IXGBE_GPIE_PBA_SUPPORT |
 		    IXGBE_GPIE_OCD;
 	}
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_GPIE, gpie);
+	IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
 
 	/* Set the various hardware offload abilities */
 	ifp->if_hwassist = 0;
@@ -1128,28 +1126,35 @@ ixgbe_init_locked(struct adapter *adapte
 
 	/* Set MTU size */
 	if (ifp->if_mtu > ETHERMTU) {
-		mhadd = IXGBE_READ_REG(&adapter->hw, IXGBE_MHADD);
+		mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
 		mhadd &= ~IXGBE_MHADD_MFS_MASK;
 		mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT;
-		IXGBE_WRITE_REG(&adapter->hw, IXGBE_MHADD, mhadd);
+		IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
 	}
 	
 	/* Now enable all the queues */
 
 	for (int i = 0; i < adapter->num_queues; i++) {
-		txdctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(i));
+		txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
 		txdctl |= IXGBE_TXDCTL_ENABLE;
 		/* Set WTHRESH to 8, burst writeback */
 		txdctl |= (8 << 16);
-		IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(i), txdctl);
+		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), txdctl);
 	}
 
 	for (int i = 0; i < adapter->num_queues; i++) {
-		rxdctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(i));
-		/* PTHRESH set to 32 */
-		rxdctl |= 0x0020;
+		rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+		if (hw->mac.type == ixgbe_mac_82598EB) {
+			/*
+			** PTHRESH = 21
+			** HTHRESH = 4
+			** WTHRESH = 8
+			*/
+			rxdctl &= ~0x3FFFFF;
+			rxdctl |= 0x080420;
+		}
 		rxdctl |= IXGBE_RXDCTL_ENABLE;
-		IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(i), rxdctl);
+		IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), rxdctl);
 		for (k = 0; k < 10; k++) {
 			if (IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)) &
 			    IXGBE_RXDCTL_ENABLE)
@@ -1166,7 +1171,7 @@ ixgbe_init_locked(struct adapter *adapte
 
 	/* Enable Receive engine */
 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
-	if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+	if (hw->mac.type == ixgbe_mac_82598EB)
 		rxctrl |= IXGBE_RXCTRL_DMBYPS;
 	rxctrl |= IXGBE_RXCTRL_RXEN;
 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
@@ -1181,7 +1186,11 @@ ixgbe_init_locked(struct adapter *adapte
                 ixgbe_set_ivar(adapter, 0, 0, 1);
 	}
 
-	ixgbe_enable_intr(adapter);
+#ifdef IXGBE_FDIR
+	/* Init Flow director */
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+		ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc);
+#endif
 
 	/*
 	** Check on any SFP devices that
@@ -1194,14 +1203,12 @@ ixgbe_init_locked(struct adapter *adapte
 		ixgbe_detach(dev);
 		return;
         }
-	if (ixgbe_is_sfp(hw)) { 
-		if (hw->phy.multispeed_fiber) {
-			hw->mac.ops.setup_sfp(hw);
-			taskqueue_enqueue(adapter->tq, &adapter->msf_task);
-		} else
-			taskqueue_enqueue(adapter->tq, &adapter->mod_task);
-	} else
-		taskqueue_enqueue(adapter->tq, &adapter->link_task);
+
+	/* Config/Enable Link */
+	ixgbe_config_link(adapter);
+
+	/* And now turn on interrupts */
+	ixgbe_enable_intr(adapter);
 
 	/* Now inform the stack we're ready */
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
@@ -1269,7 +1276,7 @@ ixgbe_disable_queue(struct adapter *adap
 }
 
 static inline void
-ixgbe_rearm_rx_queues(struct adapter *adapter, u64 queues)
+ixgbe_rearm_queues(struct adapter *adapter, u64 queues)
 {
 	u32 mask;
 
@@ -1464,11 +1471,25 @@ ixgbe_msix_link(void *arg)
 		taskqueue_enqueue(adapter->tq, &adapter->link_task);
 
 	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+#ifdef IXGBE_FDIR
+		if (reg_eicr & IXGBE_EICR_FLOW_DIR) {
+			/* This is probably overkill :) */
+			if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1))
+				return;
+                	/* Clear the interrupt */
+			IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
+			/* Turn off the interface */
+			adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+			taskqueue_enqueue(adapter->tq, &adapter->fdir_task);
+		} else
+#endif
 		if (reg_eicr & IXGBE_EICR_ECC) {
                 	device_printf(adapter->dev, "\nCRITICAL: ECC ERROR!! "
 			    "Please Reboot!!\n");
 			IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC);
-		} else if (reg_eicr & IXGBE_EICR_GPI_SDP1) {
+		} else
+
+		if (reg_eicr & IXGBE_EICR_GPI_SDP1) {
                 	/* Clear the interrupt */
                 	IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
 			taskqueue_enqueue(adapter->tq, &adapter->msf_task);
@@ -1553,11 +1574,9 @@ ixgbe_init_moderation(struct adapter *ad
 	}
 
 	/* TX irq moderation rate is fixed */
-	for (int i = 0; i < adapter->num_queues; i++, txr++) {
+	for (int i = 0; i < adapter->num_queues; i++, txr++)
 		IXGBE_WRITE_REG(&adapter->hw,
 		    IXGBE_EITR(txr->msix), ixgbe_ave_latency);
-		txr->watchdog_timer = FALSE;
-	}
 
 	/* RX moderation will be adapted over time, set default */
 	for (int i = 0; i < adapter->num_queues; i++, rxr++) {
@@ -1633,7 +1652,6 @@ ixgbe_media_change(struct ifnet * ifp)
 
         switch (IFM_SUBTYPE(ifm->ifm_media)) {
         case IFM_AUTO:
-                adapter->hw.mac.autoneg = TRUE;
                 adapter->hw.phy.autoneg_advertised =
 		    IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_10GB_FULL;
                 break;
@@ -1690,7 +1708,7 @@ ixgbe_xmit(struct tx_ring *txr, struct m
          * used because it will contain the index of
          * the one we tell the hardware to report back
          */
-        first = txr->next_avail_tx_desc;
+        first = txr->next_avail_desc;
 	txbuf = &txr->tx_buffers[first];
 	txbuf_mapped = txbuf;
 	map = txbuf->map;
@@ -1767,12 +1785,22 @@ ixgbe_xmit(struct tx_ring *txr, struct m
                 cmd_type_len |= IXGBE_ADVTXD_MAC_TSTAMP;
 #endif
 
+#ifdef IXGBE_FDIR
+	/* Do the flow director magic */
+	if ((txr->atr_sample) && (!adapter->fdir_reinit)) {
+		++txr->atr_count;
+		if (txr->atr_count >= atr_sample_rate) {
+			ixgbe_atr(txr, m_head);
+			txr->atr_count = 0;
+		}
+	}
+#endif
         /* Record payload length */
 	if (paylen == 0)
         	olinfo_status |= m_head->m_pkthdr.len <<
 		    IXGBE_ADVTXD_PAYLEN_SHIFT;
 
-	i = txr->next_avail_tx_desc;
+	i = txr->next_avail_desc;
 	for (j = 0; j < nsegs; j++) {
 		bus_size_t seglen;
 		bus_addr_t segaddr;
@@ -1798,7 +1826,7 @@ ixgbe_xmit(struct tx_ring *txr, struct m
 	txd->read.cmd_type_len |=
 	    htole32(IXGBE_TXD_CMD_EOP | IXGBE_TXD_CMD_RS);
 	txr->tx_avail -= nsegs;
-	txr->next_avail_tx_desc = i;
+	txr->next_avail_desc = i;
 
 	txbuf->m_head = m_head;
 	txbuf->map = map;
@@ -1939,7 +1967,7 @@ ixgbe_mc_array_itr(struct ixgbe_hw *hw, 
  *  Timer routine
  *
  *  This routine checks for link status,updates statistics,
- *  and runs the watchdog timer.
+ *  and runs the watchdog check.
  *
  **********************************************************************/
 
@@ -1948,6 +1976,9 @@ ixgbe_local_timer(void *arg)
 {
 	struct adapter *adapter = arg;
 	struct ifnet   *ifp = adapter->ifp;
+	device_t	dev = adapter->dev;
+	struct tx_ring *txr = adapter->tx_rings;
+	bool   tx_hung = FALSE;
 
 	mtx_assert(&adapter->core_mtx, MA_OWNED);
 
@@ -1962,16 +1993,31 @@ ixgbe_local_timer(void *arg)
 		ixgbe_print_hw_stats(adapter);
 	}
 	/*
-	 * Each tick we check the watchdog
-	 * to protect against hardware hangs.
-	 */
-	ixgbe_watchdog(adapter);
-
+	** Check for time since any descriptor was cleaned
+	*/
+        for (int i = 0; i < adapter->num_queues; i++, txr++) {
+		if (txr->watchdog_check == FALSE)
+			continue;
+		if ((ticks - txr->watchdog_time) > IXGBE_WATCHDOG) {
+			tx_hung = TRUE;
+			goto hung;
+		}
+	}
 out:
-	/* Trigger an RX interrupt on all queues */
-        ixgbe_rearm_rx_queues(adapter, adapter->rx_mask);
-
 	callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter);
+	return;
+
+hung:
+	device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
+	device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", txr->me,
+	    IXGBE_READ_REG(&adapter->hw, IXGBE_TDH(txr->me)),
+	    IXGBE_READ_REG(&adapter->hw, IXGBE_TDT(txr->me)));
+	device_printf(dev,"TX(%d) desc avail = %d,"
+	    "Next TX to Clean = %d\n",
+	    txr->me, txr->tx_avail, txr->next_to_clean);
+	adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	adapter->watchdog_events++;
+	ixgbe_init_locked(adapter);
 }
 
 /*
@@ -2004,7 +2050,7 @@ ixgbe_update_link_status(struct adapter 
 			adapter->link_active = FALSE;
 			for (int i = 0; i < adapter->num_queues;
 			    i++, txr++)
-				txr->watchdog_timer = FALSE;
+				txr->watchdog_check = FALSE;
 		}
 	}
 
@@ -2113,6 +2159,9 @@ ixgbe_allocate_legacy(struct adapter *ad
 	TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter);
 	TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter);
 	TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter);
+#ifdef IXGBE_FDIR
+	TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter);
+#endif
 	adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT,
 	    taskqueue_thread_enqueue, &adapter->tq);
 	taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq",
@@ -2242,6 +2291,9 @@ ixgbe_allocate_msix(struct adapter *adap
 	TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter);
 	TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter);
 	TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter);
+#ifdef IXGBE_FDIR
+	TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter);
+#endif
 	adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT,
 	    taskqueue_thread_enqueue, &adapter->tq);
 	taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq",
@@ -2432,65 +2484,15 @@ mem:
 
 /*********************************************************************
  *
- *  Initialize the hardware to a configuration as specified by the
- *  adapter structure. The controller is reset, the EEPROM is
- *  verified, the MAC address is set, then the shared initialization
- *  routines are called.
- *
- **********************************************************************/
-static int
-ixgbe_hardware_init(struct adapter *adapter)
-{
-	device_t dev = adapter->dev;
-	u32 ret;
-	u16 csum;
-
-	csum = 0;
-	/* Issue a global reset */
-	adapter->hw.adapter_stopped = FALSE;
-	ixgbe_stop_adapter(&adapter->hw);
-
-	/* Make sure we have a good EEPROM before we read from it */
-	if (ixgbe_validate_eeprom_checksum(&adapter->hw, &csum) < 0) {
-		device_printf(dev,"The EEPROM Checksum Is Not Valid\n");
-		return (EIO);
-	}
-
-	/* Get Hardware Flow Control setting */
-	adapter->hw.fc.requested_mode = ixgbe_fc_full;
-	adapter->hw.fc.pause_time = IXGBE_FC_PAUSE;
-	adapter->hw.fc.low_water = IXGBE_FC_LO;
-	adapter->hw.fc.high_water = IXGBE_FC_HI;
-	adapter->hw.fc.send_xon = TRUE;
-
-	ret = ixgbe_init_hw(&adapter->hw);
-	if (ret == IXGBE_ERR_EEPROM_VERSION) {
-		device_printf(dev, "This device is a pre-production adapter/"
-		    "LOM.  Please be aware there may be issues associated "
-		    "with your hardware.\n If you are experiencing problems "
-		    "please contact your Intel or hardware representative "
-		    "who provided you with this hardware.\n");
-	} else if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-		device_printf(dev,"Unsupported SFP+ Module\n");
-		return (EIO);
-	} else if (ret != 0 ) {
-		device_printf(dev,"Hardware Initialization Failure\n");
-		return (EIO);
-	}
-
-	return (0);
-}
-
-/*********************************************************************
- *
  *  Setup networking device structure and register an interface.
  *
  **********************************************************************/
 static void
 ixgbe_setup_interface(device_t dev, struct adapter *adapter)
 {
-	struct ifnet   *ifp;
 	struct ixgbe_hw *hw = &adapter->hw;
+	struct ifnet   *ifp;
+
 	INIT_DEBUGOUT("ixgbe_setup_interface: begin");
 
 	ifp = adapter->ifp = if_alloc(IFT_ETHER);
@@ -2522,17 +2524,12 @@ ixgbe_setup_interface(device_t dev, stru
 
 	ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM;
 	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
-	ifp->if_capabilities |= IFCAP_JUMBO_MTU | IFCAP_LRO;
+	ifp->if_capabilities |= IFCAP_JUMBO_MTU;
+	if (ixgbe_header_split)
+		ifp->if_capabilities |= IFCAP_LRO;
 
 	ifp->if_capenable = ifp->if_capabilities;
 
-	if (hw->device_id == IXGBE_DEV_ID_82598AT)
-		ixgbe_setup_link_speed(hw, (IXGBE_LINK_SPEED_10GB_FULL |
-		    IXGBE_LINK_SPEED_1GB_FULL), TRUE, TRUE);
-	else
-		ixgbe_setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL,
-		    TRUE, FALSE);
-
 	/*
 	 * Specify the media types supported by this adapter and register
 	 * callbacks to update media and link information
@@ -2549,7 +2546,51 @@ ixgbe_setup_interface(device_t dev, stru
 	}
 	ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
 	ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
+	return;
+}
+
+static void
+ixgbe_config_link(struct adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32	autoneg, err = 0;
+	bool	sfp, negotiate;
+
+	switch (hw->phy.type) {
+	case ixgbe_phy_sfp_avago:
+	case ixgbe_phy_sfp_ftl:
+	case ixgbe_phy_sfp_intel:
+	case ixgbe_phy_sfp_unknown:
+	case ixgbe_phy_tw_tyco:
+	case ixgbe_phy_tw_unknown:
+                sfp = TRUE;
+	default:
+                sfp = FALSE;
+        }
 
+	if (sfp) { 
+		if (hw->phy.multispeed_fiber) {
+			hw->mac.ops.setup_sfp(hw);
+			taskqueue_enqueue(adapter->tq, &adapter->msf_task);
+		} else
+			taskqueue_enqueue(adapter->tq, &adapter->mod_task);
+	} else {
+		if (hw->mac.ops.check_link)
+			err = ixgbe_check_link(hw, &autoneg,
+			    &adapter->link_up, FALSE);
+		if (err)
+			goto out;
+		autoneg = hw->phy.autoneg_advertised;
+		if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
+                	err  = hw->mac.ops.get_link_capabilities(hw,
+			    &autoneg, &negotiate);
+		if (err)
+			goto out;
+		if (hw->mac.ops.setup_link)
+                	err = hw->mac.ops.setup_link(hw, autoneg,
+			    negotiate, adapter->link_up);
+	}
+out:
 	return;
 }
 
@@ -2833,8 +2874,8 @@ ixgbe_setup_transmit_ring(struct tx_ring
 	bzero((void *)txr->tx_base,
 	      (sizeof(union ixgbe_adv_tx_desc)) * adapter->num_tx_desc);
 	/* Reset indices */
-	txr->next_avail_tx_desc = 0;
-	txr->next_tx_to_clean = 0;
+	txr->next_avail_desc = 0;
+	txr->next_to_clean = 0;
 
 	/* Free any existing tx buffers. */
         txbuf = txr->tx_buffers;
@@ -2850,6 +2891,12 @@ ixgbe_setup_transmit_ring(struct tx_ring
 		txbuf->eop_index = -1;
         }
 
+#ifdef IXGBE_FDIR
+	/* Set the rate at which we sample packets */
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+		txr->atr_sample = atr_sample_rate;
+#endif
+
 	/* Set number of descriptors available */
 	txr->tx_avail = adapter->num_tx_desc;
 
@@ -2888,6 +2935,7 @@ ixgbe_initialize_transmit_units(struct a
 
 	for (int i = 0; i < adapter->num_queues; i++, txr++) {
 		u64	tdba = txr->txdma.dma_paddr;
+		u32	txctrl;
 
 		IXGBE_WRITE_REG(hw, IXGBE_TDBAL(i),
 		       (tdba & 0x00000000ffffffffULL));
@@ -2901,15 +2949,43 @@ ixgbe_initialize_transmit_units(struct a
 
 		/* Setup Transmit Descriptor Cmd Settings */
 		txr->txd_cmd = IXGBE_TXD_CMD_IFCS;
+		txr->watchdog_check = FALSE;
+
+		/* Disable Head Writeback */
+		switch (hw->mac.type) {
+		case ixgbe_mac_82598EB:
+			txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
+			break;
+		case ixgbe_mac_82599EB:
+		default:
+			txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
+			break;
+                }
+		txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+		switch (hw->mac.type) {
+		case ixgbe_mac_82598EB:
+			IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl);
+			break;
+		case ixgbe_mac_82599EB:
+		default:
+			IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), txctrl);
+			break;
+		}
 
-		txr->watchdog_timer = 0;
 	}
 
 	if (hw->mac.type == ixgbe_mac_82599EB) {
-		u32 dmatxctl;
+		u32 dmatxctl, rttdcs;
 		dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
 		dmatxctl |= IXGBE_DMATXCTL_TE;
 		IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
+		/* Disable arbiter to set MTQC */
+		rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+		rttdcs |= IXGBE_RTTDCS_ARBDIS;
+		IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+		IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
+		rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
+		IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
 	}
 
 	return;
@@ -3009,7 +3085,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, 
 	u16	etype;
 	u8	ipproto = 0;
 	bool	offload = TRUE;
-	int ctxd = txr->next_avail_tx_desc;
+	int ctxd = txr->next_avail_desc;
 	u16 vtag = 0;
 
 
@@ -3099,7 +3175,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, 
 	/* We've consumed the first desc, adjust counters */
 	if (++ctxd == adapter->num_tx_desc)
 		ctxd = 0;
-	txr->next_avail_tx_desc = ctxd;
+	txr->next_avail_desc = ctxd;
 	--txr->tx_avail;
 
         return (offload);
@@ -3140,7 +3216,7 @@ ixgbe_tso_setup(struct tx_ring *txr, str
         if (mp->m_len < ehdrlen + sizeof(struct ip) + sizeof(struct tcphdr))
 		return FALSE;
 
-	ctxd = txr->next_avail_tx_desc;
+	ctxd = txr->next_avail_desc;
 	tx_buffer = &txr->tx_buffers[ctxd];
 	TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd];
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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