svn commit: r215970 - in stable/8/sys: conf dev/ixgbe modules/ixgbe

Jack F Vogel jfv at FreeBSD.org
Sun Nov 28 03:41:33 UTC 2010


Author: jfv
Date: Sun Nov 28 03:41:32 2010
New Revision: 215970
URL: http://svn.freebsd.org/changeset/base/215970

Log:
  MFC:  r215911, r215913, r215914

Added:
  stable/8/sys/dev/ixgbe/ixgbe_mbx.c   (contents, props changed)
  stable/8/sys/dev/ixgbe/ixgbe_mbx.h   (contents, props changed)
  stable/8/sys/dev/ixgbe/ixgbe_vf.c   (contents, props changed)
  stable/8/sys/dev/ixgbe/ixgbe_vf.h   (contents, props changed)
  stable/8/sys/dev/ixgbe/ixv.c   (contents, props changed)
  stable/8/sys/dev/ixgbe/ixv.h   (contents, props changed)
Modified:
  stable/8/sys/conf/files
  stable/8/sys/dev/ixgbe/ixgbe.c
  stable/8/sys/dev/ixgbe/ixgbe.h
  stable/8/sys/dev/ixgbe/ixgbe_82598.c
  stable/8/sys/dev/ixgbe/ixgbe_82599.c
  stable/8/sys/dev/ixgbe/ixgbe_api.c
  stable/8/sys/dev/ixgbe/ixgbe_api.h
  stable/8/sys/dev/ixgbe/ixgbe_common.c
  stable/8/sys/dev/ixgbe/ixgbe_common.h
  stable/8/sys/dev/ixgbe/ixgbe_osdep.h
  stable/8/sys/dev/ixgbe/ixgbe_phy.c
  stable/8/sys/dev/ixgbe/ixgbe_phy.h
  stable/8/sys/dev/ixgbe/ixgbe_type.h
  stable/8/sys/modules/ixgbe/Makefile

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files	Sun Nov 28 01:56:44 2010	(r215969)
+++ stable/8/sys/conf/files	Sun Nov 28 03:41:32 2010	(r215970)
@@ -1210,12 +1210,18 @@ dev/ixgb/ixgb_ee.c		optional ixgb
 dev/ixgb/ixgb_hw.c		optional ixgb
 dev/ixgbe/ixgbe.c		optional ixgbe inet \
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/ixgbe/ixv.c			optional ixgbe inet \
+	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
 dev/ixgbe/ixgbe_phy.c		optional ixgbe inet \
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
 dev/ixgbe/ixgbe_api.c		optional ixgbe inet \
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
 dev/ixgbe/ixgbe_common.c	optional ixgbe inet \
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/ixgbe/ixgbe_mbx.c		optional ixgbe inet \
+	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/ixgbe/ixgbe_vf.c		optional ixgbe inet \
+	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
 dev/ixgbe/ixgbe_82598.c		optional ixgbe inet \
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
 dev/ixgbe/ixgbe_82599.c		optional ixgbe inet \

Modified: stable/8/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- stable/8/sys/dev/ixgbe/ixgbe.c	Sun Nov 28 01:56:44 2010	(r215969)
+++ stable/8/sys/dev/ixgbe/ixgbe.c	Sun Nov 28 03:41:32 2010	(r215970)
@@ -46,7 +46,7 @@ int             ixgbe_display_debug_stat
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixgbe_driver_version[] = "2.2.1";
+char ixgbe_driver_version[] = "2.3.6";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -78,6 +78,8 @@ static ixgbe_vendor_info_t ixgbe_vendor_
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_CX4, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_T3_LOM, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_COMBO_BACKPLANE, 0, 0, 0},
+	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BACKPLANE_FCOE, 0, 0, 0},
+	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_FCOE, 0, 0, 0},
 	/* required last entry */
 	{0, 0, 0, 0, 0}
 };
@@ -118,9 +120,9 @@ static int      ixgbe_allocate_legacy(st
 static int	ixgbe_allocate_queues(struct adapter *);
 static int	ixgbe_setup_msix(struct adapter *);
 static void	ixgbe_free_pci_resources(struct adapter *);
-static void     ixgbe_local_timer(void *);
-static int      ixgbe_setup_interface(device_t, struct adapter *);
-static void     ixgbe_config_link(struct adapter *);
+static void	ixgbe_local_timer(void *);
+static int	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 *);
@@ -144,16 +146,12 @@ static bool	ixgbe_txeof(struct tx_ring *
 static bool	ixgbe_rxeof(struct ix_queue *, int);
 static void	ixgbe_rx_checksum(u32, struct mbuf *, u32);
 static void     ixgbe_set_promisc(struct adapter *);
-static void     ixgbe_disable_promisc(struct adapter *);
 static void     ixgbe_set_multi(struct adapter *);
-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 void	ixgbe_refresh_mbufs(struct rx_ring *, 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);
 static int	ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS);
+static int	ixgbe_set_advertise(SYSCTL_HANDLER_ARGS);
 static int	ixgbe_dma_malloc(struct adapter *, bus_size_t,
 		    struct ixgbe_dma_alloc *, int);
 static void     ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *);
