Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Jul 2010 12:05:09 +0200
From:      Harald Schmalzbauer <h.schmalzbauer@omnilan.de>
To:        "Brian A. Seklecki" <bseklecki@collaborativefusion.com>
Cc:        FreeBSD Stable <freebsd-stable@freebsd.org>
Subject:   Re: e1000 patchset for 8.1-release [Was: em(4) duplex problems with 82541EI on RELENG_8, -CURRENT on PowerEdge 1850]
Message-ID:  <4C4EAF55.9070908@omnilan.de>
In-Reply-To: <1280170608.17017.17.camel@soundwave>
References:  <1275419919.30057.50.camel@soundwave.ws.pitbpa0.priv.collaborativefusion.com>	 <20100601193733.GA44816@icarus.home.lan>	 <AANLkTilAiGMfh7Jo0aJk4aEYXnPOvJvz93Xl3fpsxGQR@mail.gmail.com>	 <AANLkTik2uhWo1MGbEfvZGfSiLpx5Y-m9FpA1UKn3SaTa@mail.gmail.com>	 <4C3CBC1E.9030106@omnilan.de>	<1279212377.31311.144.camel@soundwave>	 <1279212602.31311.151.camel@soundwave>	 <84875A93-3851-476E-8F2E-A7008CA6BD5C@FreeBSD.org>	 <4C3F49E8.9090201@comcast.net>	 <AANLkTilXYsE9SID4qeAdn_ZhHCWL8xO6dRKaIjNl4gJD@mail.gmail.com>	 <1279552398.31311.443.camel@soundwave>	<4C447684.7010308@omnilan.de>	 <4C4DB59D.6020204@noc.cfi.pgh.pa.us> <4C4DD917.3050007@omnilan.de> <1280170608.17017.17.camel@soundwave>

next in thread | previous in thread | raw e-mail | index | archive | help
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enig5A94A6482AB6BCA889B3EE66
Content-Type: multipart/mixed; boundary="------------020106010007020907000302"

This is a multi-part message in MIME format.
--------------020106010007020907000302
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Brian A. Seklecki schrieb am 26.07.2010 20:56 (localtime):
=2E..

I made a new convenience patch which brings the comperhensive r209309=20
merge from HEAD to RELENG_8 (not RELENG_8_1, so not included in=20
FreeBSD-8.1-RELEASE) along with the new fix for TX checksum offload=20
panics (r209959, not yet merged) to RELENG_8_1

 >> t not 209959, which addresses
 >>>   the TX checksum panic?)
 >> Looks like I really missed r209259
 >
 >
 > I fudged it manually --- Attached:
 >
 >=20
cf_e1000-releng8_send_out_the_clowns_then_dougBarton_then_Vanila_Ice.patc=
h
 >
 > It applies cleanly to 8.1, but it doesn't fix my problem.

This patch differs in many lines from yours. I haven't checked the diff=20
of the diff, but maybe something went wrong. Perhaps it's worth trying=20
my new patchset.


Please find attached.

-Harry

--------------020106010007020907000302
Content-Type: text/x-patch;
 name="e1000-r209309+r209959.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline;
 filename="e1000-r209309+r209959.patch"

--- src/sys/dev/e1000/if_em.c.orig	2010-06-14 04:09:06.000000000 +0200
+++ src/sys/dev/e1000/if_em.c	2010-07-27 10:06:45.317871239 +0200
@@ -30,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
=20
 ************************************************************************=
******/
-/*$FreeBSD: src/sys/dev/e1000/if_em.c,v 1.21.2.10.2.1 2010/06/14 02:09:0=
6 kensmith Exp $*/
+/*$FreeBSD: src/sys/dev/e1000/if_em.c,v 1.51 2010/07/12 21:47:30 jfv Exp=
 $*/
=20
 #ifdef HAVE_KERNEL_OPTION_HEADERS
 #include "opt_device_polling.h"
@@ -230,8 +230,9 @@
 static void	em_enable_intr(struct adapter *);
 static void	em_disable_intr(struct adapter *);
 static void	em_update_stats_counters(struct adapter *);
+static void	em_add_hw_stats(struct adapter *adapter);
 static bool	em_txeof(struct tx_ring *);
-static int	em_rxeof(struct rx_ring *, int);
+static bool	em_rxeof(struct rx_ring *, int, int *);
 #ifndef __NO_STRICT_ALIGNMENT
 static int	em_fixup_rx(struct rx_ring *);
 #endif
@@ -242,7 +243,6 @@
 static void	em_set_promisc(struct adapter *);
 static void	em_disable_promisc(struct adapter *);
 static void	em_set_multi(struct adapter *);
-static void	em_print_hw_stats(struct adapter *);
 static void	em_update_link_status(struct adapter *);
 static void	em_refresh_mbufs(struct rx_ring *, int);
 static void	em_register_vlan(void *, struct ifnet *, u16);
@@ -252,11 +252,9 @@
 static int	em_dma_malloc(struct adapter *, bus_size_t,
 		    struct em_dma_alloc *, int);
 static void	em_dma_free(struct adapter *, struct em_dma_alloc *);
-static void	em_print_debug_info(struct adapter *);
+static int	em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS);
 static void	em_print_nvm_info(struct adapter *);
 static int 	em_is_valid_ether_addr(u8 *);
-static int	em_sysctl_stats(SYSCTL_HANDLER_ARGS);
-static int	em_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
 static int	em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
 static void	em_add_int_delay_sysctl(struct adapter *, const char *,
 		    const char *, struct em_int_delay_info *, int, int);
@@ -347,8 +345,13 @@
 TUNABLE_INT("hw.em.sbp", &em_debug_sbp);
=20
 /* Local controls for MSI/MSIX */
+#ifdef EM_MULTIQUEUE
 static int em_enable_msix =3D TRUE;
 static int em_msix_queues =3D 2; /* for 82574, can be 1 or 2 */
+#else
+static int em_enable_msix =3D FALSE;
+static int em_msix_queues =3D 0; /* disable */
+#endif
 TUNABLE_INT("hw.em.enable_msix", &em_enable_msix);
 TUNABLE_INT("hw.em.msix_queues", &em_msix_queues);
=20
@@ -447,13 +450,8 @@
 	/* SYSCTL stuff */
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-	    OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
-	    em_sysctl_debug_info, "I", "Debug Information");
-
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-	    OID_AUTO, "stats", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
-	    em_sysctl_stats, "I", "Statistics");
+	    OID_AUTO, "nvm", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
+	    em_sysctl_nvm_info, "I", "NVM Information");
=20
 	callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
=20
@@ -651,6 +649,8 @@
 	adapter->vlan_detach =3D EVENTHANDLER_REGISTER(vlan_unconfig,
 	    em_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);=20
=20
+	em_add_hw_stats(adapter);
+
 	/* Non-AMT based hardware can now take control from firmware */
 	if (adapter->has_manage && !adapter->has_amt)
 		em_get_hw_control(adapter);
@@ -1351,12 +1351,13 @@
 	struct adapter *adapter =3D ifp->if_softc;
 	struct tx_ring	*txr =3D adapter->tx_rings;
 	struct rx_ring	*rxr =3D adapter->rx_rings;
-	u32		reg_icr, rx_done =3D 0;
+	u32		reg_icr;
+	int		rx_done;
=20
 	EM_CORE_LOCK(adapter);
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) =3D=3D 0) {
 		EM_CORE_UNLOCK(adapter);
-		return (rx_done);
+		return (0);
 	}
=20
 	if (cmd =3D=3D POLL_AND_CHECK_STATUS) {
@@ -1371,9 +1372,7 @@
 	}
 	EM_CORE_UNLOCK(adapter);
=20
-	EM_RX_LOCK(rxr);
-	rx_done =3D em_rxeof(rxr, count);
-	EM_RX_UNLOCK(rxr);
+	em_rxeof(rxr, count, &rx_done);
=20
 	EM_TX_LOCK(txr);
 	em_txeof(txr);
@@ -1445,16 +1444,15 @@
 	struct ifnet	*ifp =3D adapter->ifp;
 	struct tx_ring	*txr =3D adapter->tx_rings;
 	struct rx_ring	*rxr =3D adapter->rx_rings;
-	bool		more_rx;
+	bool		more;
=20
=20
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		EM_RX_LOCK(rxr);
-		more_rx =3D em_rxeof(rxr, adapter->rx_process_limit);
-		EM_RX_UNLOCK(rxr);
+		more =3D em_rxeof(rxr, adapter->rx_process_limit, NULL);
=20
 		EM_TX_LOCK(txr);
-		em_txeof(txr);
+		if (em_txeof(txr))
+			more =3D TRUE;
 #ifdef EM_MULTIQUEUE
 		if (!drbr_empty(ifp, txr->br))
 			em_mq_start_locked(ifp, txr, NULL);
@@ -1463,7 +1461,7 @@
 			em_start_locked(ifp, txr);
 #endif
 		EM_TX_UNLOCK(txr);
-		if (more_rx) {
+		if (more) {
 			taskqueue_enqueue(adapter->tq, &adapter->que_task);
 			return;
 		}
@@ -1511,10 +1509,8 @@
 	struct adapter	*adapter =3D rxr->adapter;
 	bool		more;
=20
-	EM_RX_LOCK(rxr);
 	++rxr->rx_irq;
-	more =3D em_rxeof(rxr, adapter->rx_process_limit);
-	EM_RX_UNLOCK(rxr);
+	more =3D em_rxeof(rxr, adapter->rx_process_limit, NULL);
 	if (more)
 		taskqueue_enqueue(rxr->tq, &rxr->rx_task);
 	else
@@ -1539,7 +1535,7 @@
=20
 	if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
 		adapter->hw.mac.get_link_status =3D 1;
-		taskqueue_enqueue(taskqueue_fast, &adapter->link_task);
+		em_handle_link(adapter, 0);
 	} else
 		E1000_WRITE_REG(&adapter->hw, E1000_IMS,
 		    EM_MSIX_LINK | E1000_IMS_LSC);
@@ -1553,9 +1549,7 @@
 	struct adapter	*adapter =3D rxr->adapter;
         bool            more;
=20
-	EM_RX_LOCK(rxr);
-	more =3D em_rxeof(rxr, adapter->rx_process_limit);
-	EM_RX_UNLOCK(rxr);
+	more =3D em_rxeof(rxr, adapter->rx_process_limit, NULL);
 	if (more)
 		taskqueue_enqueue(rxr->tq, &rxr->rx_task);
 	else
@@ -1744,6 +1738,19 @@
 	do_tso =3D ((m_head->m_pkthdr.csum_flags & CSUM_TSO) !=3D 0);
=20
 	/*
+	** When doing checksum offload, it is critical to
+	** make sure the first mbuf has more than header,
+	** because that routine expects data to be present.
+	*/
+	if ((m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) &&
+	    (m_head->m_len < ETHER_HDR_LEN + sizeof(struct ip))) {
+		m_head =3D m_pullup(m_head, ETHER_HDR_LEN + sizeof(struct ip));
+		*m_headp =3D m_head;
+		if (m_head =3D=3D NULL)
+			return (ENOBUFS);
+	}
+
+	/*
 	 * TSO workaround:=20
 	 *  If an mbuf is only header we need =20
 	 *     to pull 4 bytes of data into it.=20
@@ -2069,9 +2076,6 @@
 	if (e1000_get_laa_state_82571(&adapter->hw) =3D=3D TRUE)
 		e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
=20
-	if (em_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING)
-		em_print_hw_stats(adapter);
-
 	/*
 	** Check for time since any descriptor was cleaned
 	*/
