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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to