@@ -169,6 +167,8 @@ static void	ixgbe_setup_vlan_hw_support(
 static void	ixgbe_register_vlan(void *, struct ifnet *, u16);
 static void	ixgbe_unregister_vlan(void *, struct ifnet *, u16);
 
+static void     ixgbe_add_hw_stats(struct adapter *adapter);
+
 static __inline void ixgbe_rx_discard(struct rx_ring *, int);
 static __inline void ixgbe_rx_input(struct rx_ring *, struct ifnet *,
 		    struct mbuf *, u32);
@@ -211,7 +211,7 @@ static driver_t ixgbe_driver = {
 	"ix", ixgbe_methods, sizeof(struct adapter),
 };
 
-static devclass_t ixgbe_devclass;
+devclass_t ixgbe_devclass;
 DRIVER_MODULE(ixgbe, pci, ixgbe_driver, ixgbe_devclass, 0, 0);
 
 MODULE_DEPEND(ixgbe, pci, 1, 1, 1);
@@ -230,6 +230,9 @@ MODULE_DEPEND(ixgbe, ether, 1, 1, 1);
 static int ixgbe_enable_aim = TRUE;
 TUNABLE_INT("hw.ixgbe.enable_aim", &ixgbe_enable_aim);
 
+static int ixgbe_max_interrupt_rate = (8000000 / IXGBE_LOW_LATENCY);
+TUNABLE_INT("hw.ixgbe.max_interrupt_rate", &ixgbe_max_interrupt_rate);
+
 /* How many packets rxeof tries to clean at a time */
 static int ixgbe_rx_process_limit = 128;
 TUNABLE_INT("hw.ixgbe.rx_process_limit", &ixgbe_rx_process_limit);
@@ -288,13 +291,6 @@ TUNABLE_INT("hw.ixgbe.rxd", &ixgbe_rxd);
 static int ixgbe_total_ports;
 
 /*
-** Shadow VFTA table, this is needed because
-** the real filter table gets cleared during
-** a soft reset and we need to repopulate it.
-*/
-static u32 ixgbe_shadow_vfta[IXGBE_VFTA_SIZE];
-
-/*
 ** The number of scatter-gather segments
 ** differs for 82598 and 82599, default to
 ** the former.
@@ -445,24 +441,21 @@ ixgbe_attach(device_t dev)
 			ixgbe_num_segs = IXGBE_82599_SCATTER;
 			adapter->optics = IFM_10G_T;
 		default:
+			ixgbe_num_segs = IXGBE_82599_SCATTER;
 			break;
 	}
 
 	/* SYSCTL APIs */
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-			OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW,
-			adapter, 0, ixgbe_sysctl_stats, "I", "Statistics");
 
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-			OID_AUTO, "debug", CTLTYPE_INT | CTLFLAG_RW,
-			adapter, 0, ixgbe_sysctl_debug, "I", "Debug Info");
+			OID_AUTO, "flow_control", CTLTYPE_INT | CTLFLAG_RW,
+			adapter, 0, ixgbe_set_flowcntl, "I", "Flow Control");
 
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-			OID_AUTO, "flow_control", CTLTYPE_INT | CTLFLAG_RW,
-			adapter, 0, ixgbe_set_flowcntl, "I", "Flow Control");
+			OID_AUTO, "advertise_gig", CTLTYPE_INT | CTLFLAG_RW,
+			adapter, 0, ixgbe_set_advertise, "I", "1G Link");
 
         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
 			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
@@ -630,6 +623,8 @@ ixgbe_attach(device_t dev)
 	ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD;
 	IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
 
+	ixgbe_add_hw_stats(adapter);
+
 	INIT_DEBUGOUT("ixgbe_attach: end");
 	return (0);
 err_late:
@@ -774,8 +769,8 @@ ixgbe_start_locked(struct tx_ring *txr, 
 		ETHER_BPF_MTAP(ifp, m_head);
 
 		/* Set watchdog on */
-		txr->watchdog_check = TRUE;
 		txr->watchdog_time = ticks;
+		txr->queue_status = IXGBE_QUEUE_WORKING;
 
 	}
 	return;
@@ -845,6 +840,10 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
 		return (err);
 	}
 
+	/* Call cleanup if number of TX descriptors low */
+	if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD)
+		ixgbe_txeof(txr);
+
 	enqueued = 0;
 	if (m == NULL) {
 		next = drbr_dequeue(ifp, txr->br);
@@ -877,7 +876,7 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
 
 	if (enqueued > 0) {
 		/* Set watchdog on */
-		txr->watchdog_check = TRUE;
+		txr->queue_status = IXGBE_QUEUE_WORKING;
 		txr->watchdog_time = ticks;
 	}
 
@@ -942,7 +941,6 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 			if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 				if ((ifp->if_flags ^ adapter->if_flags) &
 				    (IFF_PROMISC | IFF_ALLMULTI)) {
-					ixgbe_disable_promisc(adapter);
 					ixgbe_set_promisc(adapter);
                                 }
 			} else
@@ -981,6 +979,8 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 			ifp->if_capenable ^= IFCAP_LRO;
 		if (mask & IFCAP_VLAN_HWTAGGING)
 			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
+		if (mask & IFCAP_VLAN_HWFILTER)
+			ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
 		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 			IXGBE_CORE_LOCK(adapter);
 			ixgbe_init_locked(adapter);
@@ -1035,6 +1035,18 @@ ixgbe_init_locked(struct adapter *adapte
 	ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1);
 	hw->addr_ctrl.rar_used_count = 1;
 