@@ -2431,11 +2435,6 @@
 	adapter->linkvec =3D vector;
 	adapter->ivars |=3D  (8 | vector) << 16;
 	adapter->ivars |=3D 0x80000000;
-	TASK_INIT(&adapter->link_task, 0, em_handle_link, adapter);
-	adapter->tq =3D taskqueue_create_fast("em_link", M_NOWAIT,
-	    taskqueue_thread_enqueue, &adapter->tq);
-	taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq",
-	    device_get_nameunit(adapter->dev));
=20
 	return (0);
 }
@@ -3276,6 +3275,7 @@
=20
=20
 	cmd =3D hdr_len =3D ipproto =3D 0;
+	*txd_upper =3D *txd_lower =3D 0;
 	cur =3D txr->next_avail_desc;
=20
 	/*
@@ -3319,29 +3319,21 @@
 			*txd_upper |=3D E1000_TXD_POPTS_IXSM << 8;
 		}
=20
-		if (mp->m_len < ehdrlen + ip_hlen)
-			return;	/* failure */
-
 		hdr_len =3D ehdrlen + ip_hlen;
 		ipproto =3D ip->ip_p;
-
 		break;
+
 	case ETHERTYPE_IPV6:
 		ip6 =3D (struct ip6_hdr *)(mp->m_data + ehdrlen);
 		ip_hlen =3D sizeof(struct ip6_hdr); /* XXX: No header stacking. */
=20
-		if (mp->m_len < ehdrlen + ip_hlen)
-			return;	/* failure */
-
 		/* IPv6 doesn't have a header checksum. */
=20
 		hdr_len =3D ehdrlen + ip_hlen;
 		ipproto =3D ip6->ip6_nxt;
-
 		break;
+
 	default:
-		*txd_upper =3D 0;
-		*txd_lower =3D 0;
 		return;
 	}
=20
@@ -3395,6 +3387,8 @@
 		break;
 	}
=20
+	if (TXD =3D=3D NULL)
+		return;
 	TXD->tcp_seg_setup.data =3D htole32(0);
 	TXD->cmd_and_length =3D
 	    htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd);
@@ -4090,8 +4084,8 @@
  * =20
  *  For polling we also now return the number of cleaned packets
  *********************************************************************/
-static int
-em_rxeof(struct rx_ring *rxr, int count)
+static bool
+em_rxeof(struct rx_ring *rxr, int count, int *done)
 {
 	struct adapter		*adapter =3D rxr->adapter;
 	struct ifnet		*ifp =3D adapter->ifp;
@@ -4102,7 +4096,7 @@
 	bool			eop;
 	struct e1000_rx_desc	*cur;
=20
-	EM_RX_LOCK_ASSERT(rxr);
+	EM_RX_LOCK(rxr);
=20
 	for (i =3D rxr->next_to_check, processed =3D 0; count !=3D 0;) {
=20
@@ -4196,8 +4190,13 @@
 			i =3D 0;
=20
 		/* Send to the stack */
-		if (sendmp !=3D NULL)
+		if (sendmp !=3D NULL) {
+			rxr->next_to_check =3D i;
+			EM_RX_UNLOCK(rxr);
 			(*ifp->if_input)(ifp, sendmp);
+			EM_RX_LOCK(rxr);
+			i =3D rxr->next_to_check;
+		}
=20
 		/* Only refresh mbufs every 8 descriptors */
 		if (processed =3D=3D 8) {
@@ -4213,12 +4212,11 @@
 	}
=20
 	rxr->next_to_check =3D i;
+	if (done !=3D NULL)
+		*done =3D rxdone;
+	EM_RX_UNLOCK(rxr);
=20
-#ifdef DEVICE_POLLING
-	return (rxdone);
-#else
 	return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
-#endif
 }
=20
 #ifndef __NO_STRICT_ALIGNMENT
@@ -4869,114 +4867,285 @@
 }
=20
=20
-/**********************************************************************
- *
- *  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.
- *
- **********************************************************************/=

+/*
+ * Add sysctl variables, one per statistic, to the system.
+ */
 static void
-em_print_debug_info(struct adapter *adapter)
+em_add_hw_stats(struct adapter *adapter)
 {
+
 	device_t dev =3D adapter->dev;
-	u8 *hw_addr =3D adapter->hw.hw_addr;
-	struct rx_ring *rxr =3D adapter->rx_rings;
-	struct tx_ring *txr =3D adapter->tx_rings;
=20
-	device_printf(dev, "Adapter hardware address =3D %p \n", hw_addr);
-	device_printf(dev, "CTRL =3D 0x%x RCTL =3D 0x%x \n",
-	    E1000_READ_REG(&adapter->hw, E1000_CTRL),
-	    E1000_READ_REG(&adapter->hw, E1000_RCTL));
-	device_printf(dev, "Packet buffer =3D Tx=3D%dk Rx=3D%dk \n",
-	    ((E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff0000) >> 16),\
-	    (E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff) );
-	device_printf(dev, "Flow control watermarks high =3D %d low =3D %d\n",
-	    adapter->hw.fc.high_water,
-	    adapter->hw.fc.low_water);
-	device_printf(dev, "tx_int_delay =3D %d, tx_abs_int_delay =3D %d\n",
-	    E1000_READ_REG(&adapter->hw, E1000_TIDV),
-	    E1000_READ_REG(&adapter->hw, E1000_TADV));
-	device_printf(dev, "rx_int_delay =3D %d, rx_abs_int_delay =3D %d\n",
-	    E1000_READ_REG(&adapter->hw, E1000_RDTR),
-	    E1000_READ_REG(&adapter->hw, E1000_RADV));
+	struct sysctl_ctx_list *ctx =3D device_get_sysctl_ctx(dev);
+	struct sysctl_oid *tree =3D device_get_sysctl_tree(dev);
+	struct sysctl_oid_list *child =3D SYSCTL_CHILDREN(tree);
+	struct e1000_hw_stats *stats =3D &adapter->stats;
+
+	struct sysctl_oid *stat_node, *int_node, *host_node;
+	struct sysctl_oid_list *stat_list, *int_list, *host_list;
+
+	/* Driver Statistics */
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "link_irq",=20
+			CTLFLAG_RD, &adapter->link_irq, 0,
+			"Link MSIX IRQ Handled");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_alloc_fail",=20
+			 CTLFLAG_RD, &adapter->mbuf_alloc_failed,
+			 "Std mbuf failed");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "cluster_alloc_fail",=20
+			 CTLFLAG_RD, &adapter->mbuf_cluster_failed,
+			 "Std mbuf cluster failed");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped",=20
+			CTLFLAG_RD, &adapter->dropped_pkts,
+			"Driver dropped packets");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_dma_fail",=20
+			CTLFLAG_RD, &adapter->no_tx_dma_setup,
+			"Driver tx dma failure in xmit");
+
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_high_water",
+			CTLFLAG_RD, &adapter->hw.fc.high_water, 0,
+			"Flow Control High Watermark");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_low_water",=20
+			CTLFLAG_RD, &adapter->hw.fc.low_water, 0,
+			"Flow Control Low Watermark");
+
+	/* MAC stats get the own sub node */
+
+	stat_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac_stats",=20
+				    CTLFLAG_RD, NULL, "Statistics");
+	stat_list =3D SYSCTL_CHILDREN(stat_node);
+
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "excess_coll",=20
+			CTLFLAG_RD, &stats->ecol,
+			"Excessive collisions");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "symbol_errors",
+			CTLFLAG_RD, &adapter->stats.symerrs,
+			"Symbol Errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "sequence_errors",
+			CTLFLAG_RD, &adapter->stats.sec,
+			"Sequence Errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "defer_count",
+			CTLFLAG_RD, &adapter->stats.dc,
+			"Defer Count");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "missed_packets",
+			CTLFLAG_RD, &adapter->stats.mpc,
+			"Missed Packets");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_no_buff",
+			CTLFLAG_RD, &adapter->stats.rnbc,
+			"Receive No Buffers");
+	/* RLEC is inaccurate on some hardware, calculate our own. */
+/* 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_len_errs", */
+/* 			CTLFLAG_RD, adapter->stats.roc + adapter->stats.ruc, */
+/* 			"Receive Length Errors"); */
+
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_errs",
+			CTLFLAG_RD, &adapter->stats.rxerrc,
+			"Receive Errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "crc_errs",
+			CTLFLAG_RD, &adapter->stats.crcerrs,
+			"CRC errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "alignment_errs",
+			CTLFLAG_RD, &adapter->stats.algnerrc,
+			"Alignment Errors");
+	/* On 82575 these are collision counts */
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "coll_ext_errs",
+			CTLFLAG_RD, &adapter->stats.cexterr,
+			"Collision/Carrier extension errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_overruns",
+			CTLFLAG_RD, &adapter->rx_overruns,
+			"RX overruns");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "watchdog_timeouts",
+			CTLFLAG_RD, &adapter->watchdog_events,
+			"Watchdog timeouts");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xon_recvd",
+			CTLFLAG_RD, &adapter->stats.xonrxc,
+			"XON Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xon_txd",
+			CTLFLAG_RD, &adapter->stats.xontxc,
+			"XON Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xoff_recvd",
+			CTLFLAG_RD, &adapter->stats.xoffrxc,
+			"XOFF Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xoff_txd",
+			CTLFLAG_RD, &adapter->stats.xofftxc,
+			"XOFF Transmitted");
+
+	/* Packet Reception Stats */
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_recvd",
+			CTLFLAG_RD, &adapter->stats.tpr,
+			"Total Packets Received ");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
+			CTLFLAG_RD, &adapter->stats.gprc,
+			"Good Packets Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_recvd",
+			CTLFLAG_RD, &adapter->stats.bprc,
+			"Broadcast Packets Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_recvd",
+			CTLFLAG_RD, &adapter->stats.mprc,
+			"Multicast Packets Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_64",
+			CTLFLAG_RD, &adapter->stats.prc64,
+			"64 byte frames received ");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127",
+			CTLFLAG_RD, &adapter->stats.prc127,
+			"65-127 byte frames received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_128_255",
+			CTLFLAG_RD, &adapter->stats.prc255,
+			"128-255 byte frames received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_256_511",
+			CTLFLAG_RD, &adapter->stats.prc511,
+			"256-511 byte frames received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_512_1023",
+			CTLFLAG_RD, &adapter->stats.prc1023,
+			"512-1023 byte frames received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_1024_1522",
+			CTLFLAG_RD, &adapter->stats.prc1522,
+			"1023-1522 byte frames received");
+ 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd",=20
+ 			CTLFLAG_RD, &adapter->stats.gorc,=20
+ 			"Good Octets Received");=20
+
+	/* Packet Transmission Stats */
+ 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octest_txd",=20
+ 			CTLFLAG_RD, &adapter->stats.gotc,=20
+ 			"Good Octest Transmitted");=20
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd",
+			CTLFLAG_RD, &adapter->stats.tpt,
+			"Total Packets Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
+			CTLFLAG_RD, &adapter->stats.gptc,
+			"Good Packets Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd",
+			CTLFLAG_RD, &adapter->stats.bptc,
+			"Broadcast Packets Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd",
+			CTLFLAG_RD, &adapter->stats.mptc,
+			"Multicast Packets Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_64",
+			CTLFLAG_RD, &adapter->stats.ptc64,
+			"64 byte frames transmitted ");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127",
+			CTLFLAG_RD, &adapter->stats.ptc127,
+			"65-127 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_128_255",
+			CTLFLAG_RD, &adapter->stats.ptc255,
+			"128-255 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_256_511",
+			CTLFLAG_RD, &adapter->stats.ptc511,
+			"256-511 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_512_1023",
+			CTLFLAG_RD, &adapter->stats.ptc1023,
+			"512-1023 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522",
+			CTLFLAG_RD, &adapter->stats.ptc1522,
+			"1024-1522 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tso_txd",
+			CTLFLAG_RD, &adapter->stats.tsctc,
+			"TSO Contexts Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tso_ctx_fail",
+			CTLFLAG_RD, &adapter->stats.tsctfc,
+			"TSO Contexts Failed");
+
+
+	/* Interrupt Stats */
+
+	int_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "interrupts",=20
+				    CTLFLAG_RD, NULL, "Interrupt Statistics");
+	int_list =3D SYSCTL_CHILDREN(int_node);
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "asserts",
+			CTLFLAG_RD, &adapter->stats.iac,
+			"Interrupt Assertion Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_pkt_timer",
+			CTLFLAG_RD, &adapter->stats.icrxptc,
+			"Interrupt Cause Rx Pkt Timer Expire Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_abs_timer",
+			CTLFLAG_RD, &adapter->stats.icrxatc,
+			"Interrupt Cause Rx Abs Timer Expire Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_pkt_timer",
+			CTLFLAG_RD, &adapter->stats.ictxptc,
+			"Interrupt Cause Tx Pkt Timer Expire Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_abs_timer",
+			CTLFLAG_RD, &adapter->stats.ictxatc,
+			"Interrupt Cause Tx Abs Timer Expire Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_queue_empty",
+			CTLFLAG_RD, &adapter->stats.ictxqec,
+			"Interrupt Cause Tx Queue Empty Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_queue_min_thresh",
+			CTLFLAG_RD, &adapter->stats.ictxqmtc,
+			"Interrupt Cause Tx Queue Min Thresh Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_desc_min_thresh",
+			CTLFLAG_RD, &adapter->stats.icrxdmtc,
+			"Interrupt Cause Rx Desc Min Thresh Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_overrun",
+			CTLFLAG_RD, &adapter->stats.icrxoc,
+			"Interrupt Cause Receiver Overrun Count");
+
+	/* Host to Card Stats */
+
+	host_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "host",=20
+				    CTLFLAG_RD, NULL,=20
+				    "Host to Card Statistics");
+
+	host_list =3D SYSCTL_CHILDREN(host_node);
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_tx_pkt",
+			CTLFLAG_RD, &adapter->stats.cbtmpc,
+			"Circuit Breaker Tx Packet Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "host_tx_pkt_discard",
+			CTLFLAG_RD, &adapter->stats.htdpmc,
+			"Host Transmit Discarded Packets");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "rx_pkt",
+			CTLFLAG_RD, &adapter->stats.rpthc,
+			"Rx Packets To Host");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_rx_pkts",
+			CTLFLAG_RD, &adapter->stats.cbrmpc,
+			"Circuit Breaker Rx Packet Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_rx_pkt_drop",
+			CTLFLAG_RD, &adapter->stats.cbrdpc,
+			"Circuit Breaker Rx Dropped Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "tx_good_pkt",
+			CTLFLAG_RD, &adapter->stats.hgptc,
+			"Host Good Packets Tx Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_tx_pkt_drop",
+			CTLFLAG_RD, &adapter->stats.htcbdpc,
+			"Host Tx Circuit Breaker Dropped Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "rx_good_bytes",
+			CTLFLAG_RD, &adapter->stats.hgorc,
+			"Host Good Octets Received Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "tx_good_bytes",
+			CTLFLAG_RD, &adapter->stats.hgotc,
+			"Host Good Octets Transmit Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "length_errors",
+			CTLFLAG_RD, &adapter->stats.lenerrs,
+			"Length Errors");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "serdes_violation_pkt",
+			CTLFLAG_RD, &adapter->stats.scvpc,
+			"SerDes/SGMII Code Violation Pkt Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "header_redir_missed",
+			CTLFLAG_RD, &adapter->stats.hrmpc,
+			"Header Redirection Missed Packet Count");
=20
-	for (int i =3D 0; i < adapter->num_queues; i++, txr++) {
-		device_printf(dev, "Queue(%d) tdh =3D %d, tdt =3D %d\n", i,
-		    E1000_READ_REG(&adapter->hw, E1000_TDH(i)),
-		    E1000_READ_REG(&adapter->hw, E1000_TDT(i)));
-		device_printf(dev, "TX(%d) no descriptors avail event =3D %ld\n",
-		    txr->me, txr->no_desc_avail);
-		device_printf(dev, "TX(%d) MSIX IRQ Handled =3D %ld\n",
-		    txr->me, txr->tx_irq);
-		device_printf(dev, "Num Tx descriptors avail =3D %d\n",
-		    txr->tx_avail);
-		device_printf(dev, "Tx Descriptors not avail1 =3D %ld\n",
-		    txr->no_desc_avail);
-	}
-	for (int i =3D 0; i < adapter->num_queues; i++, rxr++) {
-		device_printf(dev, "RX(%d) MSIX IRQ Handled =3D %ld\n",
-		    rxr->me, rxr->rx_irq);
-		device_printf(dev, "hw rdh =3D %d, hw rdt =3D %d\n",
-		    E1000_READ_REG(&adapter->hw, E1000_RDH(i)),
-		    E1000_READ_REG(&adapter->hw, E1000_RDT(i)));
-	}
-	device_printf(dev, "Std mbuf failed =3D %ld\n",
-	    adapter->mbuf_alloc_failed);
-	device_printf(dev, "Std mbuf cluster failed =3D %ld\n",
-	    adapter->mbuf_cluster_failed);
-	device_printf(dev, "Driver dropped packets =3D %ld\n",
-	    adapter->dropped_pkts);
-}
=20
-static void
-em_print_hw_stats(struct adapter *adapter)
-{
-	device_t dev =3D adapter->dev;
=20
-	device_printf(dev, "Excessive collisions =3D %lld\n",
-	    (long long)adapter->stats.ecol);
-#if	(DEBUG_HW > 0)  /* Dont output these errors normally */
-	device_printf(dev, "Symbol errors =3D %lld\n",
-	    (long long)adapter->stats.symerrs);
-#endif
-	device_printf(dev, "Sequence errors =3D %lld\n",
-	    (long long)adapter->stats.sec);
-	device_printf(dev, "Defer count =3D %lld\n",
-	    (long long)adapter->stats.dc);
-	device_printf(dev, "Missed Packets =3D %lld\n",
-	    (long long)adapter->stats.mpc);
-	device_printf(dev, "Receive No Buffers =3D %lld\n",
-	    (long long)adapter->stats.rnbc);
-	/* RLEC is inaccurate on some hardware, calculate our own. */
-	device_printf(dev, "Receive Length Errors =3D %lld\n",
-	    ((long long)adapter->stats.roc + (long long)adapter->stats.ruc));
-	device_printf(dev, "Receive errors =3D %lld\n",
-	    (long long)adapter->stats.rxerrc);
-	device_printf(dev, "Crc errors =3D %lld\n",
-	    (long long)adapter->stats.crcerrs);
-	device_printf(dev, "Alignment errors =3D %lld\n",
-	    (long long)adapter->stats.algnerrc);
-	device_printf(dev, "Collision/Carrier extension errors =3D %lld\n",
-	    (long long)adapter->stats.cexterr);
-	device_printf(dev, "watchdog timeouts =3D %ld\n",
-	    adapter->watchdog_events);
-	device_printf(dev, "XON Rcvd =3D %lld\n",
-	    (long long)adapter->stats.xonrxc);
-	device_printf(dev, "XON Xmtd =3D %lld\n",
-	    (long long)adapter->stats.xontxc);
-	device_printf(dev, "XOFF Rcvd =3D %lld\n",
-	    (long long)adapter->stats.xoffrxc);
-	device_printf(dev, "XOFF Xmtd =3D %lld\n",
-	    (long long)adapter->stats.xofftxc);
-	device_printf(dev, "Good Packets Rcvd =3D %lld\n",
-	    (long long)adapter->stats.gprc);
-	device_printf(dev, "Good Packets Xmtd =3D %lld\n",
-	    (long long)adapter->stats.gptc);
-	device_printf(dev, "TSO Contexts Xmtd =3D %lld\n",
-	    (long long)adapter->stats.tsctc);
-	device_printf(dev, "TSO Contexts Failed =3D %lld\n",
-	    (long long)adapter->stats.tsctfc);
 }
=20
 /**********************************************************************
@@ -4986,28 +5155,9 @@
  *  32 words, stuff that matters is in that extent.
  *
  **********************************************************************/=

-static void
-em_print_nvm_info(struct adapter *adapter)
-{
-	u16	eeprom_data;
-	int	i, j, row =3D 0;
-
-	/* Its a bit crude, but it gets the job done */
-	printf("\nInterface EEPROM Dump:\n");
-	printf("Offset\n0x0000  ");
-	for (i =3D 0, j =3D 0; i < 32; i++, j++) {
-		if (j =3D=3D 8) { /* Make the offset block */
-			j =3D 0; ++row;
-			printf("\n0x00%x0  ",row);
-		}
-		e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data);
-		printf("%04x ", eeprom_data);
-	}
-	printf("\n");
-}
=20
 static int