+	/* Set the various hardware offload abilities */
+	ifp->if_hwassist = 0;
+	if (ifp->if_capenable & IFCAP_TSO4)
+		ifp->if_hwassist |= CSUM_TSO;
+	if (ifp->if_capenable & IFCAP_TXCSUM) {
+		ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
+#if __FreeBSD_version >= 800000
+		if (hw->mac.type == ixgbe_mac_82599EB)
+			ifp->if_hwassist |= CSUM_SCTP;
+#endif
+	}
+
 	/* Prepare transmit descriptors and buffers */
 	if (ixgbe_setup_transmit_structures(adapter)) {
 		device_printf(dev,"Could not setup transmit structures\n");
@@ -1052,10 +1064,12 @@ ixgbe_init_locked(struct adapter *adapte
 	** Determine the correct mbuf pool
 	** for doing jumbo/headersplit
 	*/
-	if (ifp->if_mtu > ETHERMTU)
+	if (adapter->max_frame_size <= 2048)
+		adapter->rx_mbuf_sz = MCLBYTES;
+	else if (adapter->max_frame_size <= 4096)
 		adapter->rx_mbuf_sz = MJUMPAGESIZE;
 	else
-		adapter->rx_mbuf_sz = MCLBYTES;
+		adapter->rx_mbuf_sz = MJUM9BYTES;
 
 	/* Prepare receive descriptors and buffers */
 	if (ixgbe_setup_receive_structures(adapter)) {
@@ -1086,18 +1100,6 @@ ixgbe_init_locked(struct adapter *adapte
 	}
 	IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
 
-	/* Set the various hardware offload abilities */
-	ifp->if_hwassist = 0;
-	if (ifp->if_capenable & IFCAP_TSO4)
-		ifp->if_hwassist |= CSUM_TSO;
-	if (ifp->if_capenable & IFCAP_TXCSUM) {
-		ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
-#if __FreeBSD_version >= 800000
-		if (hw->mac.type == ixgbe_mac_82599EB)
-			ifp->if_hwassist |= CSUM_SCTP;
-#endif
-	}
-
 	/* Set MTU size */
 	if (ifp->if_mtu > ETHERMTU) {
 		mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
@@ -1140,7 +1142,7 @@ ixgbe_init_locked(struct adapter *adapte
 		IXGBE_WRITE_REG(hw, IXGBE_RDT(i), adapter->num_rx_desc - 1);
 	}
 
-	/* Set up VLAN offloads and filter */
+	/* Set up VLAN support and filter */
 	ixgbe_setup_vlan_hw_support(adapter);
 
 	/* Enable Receive engine */
@@ -1754,10 +1756,6 @@ ixgbe_xmit(struct tx_ring *txr, struct m
 	++txr->total_packets;
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(txr->me), i);
 
-	/* Do a clean if descriptors are low */
-	if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD)
-		ixgbe_txeof(txr);
-
 	return (0);
 
 xmit_fail:
@@ -1769,11 +1767,13 @@ xmit_fail:
 static void
 ixgbe_set_promisc(struct adapter *adapter)
 {
-
 	u_int32_t       reg_rctl;
 	struct ifnet   *ifp = adapter->ifp;
 
 	reg_rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
+	reg_rctl &= (~IXGBE_FCTRL_UPE);
+	reg_rctl &= (~IXGBE_FCTRL_MPE);
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_rctl);
 
 	if (ifp->if_flags & IFF_PROMISC) {
 		reg_rctl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
@@ -1786,20 +1786,6 @@ ixgbe_set_promisc(struct adapter *adapte
 	return;
 }
 
-static void
-ixgbe_disable_promisc(struct adapter * adapter)
-{
-	u_int32_t       reg_rctl;
-
-	reg_rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
-
-	reg_rctl &= (~IXGBE_FCTRL_UPE);
-	reg_rctl &= (~IXGBE_FCTRL_MPE);
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_rctl);
-
-	return;
-}
-
 
 /*********************************************************************
  *  Multicast Update
@@ -1893,7 +1879,6 @@ static void
 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;
 
@@ -1907,31 +1892,22 @@ ixgbe_local_timer(void *arg)
 	ixgbe_update_link_status(adapter);
 	ixgbe_update_stats_counters(adapter);
 
-	/* Debug display */
-	if (ixgbe_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING)
-		ixgbe_print_hw_stats(adapter);
-
 	/*
 	 * If the interface has been paused
 	 * then don't do the watchdog check
 	 */
 	if (IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)
 		goto out;
+
 	/*
-	** Check for time since any descriptor was cleaned
+	** Check status on the TX queues for a hang
 	*/
-        for (int i = 0; i < adapter->num_queues; i++, txr++) {
-		IXGBE_TX_LOCK(txr);
-		if (txr->watchdog_check == FALSE) {
-			IXGBE_TX_UNLOCK(txr);
-			continue;
-		}
-		if ((ticks - txr->watchdog_time) > IXGBE_WATCHDOG)
+        for (int i = 0; i < adapter->num_queues; i++, txr++)
+		if (txr->queue_status == IXGBE_QUEUE_HUNG)
 			goto hung;
-		IXGBE_TX_UNLOCK(txr);
-	}
+
 out:
-       	ixgbe_rearm_queues(adapter, adapter->que_mask);
+	ixgbe_rearm_queues(adapter, adapter->que_mask);
 	callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter);
 	return;
 
@@ -1979,7 +1955,7 @@ ixgbe_update_link_status(struct adapter 
 			adapter->link_active = FALSE;
 			for (int i = 0; i < adapter->num_queues;
 			    i++, txr++)
-				txr->watchdog_check = FALSE;
+				txr->queue_status = IXGBE_QUEUE_IDLE;
 		}
 	}
 
@@ -1999,6 +1975,7 @@ ixgbe_stop(void *arg)
 {
 	struct ifnet   *ifp;
 	struct adapter *adapter = arg;
+	struct ixgbe_hw *hw = &adapter->hw;
 	ifp = adapter->ifp;
 
 	mtx_assert(&adapter->core_mtx, MA_OWNED);
@@ -2009,9 +1986,12 @@ ixgbe_stop(void *arg)
 	/* Tell the stack that the interface is no longer active */
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
-	ixgbe_reset_hw(&adapter->hw);
-	adapter->hw.adapter_stopped = FALSE;
-	ixgbe_stop_adapter(&adapter->hw);
+	ixgbe_reset_hw(hw);
+	hw->adapter_stopped = FALSE;
+	ixgbe_stop_adapter(hw);
+	/* Turn off the laser */
+	if (hw->phy.multispeed_fiber)
+		ixgbe_disable_tx_laser(hw);
 	callout_stop(&adapter->timer);
 
 	/* reprogram the RAR[0] in case user changed it. */
@@ -2236,6 +2216,9 @@ ixgbe_setup_msix(struct adapter *adapter
 
 	if (ixgbe_num_queues != 0)
 		queues = ixgbe_num_queues;
+	/* Set max queues to 8 */
+	else if (queues > 8)
+		queues = 8;
 
 	/*
 	** Want one vector (RX/TX pair) per queue
@@ -2408,10 +2391,22 @@ 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;
 	ifp->if_capenable = ifp->if_capabilities;
 
+	/* Don't enable LRO by default */
+	ifp->if_capabilities |= IFCAP_LRO;
+
+	/*
+	** Dont 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
+	** enable this and get full hardware tag filtering.
+	*/
+	ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
+
 	/*
 	 * Specify the media types supported by this adapter and register
 	 * callbacks to update media and link information
@@ -2444,6 +2439,7 @@ ixgbe_config_link(struct adapter *adapte
 	if (sfp) { 
 		if (hw->phy.multispeed_fiber) {
 			hw->mac.ops.setup_sfp(hw);
+			ixgbe_enable_tx_laser(hw);
 			taskqueue_enqueue(adapter->tq, &adapter->msf_task);
 		} else
 			taskqueue_enqueue(adapter->tq, &adapter->mod_task);
@@ -2850,7 +2846,7 @@ ixgbe_initialize_transmit_units(struct a
 
 		/* Setup Transmit Descriptor Cmd Settings */
 		txr->txd_cmd = IXGBE_TXD_CMD_IFCS;
-		txr->watchdog_check = FALSE;
+		txr->queue_status = IXGBE_QUEUE_IDLE;
 
 		/* Disable Head Writeback */
 		switch (hw->mac.type) {
@@ -3189,7 +3185,7 @@ ixgbe_atr(struct tx_ring *txr, struct mb
 {
 	struct adapter			*adapter = txr->adapter;
 	struct ix_queue			*que;
-	struct ixgbe_atr_input		atr_input;
+	union ixgbe_atr_input		atr_input;
 	struct ip			*ip;
 	struct tcphdr			*th;
 	struct udphdr			*uh;
@@ -3233,7 +3229,7 @@ ixgbe_atr(struct tx_ring *txr, struct mb
 		return;
 	}
 
-	memset(&atr_input, 0, sizeof(struct ixgbe_atr_input));
+	memset(&atr_input, 0, sizeof(union ixgbe_atr_input));
 
 	vlan_id = htole16(mp->m_pkthdr.ether_vtag);
 	src_ipv4_addr = ip->ip_src.s_addr;
@@ -3268,15 +3264,18 @@ ixgbe_txeof(struct tx_ring *txr)
 {
 	struct adapter	*adapter = txr->adapter;
 	struct ifnet	*ifp = adapter->ifp;
-	u32	first, last, done;
+	u32	first, last, done, processed;
 	struct ixgbe_tx_buf *tx_buffer;
 	struct ixgbe_legacy_tx_desc *tx_desc, *eop_desc;
 
 	mtx_assert(&txr->tx_mtx, MA_OWNED);
 
-	if (txr->tx_avail == adapter->num_tx_desc)
+	if (txr->tx_avail == adapter->num_tx_desc) {
+		txr->queue_status = IXGBE_QUEUE_IDLE;
 		return FALSE;
+	}
 
+	processed = 0;
 	first = txr->next_to_clean;
 	tx_buffer = &txr->tx_buffers[first];
 	/* For cleanup we just use legacy struct */
@@ -3308,6 +3307,7 @@ ixgbe_txeof(struct tx_ring *txr)
 			tx_desc->lower.data = 0;
 			tx_desc->buffer_addr = 0;
 			++txr->tx_avail;
+			++processed;
 
 			if (tx_buffer->m_head) {
 				txr->bytes +=
@@ -3350,6 +3350,15 @@ ixgbe_txeof(struct tx_ring *txr)
 	txr->next_to_clean = first;
 
 	/*
+	** Watchdog calculation, we know there's
+	** work outstanding or the first return
+	** would have been taken, so none processed
+	** for too long indicates a hang.
+	*/
+	if ((!processed) && ((ticks - txr->watchdog_time) > IXGBE_WATCHDOG))
+		txr->queue_status = IXGBE_QUEUE_HUNG;
+
+	/*
 	 * If we have enough room, clear IFF_DRV_OACTIVE to tell the stack that
 	 * it is OK to send packets. If there are no pending descriptors,
 	 * clear the timeout. Otherwise, if some descriptors have been freed,
@@ -3358,7 +3367,7 @@ ixgbe_txeof(struct tx_ring *txr)
 	if (txr->tx_avail > IXGBE_TX_CLEANUP_THRESHOLD) {
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 		if (txr->tx_avail == adapter->num_tx_desc) {
-			txr->watchdog_check = FALSE;
+			txr->queue_status = IXGBE_QUEUE_IDLE;
 			return FALSE;
 		}
 	}
@@ -3389,51 +3398,59 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr,
 	cleaned = -1; /* Signify no completions */
 	while (i != limit) {
 		rxbuf = &rxr->rx_buffers[i];
-		if ((rxbuf->m_head == NULL) && (rxr->hdr_split)) {
+		if (rxr->hdr_split == FALSE)
+			goto no_split;
+
+		if (rxbuf->m_head == NULL) {
 			mh = m_gethdr(M_DONTWAIT, MT_DATA);
 			if (mh == NULL)
 				goto update;
-			mh->m_pkthdr.len = mh->m_len = MHLEN;
-			mh->m_len = MHLEN;
-			mh->m_flags |= M_PKTHDR;
-			m_adj(mh, ETHER_ALIGN);
-			/* Get the memory mapping */
-			error = bus_dmamap_load_mbuf_sg(rxr->htag,
-			    rxbuf->hmap, mh, hseg, &nsegs, BUS_DMA_NOWAIT);
-			if (error != 0) {
-				printf("GET BUF: dmamap load"
-				    " failure - %d\n", error);
-				m_free(mh);
-				goto update;
-			}
-			rxbuf->m_head = mh;
-			bus_dmamap_sync(rxr->htag, rxbuf->hmap,
-			    BUS_DMASYNC_PREREAD);
-			rxr->rx_base[i].read.hdr_addr =
-			    htole64(hseg[0].ds_addr);
+		} else
+			mh = rxbuf->m_head;
+
+		mh->m_pkthdr.len = mh->m_len = MHLEN;
+		mh->m_len = MHLEN;
+		mh->m_flags |= M_PKTHDR;
+		/* Get the memory mapping */
+		error = bus_dmamap_load_mbuf_sg(rxr->htag,
+		    rxbuf->hmap, mh, hseg, &nsegs, BUS_DMA_NOWAIT);
+		if (error != 0) {
+			printf("Refresh mbufs: hdr dmamap load"
+			    " failure - %d\n", error);
+			m_free(mh);
+			rxbuf->m_head = NULL;
+			goto update;
 		}
+		rxbuf->m_head = mh;
+		bus_dmamap_sync(rxr->htag, rxbuf->hmap,
+		    BUS_DMASYNC_PREREAD);
+		rxr->rx_base[i].read.hdr_addr = htole64(hseg[0].ds_addr);
 
+no_split:
 		if (rxbuf->m_pack == NULL) {
 			mp = m_getjcl(M_DONTWAIT, MT_DATA,
 			    M_PKTHDR, adapter->rx_mbuf_sz);
 			if (mp == NULL)
 				goto update;
-			mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
-			/* Get the memory mapping */
-			error = bus_dmamap_load_mbuf_sg(rxr->ptag,
-			    rxbuf->pmap, mp, pseg, &nsegs, BUS_DMA_NOWAIT);
-			if (error != 0) {
-				printf("GET BUF: dmamap load"
-				    " failure - %d\n", error);
-				m_free(mp);
-				goto update;
-			}
-			rxbuf->m_pack = mp;
-			bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
-			    BUS_DMASYNC_PREREAD);
-			rxr->rx_base[i].read.pkt_addr =
-			    htole64(pseg[0].ds_addr);
+		} else
+			mp = rxbuf->m_pack;
+
+		mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
+		/* Get the memory mapping */
+		error = bus_dmamap_load_mbuf_sg(rxr->ptag,
+		    rxbuf->pmap, mp, pseg, &nsegs, BUS_DMA_NOWAIT);
+		if (error != 0) {
+			printf("Refresh mbufs: payload dmamap load"
+			    " failure - %d\n", error);
+			m_free(mp);
+			rxbuf->m_pack = NULL;
+			goto update;
 		}
+		rxbuf->m_pack = mp;
+		bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
+		    BUS_DMASYNC_PREREAD);
+		rxr->rx_base[i].read.pkt_addr =
+		    htole64(pseg[0].ds_addr);
 
 		cleaned = i;
 		/* Calculate next index */
@@ -3495,9 +3512,9 @@ ixgbe_allocate_receive_buffers(struct rx
 				   BUS_SPACE_MAXADDR,	/* lowaddr */
 				   BUS_SPACE_MAXADDR,	/* highaddr */
 				   NULL, NULL,		/* filter, filterarg */
-				   MJUMPAGESIZE,	/* maxsize */
+				   MJUM9BYTES,		/* maxsize */
 				   1,			/* nsegments */
-				   MJUMPAGESIZE,	/* maxsegsize */
+				   MJUM9BYTES,		/* maxsegsize */
 				   0,			/* flags */
 				   NULL,		/* lockfunc */
 				   NULL,		/* lockfuncarg */
@@ -4021,25 +4038,33 @@ ixgbe_rx_input(struct rx_ring *rxr, stru
 static __inline void
 ixgbe_rx_discard(struct rx_ring *rxr, int i)
 {
-	struct adapter		*adapter = rxr->adapter;
 	struct ixgbe_rx_buf	*rbuf;
-	struct mbuf		*mh, *mp;
 
 	rbuf = &rxr->rx_buffers[i];
-        if (rbuf->fmp != NULL) /* Partial chain ? */
+
+        if (rbuf->fmp != NULL) {/* Partial chain ? */
+		rbuf->fmp->m_flags |= M_PKTHDR;
                 m_freem(rbuf->fmp);
+                rbuf->fmp = NULL;
+	}
 
-	mh = rbuf->m_head;
-	mp = rbuf->m_pack;
+	/*
+	** With advanced descriptors the writeback
+	** clobbers the buffer addrs, so its easier
+	** to just free the existing mbufs and take
+	** the normal refresh path to get new buffers
+	** and mapping.
+	*/
+	if (rbuf->m_head) {
+		m_free(rbuf->m_head);
+		rbuf->m_head = NULL;
+	}
+ 
+	if (rbuf->m_pack) {
+		m_free(rbuf->m_pack);
+		rbuf->m_pack = NULL;
+	}
 
-	/* Reuse loaded DMA map and just update mbuf chain */
-	mh->m_len = MHLEN;
-	mh->m_flags |= M_PKTHDR;
-	mh->m_next = NULL;
-
-	mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz;
-	mp->m_data = mp->m_ext.ext_buf;
-	mp->m_next = NULL;
 	return;
 }
 
@@ -4104,15 +4129,15 @@ ixgbe_rxeof(struct ix_queue *que, int co
 		vtag = le16toh(cur->wb.upper.vlan);
 		eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0);
 
-		/* Make sure all parts of a bad packet are discarded */
+		/* Make sure bad packets are discarded */
 		if (((staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) ||
 		    (rxr->discard)) {
 			ifp->if_ierrors++;
 			rxr->rx_discarded++;
-			if (!eop)
-				rxr->discard = TRUE;
-			else
+			if (eop)
 				rxr->discard = FALSE;
+			else
+				rxr->discard = TRUE;
 			ixgbe_rx_discard(rxr, i);
 			goto next_desc;
 		}
@@ -4123,7 +4148,7 @@ ixgbe_rxeof(struct ix_queue *que, int co
 		** not be fragmented across sequential
 		** descriptors, rather the next descriptor
 		** is indicated in bits of the descriptor.
-		** This also means that we might process
+		** This also means that we might proceses
 		** more than one packet at a time, something
 		** that has never been true before, it
 		** required eliminating global chain pointers
@@ -4204,7 +4229,8 @@ ixgbe_rxeof(struct ix_queue *que, int co
                         } else {
 				/* Singlet, prepare to send */
                                 sendmp = mh;
-                                if (staterr & IXGBE_RXD_STAT_VP) {
+                                if ((adapter->num_vlans) &&
+				  (staterr & IXGBE_RXD_STAT_VP)) {
                                         sendmp->m_pkthdr.ether_vtag = vtag;
                                         sendmp->m_flags |= M_VLANTAG;
                                 }
@@ -4370,12 +4396,13 @@ ixgbe_register_vlan(void *arg, struct if
 	if ((vtag == 0) || (vtag > 4095))	/* Invalid */
 		return;
 
+	IXGBE_CORE_LOCK(adapter);
 	index = (vtag >> 5) & 0x7F;
 	bit = vtag & 0x1F;
-	ixgbe_shadow_vfta[index] |= (1 << bit);
+	adapter->shadow_vfta[index] |= (1 << bit);
 	++adapter->num_vlans;
-	/* Re-init to load the changes */
-	ixgbe_init(adapter);
+	ixgbe_init_locked(adapter);
+	IXGBE_CORE_UNLOCK(adapter);
 }
 
 /*
@@ -4395,17 +4422,20 @@ ixgbe_unregister_vlan(void *arg, struct 
 	if ((vtag == 0) || (vtag > 4095))	/* Invalid */
 		return;
 
+	IXGBE_CORE_LOCK(adapter);
 	index = (vtag >> 5) & 0x7F;
 	bit = vtag & 0x1F;
-	ixgbe_shadow_vfta[index] &= ~(1 << bit);
+	adapter->shadow_vfta[index] &= ~(1 << bit);
 	--adapter->num_vlans;
 	/* Re-init to load the changes */
-	ixgbe_init(adapter);
+	ixgbe_init_locked(adapter);
+	IXGBE_CORE_UNLOCK(adapter);
 }
 
 static void
 ixgbe_setup_vlan_hw_support(struct adapter *adapter)
 {
+	struct ifnet 	*ifp = adapter->ifp;
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32		ctrl;
 
@@ -4424,14 +4454,16 @@ ixgbe_setup_vlan_hw_support(struct adapt
 	** we need to repopulate it now.
 	*/
 	for (int i = 0; i < IXGBE_VFTA_SIZE; i++)
-		if (ixgbe_shadow_vfta[i] != 0)
+		if (adapter->shadow_vfta[i] != 0)
 			IXGBE_WRITE_REG(hw, IXGBE_VFTA(i),
-			    ixgbe_shadow_vfta[i]);
+			    adapter->shadow_vfta[i]);
 
-	/* Enable the Filter Table */
 	ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
-	ctrl &= ~IXGBE_VLNCTRL_CFIEN;
-	ctrl |= IXGBE_VLNCTRL_VFE;
+	/* Enable the Filter Table if enabled */
+	if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) {
+		ctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		ctrl |= IXGBE_VLNCTRL_VFE;
+	}
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ctrl |= IXGBE_VLNCTRL_VME;
 	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl);
@@ -4580,6 +4612,12 @@ static void
 ixgbe_configure_ivars(struct adapter *adapter)
 {
 	struct  ix_queue *que = adapter->queues;
+	u32 newitr;
+
+	if (ixgbe_max_interrupt_rate > 0)
+		newitr = (8000000 / ixgbe_max_interrupt_rate) & 0x0FF8;
+	else
+		newitr = 0;
 
         for (int i = 0; i < adapter->num_queues; i++, que++) {
 		/* First the RX queue entry */
@@ -4588,7 +4626,7 @@ ixgbe_configure_ivars(struct adapter *ad
 		ixgbe_set_ivar(adapter, i, que->msix, 1);
 		/* Set an Initial EITR value */
                 IXGBE_WRITE_REG(&adapter->hw,
-                    IXGBE_EITR(que->msix), IXGBE_LOW_LATENCY);
+                    IXGBE_EITR(que->msix), newitr);
 	}
 
 	/* For the Link interrupt */
@@ -4725,6 +4763,9 @@ ixgbe_update_stats_counters(struct adapt
 	u64  total_missed_rx = 0;
 
 	adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
+	adapter->stats.illerrc += IXGBE_READ_REG(hw, IXGBE_ILLERRC);
+	adapter->stats.errbc += IXGBE_READ_REG(hw, IXGBE_ERRBC);
+	adapter->stats.mspdc += IXGBE_READ_REG(hw, IXGBE_MSPDC);
 
 	for (int i = 0; i < 8; i++) {
 		u32 mp;
@@ -4736,20 +4777,45 @@ ixgbe_update_stats_counters(struct adapt
 		/* Running comprehensive total for stats display */
 		total_missed_rx += adapter->stats.mpc[i];
 		if (hw->mac.type == ixgbe_mac_82598EB)
-			adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+			adapter->stats.rnbc[i] +=
+			    IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+		adapter->stats.pxontxc[i] +=
+		    IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
+		adapter->stats.pxonrxc[i] +=
+		    IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
+		adapter->stats.pxofftxc[i] +=
+		    IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
+		adapter->stats.pxoffrxc[i] +=
+		    IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
+		adapter->stats.pxon2offc[i] +=
+		    IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
+	}
+	for (int i = 0; i < 16; i++) {
+		adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
+		adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
+		adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
+		adapter->stats.qbrc[i] += 
+		    ((u64)IXGBE_READ_REG(hw, IXGBE_QBRC(i)) << 32);
+		adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+		adapter->stats.qbtc[i] +=
+		    ((u64)IXGBE_READ_REG(hw, IXGBE_QBTC(i)) << 32);
+		adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
 	}
+	adapter->stats.mlfc += IXGBE_READ_REG(hw, IXGBE_MLFC);
+	adapter->stats.mrfc += IXGBE_READ_REG(hw, IXGBE_MRFC);
+	adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
 
 	/* Hardware workaround, gprc counts missed packets */
 	adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
 	adapter->stats.gprc -= missed_rx;
 
 	if (hw->mac.type == ixgbe_mac_82599EB) {
-		adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
-		IXGBE_READ_REG(hw, IXGBE_GORCH); /* clears register */
-		adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
-		IXGBE_READ_REG(hw, IXGBE_GOTCH); /* clears register */
-		adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
-		IXGBE_READ_REG(hw, IXGBE_TORH); /* clears register */
+		adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL) +
+		    ((u64)IXGBE_READ_REG(hw, IXGBE_GORCH) << 32);
+		adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL) +
+		    ((u64)IXGBE_READ_REG(hw, IXGBE_GOTCH) << 32);
+		adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL) +
+		    ((u64)IXGBE_READ_REG(hw, IXGBE_TORH) << 32);
 		adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
 		adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
 	} else {
@@ -4770,14 +4836,12 @@ ixgbe_update_stats_counters(struct adapt
 	adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
 	adapter->stats.mprc -= bprc;
 
-	adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC);
 	adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
 	adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
 	adapter->stats.prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255);
 	adapter->stats.prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511);
 	adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
 	adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
-	adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
 
 	lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
 	adapter->stats.lxontxc += lxon;
@@ -4795,14 +4859,27 @@ ixgbe_update_stats_counters(struct adapt
 
 	adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
 	adapter->stats.rfc += IXGBE_READ_REG(hw, IXGBE_RFC);
+	adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC);
 	adapter->stats.rjc += IXGBE_READ_REG(hw, IXGBE_RJC);
+	adapter->stats.mngprc += IXGBE_READ_REG(hw, IXGBE_MNGPRC);
+	adapter->stats.mngpdc += IXGBE_READ_REG(hw, IXGBE_MNGPDC);
+	adapter->stats.mngptc += IXGBE_READ_REG(hw, IXGBE_MNGPTC);
 	adapter->stats.tpr += IXGBE_READ_REG(hw, IXGBE_TPR);
+	adapter->stats.tpt += IXGBE_READ_REG(hw, IXGBE_TPT);
 	adapter->stats.ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127);
 	adapter->stats.ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255);
 	adapter->stats.ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511);
 	adapter->stats.ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023);
 	adapter->stats.ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522);
 	adapter->stats.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
+	adapter->stats.xec += IXGBE_READ_REG(hw, IXGBE_XEC);
+	adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
+	adapter->stats.fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST);
+	adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
+	adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
+	adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
+	adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
+	adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
 
 
 	/* Fill out the OS statistics structure */
@@ -4818,147 +4895,372 @@ ixgbe_update_stats_counters(struct adapt
 		adapter->stats.rlec;
 }
 
-
-/**********************************************************************
- *
- *  This routine is called only when ixgbe_display_debug_stats is enabled.
- *  This routine provides a way to take a look at important statistics
- *  maintained by the driver and hardware.
- *
- **********************************************************************/
-static void
-ixgbe_print_hw_stats(struct adapter * adapter)
+/** ixgbe_sysctl_tdh_handler - Handler function
+ *  Retrieves the TDH value from the hardware
+ */
+static int 
+ixgbe_sysctl_tdh_handler(SYSCTL_HANDLER_ARGS)
 {
-	device_t dev = adapter->dev;
-
+	int error;
 
-	device_printf(dev,"Std Mbuf Failed = %lu\n",
-	       adapter->mbuf_defrag_failed);
-	device_printf(dev,"Missed Packets = %llu\n",
-	       (long long)adapter->stats.mpc[0]);
-	device_printf(dev,"Receive length errors = %llu\n",
-	       ((long long)adapter->stats.roc +
-	       (long long)adapter->stats.ruc));
-	device_printf(dev,"Crc errors = %llu\n",
-	       (long long)adapter->stats.crcerrs);
-	device_printf(dev,"Driver dropped packets = %lu\n",
-	       adapter->dropped_pkts);
-	device_printf(dev, "watchdog timeouts = %ld\n",
-	       adapter->watchdog_events);
-
-	device_printf(dev,"XON Rcvd = %llu\n",
-	       (long long)adapter->stats.lxonrxc);
-	device_printf(dev,"XON Xmtd = %llu\n",
-	       (long long)adapter->stats.lxontxc);
-	device_printf(dev,"XOFF Rcvd = %llu\n",
-	       (long long)adapter->stats.lxoffrxc);
-	device_printf(dev,"XOFF Xmtd = %llu\n",
-	       (long long)adapter->stats.lxofftxc);
-
-	device_printf(dev,"Total Packets Rcvd = %llu\n",
-	       (long long)adapter->stats.tpr);
-	device_printf(dev,"Good Packets Rcvd = %llu\n",
-	       (long long)adapter->stats.gprc);
-	device_printf(dev,"Good Packets Xmtd = %llu\n",
-	       (long long)adapter->stats.gptc);
-	device_printf(dev,"TSO Transmissions = %lu\n",
-	       adapter->tso_tx);
+	struct tx_ring *txr = ((struct tx_ring *)oidp->oid_arg1);
+	if (!txr) return 0;
 
-	return;
+	unsigned val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_TDH(txr->me));
+	error = sysctl_handle_int(oidp, &val, 0, req);
+	if (error || !req->newptr)
+		return error;
+	return 0;
 }
 
-/**********************************************************************
- *
- *  This routine is called only when em_display_debug_stats is enabled.
- *  This routine provides a way to take a look at important statistics
- *  maintained by the driver and hardware.
- *
- **********************************************************************/
-static void
-ixgbe_print_debug_info(struct adapter *adapter)
+/** ixgbe_sysctl_tdt_handler - Handler function
+ *  Retrieves the TDT value from the hardware
+ */
+static int 
+ixgbe_sysctl_tdt_handler(SYSCTL_HANDLER_ARGS)
 {
-	device_t dev = adapter->dev;
-	struct ixgbe_hw		*hw = &adapter->hw;
-	struct ix_queue		*que = adapter->queues;
-	struct rx_ring		*rxr;
-	struct tx_ring		*txr;
-	struct lro_ctrl		*lro;
- 
-	device_printf(dev,"Error Byte Count = %u \n",
-	    IXGBE_READ_REG(hw, IXGBE_ERRBC));
+	int error;
 
-	for (int i = 0; i < adapter->num_queues; i++, que++) {
-		txr = que->txr;
-		rxr = que->rxr;
-		lro = &rxr->lro;
-		device_printf(dev,"QUE(%d) IRQs Handled: %lu\n",
-		    que->msix, (long)que->irqs);
-		device_printf(dev,"RX[%d]: rdh = %d, hw rdt = %d\n",
-	    	    i, IXGBE_READ_REG(hw, IXGBE_RDH(i)),
-	    	    IXGBE_READ_REG(hw, IXGBE_RDT(i)));
-		device_printf(dev,"TX[%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,"RX(%d) Packets Received: %lld\n",
-	    	    rxr->me, (long long)rxr->rx_packets);

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


More information about the svn-src-all mailing list