-em_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
+em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS)
 {
 	struct adapter *adapter;
 	int error;
@@ -5019,16 +5169,12 @@
 	if (error || !req->newptr)
 		return (error);
=20
-	if (result =3D=3D 1) {
-		adapter =3D (struct adapter *)arg1;
-		em_print_debug_info(adapter);
-	}
 	/*
 	 * This value will cause a hex dump of the
 	 * first 32 16-bit words of the EEPROM to
 	 * the screen.
 	 */
-	if (result =3D=3D 2) {
+	if (result =3D=3D 1) {
 		adapter =3D (struct adapter *)arg1;
 		em_print_nvm_info(adapter);
         }
@@ -5036,26 +5182,24 @@
 	return (error);
 }
=20
-
-static int
-em_sysctl_stats(SYSCTL_HANDLER_ARGS)
+static void
+em_print_nvm_info(struct adapter *adapter)
 {
-	struct adapter *adapter;
-	int error;
-	int result;
-
-	result =3D -1;
-	error =3D sysctl_handle_int(oidp, &result, 0, req);
-
-	if (error || !req->newptr)
-		return (error);
+	u16	eeprom_data;
+	int	i, j, row =3D 0;
=20
-	if (result =3D=3D 1) {
-		adapter =3D (struct adapter *)arg1;
-		em_print_hw_stats(adapter);
+	/* Its a bit crude, but it gets the job done */
+	printf("\nInterface EEPROM Dump:\n");
+	printf("Offset\n0x0000  ");
+	for (i =3D 0, j =3D 0; i < 32; i++, j++) {
+		if (j =3D=3D 8) { /* Make the offset block */
+			j =3D 0; ++row;
+			printf("\n0x00%x0  ",row);
+		}
+		e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data);
+		printf("%04x ", eeprom_data);
 	}
-
-	return (error);
+	printf("\n");
 }
=20
 static int
--- src/sys/dev/e1000/if_igb.c.orig	2010-06-14 04:09:06.000000000 +0200
+++ src/sys/dev/e1000/if_igb.c	2010-07-27 10:06:53.833945364 +0200
@@ -30,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
=20
 ************************************************************************=
******/
-/*$FreeBSD: src/sys/dev/e1000/if_igb.c,v 1.21.2.8.2.1 2010/06/14 02:09:0=
6 kensmith Exp $*/
+/*$FreeBSD: src/sys/dev/e1000/if_igb.c,v 1.21.2.9 2010/06/18 17:22:08 jf=
v Exp $*/
=20
=20
 #ifdef HAVE_KERNEL_OPTION_HEADERS
@@ -99,7 +99,7 @@
 /*********************************************************************
  *  Driver version:
  *********************************************************************/
-char igb_driver_version[] =3D "version - 1.9.5";
+char igb_driver_version[] =3D "version - 1.9.6";
=20
=20
 /*********************************************************************
@@ -205,14 +205,13 @@
 static __inline void igb_rx_input(struct rx_ring *,
 		    struct ifnet *, struct mbuf *, u32);
=20
-static bool	igb_rxeof(struct igb_queue *, int);
+static bool	igb_rxeof(struct igb_queue *, int, int *);
 static void	igb_rx_checksum(u32, struct mbuf *, u32);
 static int	igb_tx_ctx_setup(struct tx_ring *, struct mbuf *);
 static bool	igb_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
 static void	igb_set_promisc(struct adapter *);
 static void	igb_disable_promisc(struct adapter *);
 static void	igb_set_multi(struct adapter *);
-static void	igb_print_hw_stats(struct adapter *);
 static void	igb_update_link_status(struct adapter *);
 static void	igb_refresh_mbufs(struct rx_ring *, int);
=20
@@ -224,11 +223,10 @@
 static int	igb_dma_malloc(struct adapter *, bus_size_t,
 		    struct igb_dma_alloc *, int);
 static void	igb_dma_free(struct adapter *, struct igb_dma_alloc *);
-static void	igb_print_debug_info(struct adapter *);
+static int	igb_sysctl_nvm_info(SYSCTL_HANDLER_ARGS);
 static void	igb_print_nvm_info(struct adapter *);
 static int 	igb_is_valid_ether_addr(u8 *);
-static int	igb_sysctl_stats(SYSCTL_HANDLER_ARGS);
-static int	igb_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
+static void     igb_add_hw_stats(struct adapter *adapter);
 /* Management and WOL Support */
 static void	igb_init_manageability(struct adapter *);
 static void	igb_release_manageability(struct adapter *);
@@ -240,7 +238,6 @@
 static int	igb_irq_fast(void *);
 static void	igb_add_rx_process_limit(struct adapter *, const char *,
 		    const char *, int *, int);
-static void	igb_handle_rxtx(void *context, int pending);
 static void	igb_handle_que(void *context, int pending);
 static void	igb_handle_link(void *context, int pending);
=20
@@ -412,13 +409,8 @@
 	/* SYSCTL stuff */
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-	    OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
-	    igb_sysctl_debug_info, "I", "Debug Information");
-
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-	    OID_AUTO, "stats", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
-	    igb_sysctl_stats, "I", "Statistics");
+	    OID_AUTO, "nvm", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
+	    igb_sysctl_nvm_info, "I", "NVM Information");
=20
 	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
@@ -584,6 +576,8 @@
 	adapter->vlan_detach =3D EVENTHANDLER_REGISTER(vlan_unconfig,
 	     igb_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
=20
+	igb_add_hw_stats(adapter);
+
 	/* Tell the stack that the interface is not active */
 	adapter->ifp->if_drv_flags &=3D ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
=20
@@ -818,21 +812,25 @@
 static int
 igb_mq_start(struct ifnet *ifp, struct mbuf *m)
 {
-	struct adapter	*adapter =3D ifp->if_softc;
-	struct tx_ring	*txr;
-	int 		i =3D 0, err =3D 0;
+	struct adapter		*adapter =3D ifp->if_softc;
+	struct igb_queue	*que;
+	struct tx_ring		*txr;
+	int 			i =3D 0, err =3D 0;
=20
 	/* Which queue to use */
 	if ((m->m_flags & M_FLOWID) !=3D 0)
 		i =3D m->m_pkthdr.flowid % adapter->num_queues;
=20
 	txr =3D &adapter->tx_rings[i];
+	que =3D &adapter->queues[i];
=20
 	if (IGB_TX_TRYLOCK(txr)) {
 		err =3D igb_mq_start_locked(ifp, txr, m);
 		IGB_TX_UNLOCK(txr);
-	} else
+	} else {
 		err =3D drbr_enqueue(ifp, txr->br, m);
+		taskqueue_enqueue(que->tq, &que->que_task);
+	}
=20
 	return (err);
 }
@@ -1225,50 +1223,24 @@
=20
=20
 static void
-igb_handle_rxtx(void *context, int pending)
-{
-	struct igb_queue	*que =3D context;
-	struct adapter		*adapter =3D que->adapter;
-	struct tx_ring		*txr =3D adapter->tx_rings;
-	struct ifnet		*ifp;
-
-	ifp =3D adapter->ifp;
-
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		if (igb_rxeof(que, adapter->rx_process_limit))
-			taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
-		IGB_TX_LOCK(txr);
-		igb_txeof(txr);
-
-#if __FreeBSD_version >=3D 800000
-		if (!drbr_empty(ifp, txr->br))
-			igb_mq_start_locked(ifp, txr, NULL);
-#else
-		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			igb_start_locked(txr, ifp);
-#endif
-		IGB_TX_UNLOCK(txr);
-	}
-
-	igb_enable_intr(adapter);
-}
-
-static void
 igb_handle_que(void *context, int pending)
 {
 	struct igb_queue *que =3D context;
 	struct adapter *adapter =3D que->adapter;
 	struct tx_ring *txr =3D que->txr;
 	struct ifnet	*ifp =3D adapter->ifp;
-	bool		more;
=20
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		more =3D igb_rxeof(que, -1);
+		bool	more;
+
+		more =3D igb_rxeof(que, -1, NULL);
=20
 		IGB_TX_LOCK(txr);
-		igb_txeof(txr);
+		if (igb_txeof(txr))
+			more =3D TRUE;
 #if __FreeBSD_version >=3D 800000
-		igb_mq_start_locked(ifp, txr, NULL);
+		if (!drbr_empty(ifp, txr->br))
+			igb_mq_start_locked(ifp, txr, NULL);
 #else
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 			igb_start_locked(txr, ifp);
@@ -1280,11 +1252,15 @@
 		}
 	}
=20
-	/* Reenable this interrupt */
 #ifdef DEVICE_POLLING
-	if (!(ifp->if_capenable & IFCAP_POLLING))
+	if (ifp->if_capenable & IFCAP_POLLING)
+		return;
 #endif
-	E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims);
+	/* Reenable this interrupt */
+	if (que->eims)
+		E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims);
+	else
+		igb_enable_intr(adapter);
 }
=20
 /* Deal with link in a sleepable context */
@@ -1306,8 +1282,9 @@
 static int
 igb_irq_fast(void *arg)
 {
-	struct adapter	*adapter =3D arg;
-	uint32_t	reg_icr;
+	struct adapter		*adapter =3D arg;
+	struct igb_queue	*que =3D adapter->queues;
+	u32			reg_icr;
=20
=20
 	reg_icr =3D E1000_READ_REG(&adapter->hw, E1000_ICR);
@@ -1329,11 +1306,11 @@
 	 * MSI message reordering errata on certain systems.
 	 */
 	igb_disable_intr(adapter);
-	taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
+	taskqueue_enqueue(que->tq, &que->que_task);
=20
 	/* Link status change */
 	if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))
-		taskqueue_enqueue(adapter->tq, &adapter->link_task);
+		taskqueue_enqueue(que->tq, &adapter->link_task);
=20
 	if (reg_icr & E1000_ICR_RXO)
 		adapter->rx_overruns++;
@@ -1373,15 +1350,14 @@
 		reg_icr =3D E1000_READ_REG(&adapter->hw, E1000_ICR);
 		/* Link status change */
 		if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))
-			taskqueue_enqueue(adapter->tq, &adapter->link_task);
+			igb_handle_link(adapter, 0);
=20
 		if (reg_icr & E1000_ICR_RXO)
 			adapter->rx_overruns++;
 	}
 	IGB_CORE_UNLOCK(adapter);
=20
-	/* TODO: rx_count */
-	rx_done =3D igb_rxeof(que, count) ? 1 : 0;
+	igb_rxeof(que, count, &rx_done);
=20
 	IGB_TX_LOCK(txr);
 	do {
@@ -1421,7 +1397,7 @@
 	more_tx =3D igb_txeof(txr);
 	IGB_TX_UNLOCK(txr);
=20
-	more_rx =3D igb_rxeof(que, adapter->rx_process_limit);
+	more_rx =3D igb_rxeof(que, adapter->rx_process_limit, NULL);
=20
 	if (igb_enable_aim =3D=3D FALSE)
 		goto no_calc;
@@ -1501,7 +1477,7 @@
 	icr =3D E1000_READ_REG(&adapter->hw, E1000_ICR);
 	if (!(icr & E1000_ICR_LSC))
 		goto spurious;
-	taskqueue_enqueue(adapter->tq, &adapter->link_task);
+	igb_handle_link(adapter, 0);
=20
 spurious:
 	/* Rearm */
@@ -1900,7 +1876,6 @@
 igb_local_timer(void *arg)
 {
 	struct adapter		*adapter =3D arg;
-	struct ifnet		*ifp =3D adapter->ifp;
 	device_t		dev =3D adapter->dev;
 	struct tx_ring		*txr =3D adapter->tx_rings;
=20
@@ -1910,9 +1885,6 @@
 	igb_update_link_status(adapter);
 	igb_update_stats_counters(adapter);
=20
-	if (igb_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING)
-		igb_print_hw_stats(adapter);
-
         /*
         ** Watchdog: check for time since any descriptor was cleaned
         */
@@ -1923,11 +1895,6 @@
 			goto timeout;
 	}
=20
-	/* Trigger an RX interrupt on all queues */
-#ifdef DEVICE_POLLING
-	if (!(ifp->if_capenable & IFCAP_POLLING))
-#endif
-	E1000_WRITE_REG(&adapter->hw, E1000_EICS, adapter->rx_mask);
 	callout_reset(&adapter->timer, hz, igb_local_timer, adapter);
 	return;
=20
@@ -2142,20 +2109,20 @@
 	 * Try allocating a fast interrupt and the associated deferred
 	 * processing contexts.
 	 */
-	TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, que);
+	TASK_INIT(&que->que_task, 0, igb_handle_que, que);
 	/* Make tasklet for deferred link handling */
 	TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter);
-	adapter->tq =3D taskqueue_create_fast("igb_taskq", M_NOWAIT,
-	    taskqueue_thread_enqueue, &adapter->tq);
-	taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq",
+	que->tq =3D taskqueue_create_fast("igb_taskq", M_NOWAIT,
+	    taskqueue_thread_enqueue, &que->tq);
+	taskqueue_start_threads(&que->tq, 1, PI_NET, "%s taskq",
 	    device_get_nameunit(adapter->dev));
 	if ((error =3D bus_setup_intr(dev, adapter->res,
 	    INTR_TYPE_NET | INTR_MPSAFE, igb_irq_fast, NULL,
 	    adapter, &adapter->tag)) !=3D 0) {
 		device_printf(dev, "Failed to register fast interrupt "
 			    "handler: %d\n", error);
-		taskqueue_free(adapter->tq);
-		adapter->tq =3D NULL;
+		taskqueue_free(que->tq);
+		que->tq =3D NULL;
 		return (error);
 	}
=20
@@ -2194,6 +2161,9 @@
 			device_printf(dev, "Failed to register Queue handler");
 			return (error);
 		}
+#if __FreeBSD_version >=3D 800504
+		bus_describe_intr(dev, que->res, que->tag, "que %d", i);
+#endif
 		que->msix =3D vector;
 		if (adapter->hw.mac.type =3D=3D e1000_82575)
 			que->eims =3D E1000_EICR_TX_QUEUE0 << i;
@@ -2229,15 +2199,11 @@
 		device_printf(dev, "Failed to register Link handler");
 		return (error);
 	}
+#if __FreeBSD_version >=3D 800504
+	bus_describe_intr(dev, adapter->res, adapter->tag, "link");
+#endif
 	adapter->linkvec =3D vector;
=20
-	/* Make tasklet for deferred handling */
-	TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter);
-	adapter->tq =3D taskqueue_create_fast("igb_link", M_NOWAIT,
-	    taskqueue_thread_enqueue, &adapter->tq);
-	taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s link",
-	    device_get_nameunit(adapter->dev));
-
 	return (0);
 }
=20
@@ -3570,7 +3536,7 @@
 	cleaned =3D -1; /* Signify no completions */
 	while (i !=3D limit) {
 		rxbuf =3D &rxr->rx_buffers[i];
-		if (rxbuf->m_head =3D=3D NULL) {
+		if ((rxbuf->m_head =3D=3D NULL) && (rxr->hdr_split)) {
 			mh =3D m_gethdr(M_DONTWAIT, MT_DATA);
 			if (mh =3D=3D NULL)
 				goto update;
@@ -3776,16 +3742,24 @@
 	*/
 	igb_free_receive_ring(rxr);
=20
+	/* Configure for header split? */
+	if (igb_header_split)
+		rxr->hdr_split =3D TRUE;
+
         /* Now replenish the ring mbufs */
 	for (int j =3D 0; j !=3D adapter->num_rx_desc; ++j) {
 		struct mbuf	*mh, *mp;
=20
 		rxbuf =3D &rxr->rx_buffers[j];
+		if (rxr->hdr_split =3D=3D FALSE)
+			goto skip_head;
=20
 		/* First the header */
 		rxbuf->m_head =3D m_gethdr(M_DONTWAIT, MT_DATA);
-		if (rxbuf->m_head =3D=3D NULL)
+		if (rxbuf->m_head =3D=3D NULL) {
+			error =3D ENOBUFS;
                         goto fail;
+		}
 		m_adj(rxbuf->m_head, ETHER_ALIGN);
 		mh =3D rxbuf->m_head;
 		mh->m_len =3D mh->m_pkthdr.len =3D MHLEN;
@@ -3801,11 +3775,14 @@
 		/* Update descriptor */
 		rxr->rx_base[j].read.hdr_addr =3D htole64(hseg[0].ds_addr);
=20
+skip_head:
 		/* Now the payload cluster */
 		rxbuf->m_pack =3D m_getjcl(M_DONTWAIT, MT_DATA,
 		    M_PKTHDR, adapter->rx_mbuf_sz);
-		if (rxbuf->m_pack =3D=3D NULL)
+		if (rxbuf->m_pack =3D=3D NULL) {
+			error =3D ENOBUFS;
                         goto fail;
+		}
 		mp =3D rxbuf->m_pack;
 		mp->m_pkthdr.len =3D mp->m_len =3D adapter->rx_mbuf_sz;
 		/* Get the memory mapping */
@@ -3824,11 +3801,8 @@
 	rxr->next_to_check =3D 0;
 	rxr->next_to_refresh =3D 0;
 	rxr->lro_enabled =3D FALSE;
-
-	if (igb_header_split)
-		rxr->hdr_split =3D TRUE;
-	else
-		ifp->if_capabilities &=3D ~IFCAP_LRO;
+	rxr->rx_split_packets =3D 0;
+	rxr->rx_bytes =3D 0;
=20
 	rxr->fmp =3D NULL;
 	rxr->lmp =3D NULL;
@@ -3872,7 +3846,7 @@
 igb_setup_receive_structures(struct adapter *adapter)
 {
 	struct rx_ring *rxr =3D adapter->rx_rings;
-	int i, j;
+	int i;
=20
 	for (i =3D 0; i < adapter->num_queues; i++, rxr++)
 		if (igb_setup_receive_ring(rxr))
@@ -3883,13 +3857,11 @@
 	/*
 	 * Free RX buffers allocated so far, we will only handle
 	 * the rings that completed, the failing case will have
-	 * cleaned up for itself. The value of 'i' will be the
-	 * failed ring so we must pre-decrement it.
+	 * cleaned up for itself. 'i' is the endpoint.
 	 */
-	rxr =3D adapter->rx_rings;
-	for (--i; i > 0; i--, rxr++) {
-		for (j =3D 0; j < adapter->num_rx_desc; j++)
-			igb_free_receive_ring(rxr);
+	for (int j =3D 0; j > i; ++j) {
+		rxr =3D &adapter->rx_rings[i];
+		igb_free_receive_ring(rxr);
 	}
=20
 	return (ENOBUFS);
@@ -4195,7 +4167,9 @@
 			if (tcp_lro_rx(&rxr->lro, m, 0) =3D=3D 0)
 				return;
 	}
+	IGB_RX_UNLOCK(rxr);
 	(*ifp->if_input)(ifp, m);
+	IGB_RX_LOCK(rxr);
 }
=20
 /*********************************************************************
@@ -4210,14 +4184,14 @@
  *  Return TRUE if more to clean, FALSE otherwise
  *********************************************************************/
 static bool
-igb_rxeof(struct igb_queue *que, int count)
+igb_rxeof(struct igb_queue *que, int count, int *done)
 {
 	struct adapter		*adapter =3D que->adapter;
 	struct rx_ring		*rxr =3D que->rxr;
 	struct ifnet		*ifp =3D adapter->ifp;
 	struct lro_ctrl		*lro =3D &rxr->lro;
 	struct lro_entry	*queued;
-	int			i, processed =3D 0;
+	int			i, processed =3D 0, rxdone =3D 0;
 	u32			ptype, staterr =3D 0;
 	union e1000_adv_rx_desc	*cur;
=20
@@ -4366,8 +4340,12 @@
 		/*
 		** Send to the stack or LRO
 		*/
-		if (sendmp !=3D NULL)
+		if (sendmp !=3D NULL) {
+			rxr->next_to_check =3D i;
 			igb_rx_input(rxr, ifp, sendmp, ptype);
+			i =3D rxr->next_to_check;
+			rxdone++;
+		}
=20
 		/* Every 8 descriptors we go to refresh mbufs */
 		if (processed =3D=3D 8) {
@@ -4394,6 +4372,9 @@
=20
 	IGB_RX_UNLOCK(rxr);
=20
+	if (done !=3D NULL)
+		*done =3D rxdone;
+
 	/*
 	** We still have cleaning to do?
 	** Schedule another interrupt if so.
@@ -4751,8 +4732,10 @@
 	/* For the 64-bit byte counters the low dword must be read first. */
 	/* Both registers clear on the read of the high dword */
=20
-	adapter->stats.gorc +=3D E1000_READ_REG(&adapter->hw, E1000_GORCH);
-	adapter->stats.gotc +=3D E1000_READ_REG(&adapter->hw, E1000_GOTCH);
+	adapter->stats.gorc +=3D E1000_READ_REG(&adapter->hw, E1000_GORCL) +
+	  ((u64)E1000_READ_REG(&adapter->hw, E1000_GORCH) << 32);
+	adapter->stats.gotc +=3D E1000_READ_REG(&adapter->hw, E1000_GOTCL) +
+	  ((u64)E1000_READ_REG(&adapter->hw, E1000_GOTCH) << 32) ;
=20
 	adapter->stats.rnbc +=3D E1000_READ_REG(&adapter->hw, E1000_RNBC);
 	adapter->stats.ruc +=3D E1000_READ_REG(&adapter->hw, E1000_RUC);
@@ -4774,6 +4757,38 @@
 	adapter->stats.mptc +=3D E1000_READ_REG(&adapter->hw, E1000_MPTC);
 	adapter->stats.bptc +=3D E1000_READ_REG(&adapter->hw, E1000_BPTC);
=20
+	/* Interrupt Counts */
+
+	adapter->stats.iac +=3D E1000_READ_REG(&adapter->hw, E1000_IAC);
+	adapter->stats.icrxptc +=3D E1000_READ_REG(&adapter->hw, E1000_ICRXPTC)=
;
+	adapter->stats.icrxatc +=3D E1000_READ_REG(&adapter->hw, E1000_ICRXATC)=
;
+	adapter->stats.ictxptc +=3D E1000_READ_REG(&adapter->hw, E1000_ICTXPTC)=
;
+	adapter->stats.ictxatc +=3D E1000_READ_REG(&adapter->hw, E1000_ICTXATC)=
;
+	adapter->stats.ictxqec +=3D E1000_READ_REG(&adapter->hw, E1000_ICTXQEC)=
;
+	adapter->stats.ictxqmtc +=3D E1000_READ_REG(&adapter->hw, E1000_ICTXQMT=
C);
+	adapter->stats.icrxdmtc +=3D E1000_READ_REG(&adapter->hw, E1000_ICRXDMT=
C);
+	adapter->stats.icrxoc +=3D E1000_READ_REG(&adapter->hw, E1000_ICRXOC);
+
+	/* Host to Card Statistics */
+
+	adapter->stats.cbtmpc +=3D E1000_READ_REG(&adapter->hw, E1000_CBTMPC);
+	adapter->stats.htdpmc +=3D E1000_READ_REG(&adapter->hw, E1000_HTDPMC);
+	adapter->stats.cbrdpc +=3D E1000_READ_REG(&adapter->hw, E1000_CBRDPC);
+	adapter->stats.cbrmpc +=3D E1000_READ_REG(&adapter->hw, E1000_CBRMPC);
+	adapter->stats.rpthc +=3D E1000_READ_REG(&adapter->hw, E1000_RPTHC);
+	adapter->stats.hgptc +=3D E1000_READ_REG(&adapter->hw, E1000_HGPTC);
+	adapter->stats.htcbdpc +=3D E1000_READ_REG(&adapter->hw, E1000_HTCBDPC)=
;
+	adapter->stats.hgorc +=3D (E1000_READ_REG(&adapter->hw, E1000_HGORCL) +=

+				 ((u64)E1000_READ_REG(&adapter->hw,=20
+						      E1000_HGORCH) << 32));
+
+	adapter->stats.hgotc +=3D (E1000_READ_REG(&adapter->hw, E1000_HGOTCL) +=

+				 ((u64)E1000_READ_REG(&adapter->hw,=20
+						      E1000_HGOTCH) << 32));
+	adapter->stats.lenerrs +=3D E1000_READ_REG(&adapter->hw, E1000_LENERRS)=
;
+	adapter->stats.scvpc +=3D E1000_READ_REG(&adapter->hw, E1000_SCVPC);
+	adapter->stats.hrmpc +=3D E1000_READ_REG(&adapter->hw, E1000_HRMPC);
+
 	adapter->stats.algnerrc +=3D=20
 		E1000_READ_REG(&adapter->hw, E1000_ALGNERRC);
 	adapter->stats.rxerrc +=3D=20
@@ -4802,140 +4817,375 @@
 }
=20
=20
-/**********************************************************************
- *
- *  This routine is called only when igb_display_debug_stats is enabled.=

- *  This routine provides a way to take a look at important statistics
- *  maintained by the driver and hardware.
- *
- **********************************************************************/=

+/*
+ * Add sysctl variables, one per statistic, to the system.
+ */
 static void
-igb_print_debug_info(struct adapter *adapter)
+igb_add_hw_stats(struct adapter *adapter)
 {
+
 	device_t dev =3D adapter->dev;
-	struct igb_queue *que =3D adapter->queues;
-	struct rx_ring *rxr =3D adapter->rx_rings;
+
 	struct tx_ring *txr =3D adapter->tx_rings;
-	uint8_t *hw_addr =3D adapter->hw.hw_addr;
+	struct rx_ring *rxr =3D adapter->rx_rings;
=20
-	device_printf(dev, "Adapter hardware address =3D %p \n", hw_addr);
-	device_printf(dev, "CTRL =3D 0x%x RCTL =3D 0x%x \n",
-	    E1000_READ_REG(&adapter->hw, E1000_CTRL),
-	    E1000_READ_REG(&adapter->hw, E1000_RCTL));
-
-#if	(DEBUG_HW > 0)  /* Dont output these errors normally */
-	device_printf(dev, "IMS =3D 0x%x EIMS =3D 0x%x \n",
-	    E1000_READ_REG(&adapter->hw, E1000_IMS),
-	    E1000_READ_REG(&adapter->hw, E1000_EIMS));
-#endif
+	struct sysctl_ctx_list *ctx =3D device_get_sysctl_ctx(dev);
+	struct sysctl_oid *tree =3D device_get_sysctl_tree(dev);
+	struct sysctl_oid_list *child =3D SYSCTL_CHILDREN(tree);
+	struct e1000_hw_stats *stats =3D &adapter->stats;
+
+	struct sysctl_oid *stat_node, *queue_node, *int_node, *host_node;
+	struct sysctl_oid_list *stat_list, *queue_list, *int_list, *host_list;
+
+#define QUEUE_NAME_LEN 32
+	char namebuf[QUEUE_NAME_LEN];
+
+	/* Driver Statistics */
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "link_irq",=20
+			CTLFLAG_RD, &adapter->link_irq, 0,
+			"Link MSIX IRQ Handled");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped",=20
+			CTLFLAG_RD, &adapter->dropped_pkts,
+			"Driver dropped packets");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_dma_fail",=20
+			CTLFLAG_RD, &adapter->no_tx_dma_setup,
+			"Driver tx dma failure in xmit");
+
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "device_control",=20
+			CTLFLAG_RD, &adapter->device_control,
+			"Device Control Register");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "rx_control",=20
+			CTLFLAG_RD, &adapter->rx_control,
+			"Receiver Control Register");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "interrupt_mask",=20
+			CTLFLAG_RD, &adapter->int_mask,
+			"Interrupt Mask");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "extended_int_mask",=20
+			CTLFLAG_RD, &adapter->eint_mask,
+			"Extended Interrupt Mask");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_buf_alloc",=20
+			CTLFLAG_RD, &adapter->packet_buf_alloc_tx,
+			"Transmit Buffer Packet Allocation");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "rx_buf_alloc",=20
+			CTLFLAG_RD, &adapter->packet_buf_alloc_rx,
+			"Receive Buffer Packet Allocation");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_high_water",
+			CTLFLAG_RD, &adapter->hw.fc.high_water, 0,
+			"Flow Control High Watermark");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_low_water",=20
+			CTLFLAG_RD, &adapter->hw.fc.low_water, 0,
+			"Flow Control Low Watermark");
=20
-	device_printf(dev, "Packet buffer =3D Tx=3D%dk Rx=3D%dk \n",
-	    ((E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff0000) >> 16),\
-	    (E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff) );
-	device_printf(dev, "Flow control watermarks high =3D %d low =3D %d\n",
-	    adapter->hw.fc.high_water,
-	    adapter->hw.fc.low_water);
-
-	for (int i =3D 0; i < adapter->num_queues; i++, rxr++, txr++) {
-		device_printf(dev, "Queue(%d) tdh =3D %d, tdt =3D %d  ", i,
-		    E1000_READ_REG(&adapter->hw, E1000_TDH(i)),
-		    E1000_READ_REG(&adapter->hw, E1000_TDT(i)));
-		device_printf(dev, "rdh =3D %d, rdt =3D %d\n",
-		    E1000_READ_REG(&adapter->hw, E1000_RDH(i)),
-		    E1000_READ_REG(&adapter->hw, E1000_RDT(i)));
-		device_printf(dev, "TX(%d) no descriptors avail event =3D %lld\n",
-		    txr->me, (long long)txr->no_desc_avail);
-		device_printf(dev, "TX(%d) Packets sent =3D %lld\n",
-		    txr->me, (long long)txr->tx_packets);
-		device_printf(dev, "RX(%d) Packets received =3D %lld  ",
-		    rxr->me, (long long)rxr->rx_packets);
+	for (int i =3D 0; i < adapter->num_queues; i++, txr++) {
+		snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i);
+		queue_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
+					    CTLFLAG_RD, NULL, "Queue Name");
+		queue_list =3D SYSCTL_CHILDREN(queue_node);
+
+		SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "txd_head",
+				CTLFLAG_RD, &txr->tdh, 0,
+				"Transmit Descriptor Head");
+		SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "txd_tail",
+				CTLFLAG_RD, &txr->tdt, 0,
+				"Transmit Descriptor Tail");
+		SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "no_desc_avail",=20
+				CTLFLAG_RD, &txr->no_desc_avail,
+				"Queue No Descriptor Available");
+		SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "tx_packets",
+				CTLFLAG_RD, &txr->tx_packets,
+				"Queue Packets Transmitted");
 	}
=20
 	for (int i =3D 0; i < adapter->num_queues; i++, rxr++) {
 		struct lro_ctrl *lro =3D &rxr->lro;
-		device_printf(dev, "Queue(%d) rdh =3D %d, rdt =3D %d\n", i,
-		    E1000_READ_REG(&adapter->hw, E1000_RDH(i)),
-		    E1000_READ_REG(&adapter->hw, E1000_RDT(i)));
-		device_printf(dev, "RX(%d) Packets received =3D %lld\n", rxr->me,
-		    (long long)rxr->rx_packets);
-		device_printf(dev, " Split Packets =3D %lld ",
-		    (long long)rxr->rx_split_packets);
-		device_printf(dev, " Byte count =3D %lld\n",
-		    (long long)rxr->rx_bytes);
-		device_printf(dev,"RX(%d) LRO Queued=3D %d  ",
-		    i, lro->lro_queued);
-		device_printf(dev,"LRO Flushed=3D %d\n",lro->lro_flushed);
-	}
-
-	for (int i =3D 0; i < adapter->num_queues; i++, que++)
-		device_printf(dev,"QUE(%d) IRQs =3D %llx\n",
-		    i, (long long)que->irqs);
-
-	device_printf(dev, "LINK MSIX IRQ Handled =3D %u\n", adapter->link_irq)=
;
-	device_printf(dev, "Mbuf defrag failed =3D %ld\n",
-	    adapter->mbuf_defrag_failed);
-	device_printf(dev, "Std mbuf header failed =3D %ld\n",
-	    adapter->mbuf_header_failed);
-	device_printf(dev, "Std mbuf packet failed =3D %ld\n",
-	    adapter->mbuf_packet_failed);
-	device_printf(dev, "Driver dropped packets =3D %ld\n",
-	    adapter->dropped_pkts);
-	device_printf(dev, "Driver tx dma failure in xmit =3D %ld\n",
-		adapter->no_tx_dma_setup);
-}
=20
-static void
-igb_print_hw_stats(struct adapter *adapter)
-{
-	device_t dev =3D adapter->dev;
+		snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i);
+		queue_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,=20
+					    CTLFLAG_RD, NULL, "Queue Name");
+		queue_list =3D SYSCTL_CHILDREN(queue_node);
+
+		SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "rxd_head",
+				CTLFLAG_RD, &rxr->rdh, 0,
+				"Receive Descriptor Head");
+		SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "rxd_tail",
+				CTLFLAG_RD, &rxr->rdt, 0,
+				"Receive Descriptor Tail");
+		SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "rx_packets",
+				CTLFLAG_RD, &rxr->rx_packets,
+				"Queue Packets Received");
+		SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "rx_bytes",
+				CTLFLAG_RD, &rxr->rx_bytes,
+				"Queue Bytes Received");
+		SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "lro_queued",
+				CTLFLAG_RD, &lro->lro_queued, 0,
+				"LRO Queued");
+		SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "lro_flushed",
+				CTLFLAG_RD, &lro->lro_flushed, 0,
+				"LRO Flushed");
+	}
+
+	/* MAC stats get the own sub node */
+
+	stat_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac_stats",=20
+				    CTLFLAG_RD, NULL, "MAC Statistics");
+	stat_list =3D SYSCTL_CHILDREN(stat_node);
+
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "excess_coll",=20
+			CTLFLAG_RD, &stats->ecol,
+			"Excessive collisions");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "single_coll",=20
+			CTLFLAG_RD, &stats->scc,
+			"Single collisions");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "multiple_coll",=20
+			CTLFLAG_RD, &stats->mcc,
+			"Multiple collisions");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "late_coll",=20
+			CTLFLAG_RD, &stats->latecol,
+			"Late collisions");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "collision_count",=20
+			CTLFLAG_RD, &stats->colc,
+			"Collision Count");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "symbol_errors",
+			CTLFLAG_RD, &adapter->stats.symerrs,
+			"Symbol Errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "sequence_errors",
+			CTLFLAG_RD, &adapter->stats.sec,
+			"Sequence Errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "defer_count",
+			CTLFLAG_RD, &adapter->stats.dc,
+			"Defer Count");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "missed_packets",
+			CTLFLAG_RD, &adapter->stats.mpc,
+			"Missed Packets");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_no_buff",
+			CTLFLAG_RD, &adapter->stats.rnbc,
+			"Receive No Buffers");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_undersize",
+			CTLFLAG_RD, &adapter->stats.ruc,
+			"Receive Undersize");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_fragmented",
+			CTLFLAG_RD, &adapter->stats.rfc,
+			"Fragmented Packets Received ");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_oversize",
+			CTLFLAG_RD, &adapter->stats.roc,
+			"Oversized Packets Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_jabber",
+			CTLFLAG_RD, &adapter->stats.rjc,
+			"Recevied Jabber");
=20
-	device_printf(dev, "Excessive collisions =3D %lld\n",
-	    (long long)adapter->stats.ecol);
-#if	(DEBUG_HW > 0)  /* Dont output these errors normally */
-	device_printf(dev, "Symbol errors =3D %lld\n",
-	    (long long)adapter->stats.symerrs);
-#endif
-	device_printf(dev, "Sequence errors =3D %lld\n",
-	    (long long)adapter->stats.sec);
-	device_printf(dev, "Defer count =3D %lld\n",
-	    (long long)adapter->stats.dc);
-	device_printf(dev, "Missed Packets =3D %lld\n",
-	    (long long)adapter->stats.mpc);
-	device_printf(dev, "Receive No Buffers =3D %lld\n",
-	    (long long)adapter->stats.rnbc);
 	/* RLEC is inaccurate on some hardware, calculate our own. */
-	device_printf(dev, "Receive Length Errors =3D %lld\n",
-	    ((long long)adapter->stats.roc + (long long)adapter->stats.ruc));
-	device_printf(dev, "Receive errors =3D %lld\n",
-	    (long long)adapter->stats.rxerrc);
-	device_printf(dev, "Crc errors =3D %lld\n",
-	    (long long)adapter->stats.crcerrs);
-	device_printf(dev, "Alignment errors =3D %lld\n",
-	    (long long)adapter->stats.algnerrc);
+/* 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_len_errs", */
+/* 			CTLFLAG_RD, adapter->stats.roc + adapter->stats.ruc, */
+/* 			"Receive Length Errors"); */
+
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_errs",
+			CTLFLAG_RD, &adapter->stats.rxerrc,
+			"Receive Errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "crc_errs",
+			CTLFLAG_RD, &adapter->stats.crcerrs,
+			"CRC errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "alignment_errs",
+			CTLFLAG_RD, &adapter->stats.algnerrc,
+			"Alignment Errors");
 	/* On 82575 these are collision counts */
-	device_printf(dev, "Collision/Carrier extension errors =3D %lld\n",
-	    (long long)adapter->stats.cexterr);
-	device_printf(dev, "RX overruns =3D %ld\n", adapter->rx_overruns);
-	device_printf(dev, "watchdog timeouts =3D %ld\n",
-	    adapter->watchdog_events);
-	device_printf(dev, "XON Rcvd =3D %lld\n",
-	    (long long)adapter->stats.xonrxc);
-	device_printf(dev, "XON Xmtd =3D %lld\n",
-	    (long long)adapter->stats.xontxc);
-	device_printf(dev, "XOFF Rcvd =3D %lld\n",
-	    (long long)adapter->stats.xoffrxc);
-	device_printf(dev, "XOFF Xmtd =3D %lld\n",
-	    (long long)adapter->stats.xofftxc);
-	device_printf(dev, "Good Packets Rcvd =3D %lld\n",
-	    (long long)adapter->stats.gprc);
-	device_printf(dev, "Good Packets Xmtd =3D %lld\n",
-	    (long long)adapter->stats.gptc);
-	device_printf(dev, "TSO Contexts Xmtd =3D %lld\n",
-	    (long long)adapter->stats.tsctc);
-	device_printf(dev, "TSO Contexts Failed =3D %lld\n",
-	    (long long)adapter->stats.tsctfc);
-}
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "coll_ext_errs",
+			CTLFLAG_RD, &adapter->stats.cexterr,
+			"Collision/Carrier extension errors");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_overruns",
+			CTLFLAG_RD, &adapter->rx_overruns,
+			"RX overruns");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "watchdog_timeouts",
+			CTLFLAG_RD, &adapter->watchdog_events,
+			"Watchdog timeouts");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xon_recvd",
+			CTLFLAG_RD, &adapter->stats.xonrxc,
+			"XON Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xon_txd",
+			CTLFLAG_RD, &adapter->stats.xontxc,
+			"XON Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xoff_recvd",
+			CTLFLAG_RD, &adapter->stats.xoffrxc,
+			"XOFF Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xoff_txd",
+			CTLFLAG_RD, &adapter->stats.xofftxc,
+			"XOFF Transmitted");
+	/* Packet Reception Stats */
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_recvd",
+			CTLFLAG_RD, &adapter->stats.tpr,
+			"Total Packets Received ");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
+			CTLFLAG_RD, &adapter->stats.gprc,
+			"Good Packets Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_recvd",
+			CTLFLAG_RD, &adapter->stats.bprc,
+			"Broadcast Packets Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_recvd",
+			CTLFLAG_RD, &adapter->stats.mprc,
+			"Multicast Packets Received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_64",
+			CTLFLAG_RD, &adapter->stats.prc64,
+			"64 byte frames received ");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127",
+			CTLFLAG_RD, &adapter->stats.prc127,
+			"65-127 byte frames received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_128_255",
+			CTLFLAG_RD, &adapter->stats.prc255,
+			"128-255 byte frames received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_256_511",
+			CTLFLAG_RD, &adapter->stats.prc511,
+			"256-511 byte frames received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_512_1023",
+			CTLFLAG_RD, &adapter->stats.prc1023,
+			"512-1023 byte frames received");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_1024_1522",
+			CTLFLAG_RD, &adapter->stats.prc1522,
+			"1023-1522 byte frames received");
+ 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd",=20
+ 			CTLFLAG_RD, &adapter->stats.gorc,=20
+ 			"Good Octets Received");=20
+
+	/* Packet Transmission Stats */
+ 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octest_txd",=20
+ 			CTLFLAG_RD, &adapter->stats.gotc,=20
+ 			"Good Octest Transmitted");=20
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd",
+			CTLFLAG_RD, &adapter->stats.tpt,
+			"Total Packets Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
+			CTLFLAG_RD, &adapter->stats.gptc,
+			"Good Packets Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd",
+			CTLFLAG_RD, &adapter->stats.bptc,
+			"Broadcast Packets Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd",
+			CTLFLAG_RD, &adapter->stats.mptc,
+			"Multicast Packets Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_64",
+			CTLFLAG_RD, &adapter->stats.ptc64,
+			"64 byte frames transmitted ");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127",
+			CTLFLAG_RD, &adapter->stats.ptc127,
+			"65-127 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_128_255",
+			CTLFLAG_RD, &adapter->stats.ptc255,
+			"128-255 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_256_511",
+			CTLFLAG_RD, &adapter->stats.ptc511,
+			"256-511 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_512_1023",
+			CTLFLAG_RD, &adapter->stats.ptc1023,
+			"512-1023 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522",
+			CTLFLAG_RD, &adapter->stats.ptc1522,
+			"1024-1522 byte frames transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tso_txd",
+			CTLFLAG_RD, &adapter->stats.tsctc,
+			"TSO Contexts Transmitted");
+	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tso_ctx_fail",
+			CTLFLAG_RD, &adapter->stats.tsctfc,
+			"TSO Contexts Failed");
+
+
+	/* Interrupt Stats */
+
+	int_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "interrupts",=20
+				    CTLFLAG_RD, NULL, "Interrupt Statistics");
+	int_list =3D SYSCTL_CHILDREN(int_node);
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "asserts",
+			CTLFLAG_RD, &adapter->stats.iac,
+			"Interrupt Assertion Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_pkt_timer",
+			CTLFLAG_RD, &adapter->stats.icrxptc,
+			"Interrupt Cause Rx Pkt Timer Expire Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_abs_timer",
+			CTLFLAG_RD, &adapter->stats.icrxatc,
+			"Interrupt Cause Rx Abs Timer Expire Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_pkt_timer",
+			CTLFLAG_RD, &adapter->stats.ictxptc,
+			"Interrupt Cause Tx Pkt Timer Expire Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_abs_timer",
+			CTLFLAG_RD, &adapter->stats.ictxatc,
+			"Interrupt Cause Tx Abs Timer Expire Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_queue_empty",
+			CTLFLAG_RD, &adapter->stats.ictxqec,
+			"Interrupt Cause Tx Queue Empty Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_queue_min_thresh",
+			CTLFLAG_RD, &adapter->stats.ictxqmtc,
+			"Interrupt Cause Tx Queue Min Thresh Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_desc_min_thresh",
+			CTLFLAG_RD, &adapter->stats.icrxdmtc,
+			"Interrupt Cause Rx Desc Min Thresh Count");
+
+	SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_overrun",
+			CTLFLAG_RD, &adapter->stats.icrxoc,
+			"Interrupt Cause Receiver Overrun Count");
+
+	/* Host to Card Stats */
+
+	host_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "host",=20
+				    CTLFLAG_RD, NULL,=20
+				    "Host to Card Statistics");
+
+	host_list =3D SYSCTL_CHILDREN(host_node);
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_tx_pkt",
+			CTLFLAG_RD, &adapter->stats.cbtmpc,
+			"Circuit Breaker Tx Packet Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "host_tx_pkt_discard",
+			CTLFLAG_RD, &adapter->stats.htdpmc,
+			"Host Transmit Discarded Packets");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "rx_pkt",
+			CTLFLAG_RD, &adapter->stats.rpthc,
+			"Rx Packets To Host");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_rx_pkts",
+			CTLFLAG_RD, &adapter->stats.cbrmpc,
+			"Circuit Breaker Rx Packet Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_rx_pkt_drop",
+			CTLFLAG_RD, &adapter->stats.cbrdpc,
+			"Circuit Breaker Rx Dropped Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "tx_good_pkt",
+			CTLFLAG_RD, &adapter->stats.hgptc,
+			"Host Good Packets Tx Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_tx_pkt_drop",
+			CTLFLAG_RD, &adapter->stats.htcbdpc,
+			"Host Tx Circuit Breaker Dropped Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "rx_good_bytes",
+			CTLFLAG_RD, &adapter->stats.hgorc,
+			"Host Good Octets Received Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "tx_good_bytes",
+			CTLFLAG_RD, &adapter->stats.hgotc,
+			"Host Good Octets Transmit Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "length_errors",
+			CTLFLAG_RD, &adapter->stats.lenerrs,
+			"Length Errors");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "serdes_violation_pkt",
+			CTLFLAG_RD, &adapter->stats.scvpc,
+			"SerDes/SGMII Code Violation Pkt Count");
+
+	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "header_redir_missed",
+			CTLFLAG_RD, &adapter->stats.hrmpc,
+			"Header Redirection Missed Packet Count");
=20
+
+}
 /**********************************************************************
  *
  *  This routine provides a way to dump out the adapter eeprom,
@@ -4943,28 +5193,8 @@
  *  32 words, stuff that matters is in that extent.
  *
  **********************************************************************/=

-static void
-igb_print_nvm_info(struct adapter *adapter)
-{
-	u16	eeprom_data;
-	int	i, j, row =3D 0;
-
-	/* Its a bit crude, but it gets the job done */
-	printf("\nInterface EEPROM Dump:\n");
-	printf("Offset\n0x0000  ");
-	for (i =3D 0, j =3D 0; i < 32; i++, j++) {
-		if (j =3D=3D 8) { /* Make the offset block */
-			j =3D 0; ++row;
-			printf("\n0x00%x0  ",row);
-		}
-		e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data);
-		printf("%04x ", eeprom_data);
-	}
-	printf("\n");
-}
-
 static int
-igb_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
+igb_sysctl_nvm_info(SYSCTL_HANDLER_ARGS)
 {
 	struct adapter *adapter;
 	int error;
@@ -4976,16 +5206,12 @@
 	if (error || !req->newptr)
 		return (error);
=20
-	if (result =3D=3D 1) {
-		adapter =3D (struct adapter *)arg1;
-		igb_print_debug_info(adapter);
-	}
 	/*
 	 * This value will cause a hex dump of the
 	 * first 32 16-bit words of the EEPROM to
 	 * the screen.
 	 */
-	if (result =3D=3D 2) {
+	if (result =3D=3D 1) {
 		adapter =3D (struct adapter *)arg1;
 		igb_print_nvm_info(adapter);
         }
@@ -4993,26 +5219,24 @@
 	return (error);
 }
=20
-
-static int
-igb_sysctl_stats(SYSCTL_HANDLER_ARGS)
+static void
+igb_print_nvm_info(struct adapter *adapter)
 {
-	struct adapter *adapter;
-	int error;
-	int result;
-
-	result =3D -1;
-	error =3D sysctl_handle_int(oidp, &result, 0, req);
-
-	if (error || !req->newptr)
-		return (error);
+	u16	eeprom_data;
+	int	i, j, row =3D 0;
=20
-	if (result =3D=3D 1) {
-		adapter =3D (struct adapter *)arg1;
-		igb_print_hw_stats(adapter);
+	/* Its a bit crude, but it gets the job done */
+	printf("\nInterface EEPROM Dump:\n");
+	printf("Offset\n0x0000  ");
+	for (i =3D 0, j =3D 0; i < 32; i++, j++) {
+		if (j =3D=3D 8) { /* Make the offset block */
+			j =3D 0; ++row;
+			printf("\n0x00%x0  ",row);
+		}
+		e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data);
+		printf("%04x ", eeprom_data);
 	}
-
-	return (error);
+	printf("\n");
 }
=20
 static void
--- src/sys/dev/e1000/if_igb.h.orig	2010-06-14 04:09:06.000000000 +0200
+++ src/sys/dev/e1000/if_igb.h	2010-07-27 10:07:14.477145093 +0200
@@ -30,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
=20
 ************************************************************************=
******/
-/*$FreeBSD: src/sys/dev/e1000/if_igb.h,v 1.4.2.2.2.1 2010/06/14 02:09:06=
 kensmith Exp $*/
+/*$FreeBSD: src/sys/dev/e1000/if_igb.h,v 1.4.2.3 2010/06/18 17:22:08 jfv=
 Exp $*/
=20
 #ifndef _IGB_H_DEFINED_
 #define _IGB_H_DEFINED_
@@ -317,6 +317,9 @@
 	int			watchdog_time;
 	u64			no_desc_avail;
 	u64			tx_packets;
+	/* Statistics for reporting, ONLY. */
+	u32			tdh; /* Transmit Descriptor Head */
+	u32			tdt; /* Transmit Descriptor Tail */
 };
=20
 /*
@@ -353,6 +356,9 @@
 	u64			rx_discarded;
 	u64			rx_packets;
 	u64			rx_bytes;
+	/* Statistics for reporting, ONLY. */
+	u32			rdh; /* Transmit Descriptor Head */
+	u32			rdt; /* Transmit Descriptor Tail */
 };
=20
 struct adapter {
@@ -382,8 +388,6 @@
 	int		min_frame_size;
 	struct mtx	core_mtx;
 	int		igb_insert_vlan_header;
-	struct task     rxtx_task;
-	struct taskqueue *tq;	/* adapter task queue */
         u16		num_queues;
=20
 	eventhandler_tag vlan_attach;
@@ -428,6 +432,12 @@
         unsigned long	no_tx_dma_setup;
 	unsigned long	watchdog_events;
 	unsigned long	rx_overruns;
+	unsigned long	device_control;
+	unsigned long	rx_control;
+	unsigned long	int_mask;
+	unsigned long	eint_mask;
+	unsigned long	packet_buf_alloc_rx;
+	unsigned long	packet_buf_alloc_tx;
=20
 	boolean_t       in_detach;
=20
--- src/sys/dev/e1000/if_lem.c.orig	2010-06-14 04:09:06.000000000 +0200
+++ src/sys/dev/e1000/if_lem.c	2010-07-27 10:07:12.343126580 +0200
@@ -30,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
=20
 ************************************************************************=
******/
-/*$FreeBSD: src/sys/dev/e1000/if_lem.c,v 1.3.2.4.2.1 2010/06/14 02:09:06=
 kensmith Exp $*/
+/*$FreeBSD: src/sys/dev/e1000/if_lem.c,v 1.7 2010/07/12 21:47:30 jfv Exp=
 $*/
=20
 #ifdef HAVE_KERNEL_OPTION_HEADERS
 #include "opt_device_polling.h"
@@ -200,7 +200,7 @@
 static void	lem_tx_purge(struct adapter *);
 static int	lem_allocate_receive_structures(struct adapter *);
 static int	lem_allocate_transmit_structures(struct adapter *);
-static int	lem_rxeof(struct adapter *, int);
+static bool	lem_rxeof(struct adapter *, int, int *);
 #ifndef __NO_STRICT_ALIGNMENT
 static int	lem_fixup_rx(struct adapter *);
 #endif
@@ -1255,7 +1255,7 @@
 	}
 	EM_CORE_UNLOCK(adapter);
=20
-	rx_done =3D lem_rxeof(adapter, count);
+	lem_rxeof(adapter, count, &rx_done);
=20
 	EM_TX_LOCK(adapter);
 	lem_txeof(adapter);
@@ -1308,7 +1308,7 @@
=20
 	EM_TX_LOCK(adapter);
 	lem_txeof(adapter);
-	lem_rxeof(adapter, -1);
+	lem_rxeof(adapter, -1, NULL);
 	lem_txeof(adapter);
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
@@ -1350,7 +1350,7 @@
=20
=20
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		if (lem_rxeof(adapter, adapter->rx_process_limit) !=3D 0)
+		if (lem_rxeof(adapter, adapter->rx_process_limit, NULL) !=3D 0)
 			taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
 		EM_TX_LOCK(adapter);
 		lem_txeof(adapter);
@@ -1566,6 +1566,19 @@
 	}
=20
 	/*
+	** When doing checksum offload, it is critical to
+	** make sure the first mbuf has more than header,
+	** because that routine expects data to be present.
+	*/
+	if ((m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) &&
+	    (m_head->m_len < ETHER_HDR_LEN + sizeof(struct ip))) {
+		m_head =3D m_pullup(m_head, ETHER_HDR_LEN + sizeof(struct ip));
+		*m_headp =3D m_head;
+		if (m_head =3D=3D NULL)
+			return (ENOBUFS);
+	}
+
+	/*
 	 * Map the packet for DMA
 	 *
 	 * Capture the first descriptor index,
@@ -2851,6 +2864,7 @@
=20
=20
 	cmd =3D hdr_len =3D ipproto =3D 0;
+	*txd_upper =3D *txd_lower =3D 0;
 	curr_txd =3D adapter->next_avail_tx_desc;
=20
 	/*
@@ -2894,9 +2908,6 @@
 			*txd_upper |=3D E1000_TXD_POPTS_IXSM << 8;
 		}
=20
-		if (mp->m_len < ehdrlen + ip_hlen)
-			return;	/* failure */
-
 		hdr_len =3D ehdrlen + ip_hlen;
 		ipproto =3D ip->ip_p;
=20
@@ -2905,18 +2916,13 @@
 		ip6 =3D (struct ip6_hdr *)(mp->m_data + ehdrlen);
 		ip_hlen =3D sizeof(struct ip6_hdr); /* XXX: No header stacking. */
=20
-		if (mp->m_len < ehdrlen + ip_hlen)
-			return;	/* failure */
-
 		/* IPv6 doesn't have a header checksum. */
=20
 		hdr_len =3D ehdrlen + ip_hlen;
 		ipproto =3D ip6->ip6_nxt;
-
 		break;
+
 	default:
-		*txd_upper =3D 0;
-		*txd_lower =3D 0;
 		return;
 	}
=20
@@ -2970,6 +2976,8 @@
 		break;
 	}
=20
+	if (TXD =3D=3D NULL)
+		return;
 	TXD->tcp_seg_setup.data =3D htole32(0);
 	TXD->cmd_and_length =3D
 	    htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd);
@@ -3449,8 +3457,8 @@
  * =20
  *  For polling we also now return the number of cleaned packets
  *********************************************************************/
-static int
-lem_rxeof(struct adapter *adapter, int count)
+static bool
+lem_rxeof(struct adapter *adapter, int count, int *done)
 {
 	struct ifnet	*ifp =3D adapter->ifp;;
 	struct mbuf	*mp;
@@ -3466,8 +3474,10 @@
 	    BUS_DMASYNC_POSTREAD);
=20
 	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
+		if (done !=3D NULL)
+			*done =3D rx_sent;
 		EM_RX_UNLOCK(adapter);
-		return (rx_sent);
+		return (FALSE);
 	}
=20
 	while ((current_desc->status & E1000_RXD_STAT_DD) &&
@@ -3626,8 +3636,10 @@
 	if (--i < 0)
 		i =3D adapter->num_rx_desc - 1;
 	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
+	if (done !=3D NULL)
+		*done =3D rx_sent;
 	EM_RX_UNLOCK(adapter);
-	return (rx_sent);
+	return (current_desc->status & E1000_RXD_STAT_DD);
 }
=20
 #ifndef __NO_STRICT_ALIGNMENT

--------------020106010007020907000302--

--------------enig5A94A6482AB6BCA889B3EE66
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.13 (FreeBSD)

iEYEARECAAYFAkxOr1YACgkQLDqVQ9VXb8hc6QCgzg9dPQ8LBpzOkORDbNpIog2J
MlUAoMsu87CgvUgcClm9Ud5kUGqPyeTk
=al3B
-----END PGP SIGNATURE-----

--------------enig5A94A6482AB6BCA889B3EE66--



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