]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/ixgbe/ixgbe_main.c
ixgbe: move CPU variable from ring into q_vector, add ring->q_vector
[net-next-2.6.git] / drivers / net / ixgbe / ixgbe_main.c
index be76dd9b94a95d94b8921143e0476591857ed6fd..dc78736d30528185a6082687b7fa2b38b228dc7e 100644 (file)
@@ -733,7 +733,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
                               struct ixgbe_ring *tx_ring)
 {
        struct ixgbe_adapter *adapter = q_vector->adapter;
-       struct net_device *netdev = adapter->netdev;
        union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
        struct ixgbe_tx_buffer *tx_buffer_info;
        unsigned int i, eop, count = 0;
@@ -774,16 +773,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
        tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
-       if (unlikely(count && netif_carrier_ok(netdev) &&
+       if (unlikely(count && netif_carrier_ok(tx_ring->netdev) &&
                     (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
                /* Make sure that anybody stopping the queue after this
                 * sees the new next_to_clean.
                 */
                smp_mb();
-               if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
+               if (__netif_subqueue_stopped(tx_ring->netdev, tx_ring->queue_index) &&
                    !test_bit(__IXGBE_DOWN, &adapter->state)) {
-                       netif_wake_subqueue(netdev, tx_ring->queue_index);
-                       ++tx_ring->restart_queue;
+                       netif_wake_subqueue(tx_ring->netdev, tx_ring->queue_index);
+                       ++tx_ring->tx_stats.restart_queue;
                }
        }
 
@@ -811,63 +810,98 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 
 #ifdef CONFIG_IXGBE_DCA
 static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
-                               struct ixgbe_ring *rx_ring)
+                               struct ixgbe_ring *rx_ring,
+                               int cpu)
 {
+       struct ixgbe_hw *hw = &adapter->hw;
        u32 rxctrl;
-       int cpu = get_cpu();
-       int q = rx_ring->reg_idx;
+       u8 reg_idx = rx_ring->reg_idx;
 
-       if (rx_ring->cpu != cpu) {
-               rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q));
-               if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
-                       rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
-                       rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
-               } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-                       rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
-                       rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
-                                  IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
-               }
-               rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
-               rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
-               rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
-               rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
-                           IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
-               rx_ring->cpu = cpu;
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(reg_idx));
+       switch (hw->mac.type) {
+       case ixgbe_mac_82598EB:
+               rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
+               rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+               break;
+       case ixgbe_mac_82599EB:
+               rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
+               rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+                          IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
+               break;
+       default:
+               break;
        }
-       put_cpu();
+       rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
+       rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
+       rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
+       rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+                   IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+       IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl);
 }
 
 static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
-                               struct ixgbe_ring *tx_ring)
+                               struct ixgbe_ring *tx_ring,
+                               int cpu)
 {
+       struct ixgbe_hw *hw = &adapter->hw;
        u32 txctrl;
+       u8 reg_idx = tx_ring->reg_idx;
+
+       switch (hw->mac.type) {
+       case ixgbe_mac_82598EB:
+               txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(reg_idx));
+               txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
+               txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+               txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
+               txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+               IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(reg_idx), txctrl);
+               break;
+       case ixgbe_mac_82599EB:
+               txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx));
+               txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
+               txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+                          IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+               txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
+               txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+               IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx), txctrl);
+               break;
+       default:
+               break;
+       }
+}
+
+static void ixgbe_update_dca(struct ixgbe_q_vector *q_vector)
+{
+       struct ixgbe_adapter *adapter = q_vector->adapter;
        int cpu = get_cpu();
-       int q = tx_ring->reg_idx;
-       struct ixgbe_hw *hw = &adapter->hw;
+       long r_idx;
+       int i;
 
-       if (tx_ring->cpu != cpu) {
-               if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
-                       txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(q));
-                       txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
-                       txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
-                       txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
-                       IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(q), txctrl);
-               } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-                       txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q));
-                       txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
-                       txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
-                                 IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
-                       txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
-                       IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl);
-               }
-               tx_ring->cpu = cpu;
+       if (q_vector->cpu == cpu)
+               goto out_no_update;
+
+       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+       for (i = 0; i < q_vector->txr_count; i++) {
+               ixgbe_update_tx_dca(adapter, adapter->tx_ring[r_idx], cpu);
+               r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+                                     r_idx + 1);
+       }
+
+       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+       for (i = 0; i < q_vector->rxr_count; i++) {
+               ixgbe_update_rx_dca(adapter, adapter->rx_ring[r_idx], cpu);
+               r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+                                     r_idx + 1);
        }
+
+       q_vector->cpu = cpu;
+out_no_update:
        put_cpu();
 }
 
 static void ixgbe_setup_dca(struct ixgbe_adapter *adapter)
 {
+       int num_q_vectors;
        int i;
 
        if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED))
@@ -876,22 +910,25 @@ static void ixgbe_setup_dca(struct ixgbe_adapter *adapter)
        /* always use CB2 mode, difference is masked in the CB driver */
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
 
-       for (i = 0; i < adapter->num_tx_queues; i++) {
-               adapter->tx_ring[i]->cpu = -1;
-               ixgbe_update_tx_dca(adapter, adapter->tx_ring[i]);
-       }
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               adapter->rx_ring[i]->cpu = -1;
-               ixgbe_update_rx_dca(adapter, adapter->rx_ring[i]);
+       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
+               num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+       else
+               num_q_vectors = 1;
+
+       for (i = 0; i < num_q_vectors; i++) {
+               adapter->q_vector[i]->cpu = -1;
+               ixgbe_update_dca(adapter->q_vector[i]);
        }
 }
 
 static int __ixgbe_notify_dca(struct device *dev, void *data)
 {
-       struct net_device *netdev = dev_get_drvdata(dev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_adapter *adapter = dev_get_drvdata(dev);
        unsigned long event = *(unsigned long *)data;
 
+       if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED))
+               return 0;
+
        switch (event) {
        case DCA_PROVIDER_ADD:
                /* if we're already enabled, don't do it again */
@@ -1004,27 +1041,30 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val)
 
 /**
  * ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split
- * @adapter: address of board private structure
+ * @rx_ring: ring to place buffers on
+ * @cleaned_count: number of buffers to replace
  **/
-void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
-                           struct ixgbe_ring *rx_ring,
-                           u16 cleaned_count)
+void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count)
 {
        union ixgbe_adv_rx_desc *rx_desc;
        struct ixgbe_rx_buffer *bi;
        struct sk_buff *skb;
        u16 i = rx_ring->next_to_use;
 
+       /* do nothing if no valid netdev defined */
+       if (!rx_ring->netdev)
+               return;
+
        while (cleaned_count--) {
                rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
                bi = &rx_ring->rx_buffer_info[i];
                skb = bi->skb;
 
                if (!skb) {
-                       skb = netdev_alloc_skb_ip_align(adapter->netdev,
+                       skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
                                                        rx_ring->rx_buf_len);
                        if (!skb) {
-                               adapter->alloc_rx_buff_failed++;
+                               rx_ring->rx_stats.alloc_rx_buff_failed++;
                                goto no_buffers;
                        }
                        /* initialize queue mapping */
@@ -1038,7 +1078,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
                                                 rx_ring->rx_buf_len,
                                                 DMA_FROM_DEVICE);
                        if (dma_mapping_error(rx_ring->dev, bi->dma)) {
-                               adapter->alloc_rx_buff_failed++;
+                               rx_ring->rx_stats.alloc_rx_buff_failed++;
                                bi->dma = 0;
                                goto no_buffers;
                        }
@@ -1046,9 +1086,9 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
 
                if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
                        if (!bi->page) {
-                               bi->page = netdev_alloc_page(adapter->netdev);
+                               bi->page = netdev_alloc_page(rx_ring->netdev);
                                if (!bi->page) {
-                                       adapter->alloc_rx_page_failed++;
+                                       rx_ring->rx_stats.alloc_rx_page_failed++;
                                        goto no_buffers;
                                }
                        }
@@ -1063,7 +1103,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
                                                            DMA_FROM_DEVICE);
                                if (dma_mapping_error(rx_ring->dev,
                                                      bi->page_dma)) {
-                                       adapter->alloc_rx_page_failed++;
+                                       rx_ring->rx_stats.alloc_rx_page_failed++;
                                        bi->page_dma = 0;
                                        goto no_buffers;
                                }
@@ -1258,7 +1298,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                if (staterr & IXGBE_RXD_STAT_EOP) {
                        if (skb->prev)
                                skb = ixgbe_transform_rsc_queue(skb,
-                                                               &(rx_ring->rsc_count));
+                                               &(rx_ring->rx_stats.rsc_count));
                        if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
                                if (IXGBE_RSC_CB(skb)->delay_unmap) {
                                        dma_unmap_single(rx_ring->dev,
@@ -1269,11 +1309,11 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                                        IXGBE_RSC_CB(skb)->delay_unmap = false;
                                }
                                if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
-                                       rx_ring->rsc_count +=
-                                               skb_shinfo(skb)->nr_frags;
+                                       rx_ring->rx_stats.rsc_count +=
+                                                skb_shinfo(skb)->nr_frags;
                                else
-                                       rx_ring->rsc_count++;
-                               rx_ring->rsc_flush++;
+                                       rx_ring->rx_stats.rsc_count++;
+                               rx_ring->rx_stats.rsc_flush++;
                        }
                        u64_stats_update_begin(&rx_ring->syncp);
                        rx_ring->stats.packets++;
@@ -1289,7 +1329,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                                skb->next = next_buffer->skb;
                                skb->next->prev = skb;
                        }
-                       rx_ring->non_eop_descs++;
+                       rx_ring->rx_stats.non_eop_descs++;
                        goto next_desc;
                }
 
@@ -1304,7 +1344,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                total_rx_bytes += skb->len;
                total_rx_packets++;
 
-               skb->protocol = eth_type_trans(skb, adapter->netdev);
+               skb->protocol = eth_type_trans(skb, rx_ring->netdev);
 #ifdef IXGBE_FCOE
                /* if ddp, not passing to ULD unless for FCP_RSP or error */
                if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
@@ -1320,7 +1360,7 @@ next_desc:
 
                /* return some buffers to hardware, one at a time is too slow */
                if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) {
-                       ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
+                       ixgbe_alloc_rx_buffers(rx_ring, cleaned_count);
                        cleaned_count = 0;
                }
 
@@ -1335,14 +1375,14 @@ next_desc:
        cleaned_count = IXGBE_DESC_UNUSED(rx_ring);
 
        if (cleaned_count)
-               ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
+               ixgbe_alloc_rx_buffers(rx_ring, cleaned_count);
 
 #ifdef IXGBE_FCOE
        /* include DDPed FCoE data */
        if (ddp_bytes > 0) {
                unsigned int mss;
 
-               mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) -
+               mss = rx_ring->netdev->mtu - sizeof(struct fcoe_hdr) -
                        sizeof(struct fc_frame_header) -
                        sizeof(struct fcoe_crc_eof);
                if (mss > 512)
@@ -1826,8 +1866,13 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
        int r_idx;
        int i;
 
+#ifdef CONFIG_IXGBE_DCA
+       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+               ixgbe_update_dca(q_vector);
+#endif
+
        r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       for (i = 0;  i < q_vector->rxr_count; i++) {
+       for (i = 0; i < q_vector->rxr_count; i++) {
                rx_ring = adapter->rx_ring[r_idx];
                rx_ring->total_bytes = 0;
                rx_ring->total_packets = 0;
@@ -1838,7 +1883,6 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
        if (!q_vector->rxr_count)
                return IRQ_HANDLED;
 
-       /* disable interrupts on this vector only */
        /* EIAM disabled interrupts (on this vector) for us */
        napi_schedule(&q_vector->napi);
 
@@ -1897,13 +1941,14 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
        int work_done = 0;
        long r_idx;
 
-       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       rx_ring = adapter->rx_ring[r_idx];
 #ifdef CONFIG_IXGBE_DCA
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
-               ixgbe_update_rx_dca(adapter, rx_ring);
+               ixgbe_update_dca(q_vector);
 #endif
 
+       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+       rx_ring = adapter->rx_ring[r_idx];
+
        ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
 
        /* If all Rx work done, exit the polling mode */
@@ -1937,13 +1982,14 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
        long r_idx;
        bool tx_clean_complete = true;
 
+#ifdef CONFIG_IXGBE_DCA
+       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+               ixgbe_update_dca(q_vector);
+#endif
+
        r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
        for (i = 0; i < q_vector->txr_count; i++) {
                ring = adapter->tx_ring[r_idx];
-#ifdef CONFIG_IXGBE_DCA
-               if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
-                       ixgbe_update_tx_dca(adapter, ring);
-#endif
                tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring);
                r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
                                      r_idx + 1);
@@ -1956,10 +2002,6 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
        r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
        for (i = 0; i < q_vector->rxr_count; i++) {
                ring = adapter->rx_ring[r_idx];
-#ifdef CONFIG_IXGBE_DCA
-               if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
-                       ixgbe_update_rx_dca(adapter, ring);
-#endif
                ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget);
                r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
                                      r_idx + 1);
@@ -1998,13 +2040,14 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
        int work_done = 0;
        long r_idx;
 
-       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
-       tx_ring = adapter->tx_ring[r_idx];
 #ifdef CONFIG_IXGBE_DCA
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
-               ixgbe_update_tx_dca(adapter, tx_ring);
+               ixgbe_update_dca(q_vector);
 #endif
 
+       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+       tx_ring = adapter->tx_ring[r_idx];
+
        if (!ixgbe_clean_tx_irq(q_vector, tx_ring))
                work_done = budget;
 
@@ -2810,7 +2853,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
        IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
 
        ixgbe_rx_desc_queue_enable(adapter, ring);
-       ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring));
+       ixgbe_alloc_rx_buffers(ring, IXGBE_DESC_UNUSED(ring));
 }
 
 static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter)
@@ -3326,8 +3369,6 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
        int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
-       u32 txdctl;
-       int i, j;
 
        if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) {
                if (hw->mac.type == ixgbe_mac_82598EB)
@@ -3348,20 +3389,13 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
        ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame,
                                        DCB_RX_CONFIG);
 
-       /* reconfigure the hardware */
-       ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg);
-
-       for (i = 0; i < adapter->num_tx_queues; i++) {
-               j = adapter->tx_ring[i]->reg_idx;
-               txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
-               /* PThresh workaround for Tx hang with DFP enabled. */
-               txdctl |= 32;
-               IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
-       }
        /* Enable VLAN tag insert/strip */
        adapter->netdev->features |= NETIF_F_HW_VLAN_RX;
 
        hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
+
+       /* reconfigure the hardware */
+       ixgbe_dcb_hw_config(hw, &adapter->dcb_cfg);
 }
 
 #endif
@@ -3888,10 +3922,8 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
        int tx_clean_complete, work_done = 0;
 
 #ifdef CONFIG_IXGBE_DCA
-       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
-               ixgbe_update_tx_dca(adapter, adapter->tx_ring[0]);
-               ixgbe_update_rx_dca(adapter, adapter->rx_ring[0]);
-       }
+       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+               ixgbe_update_dca(q_vector);
 #endif
 
        tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring[0]);
@@ -4455,6 +4487,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
                ring->count = adapter->tx_ring_count;
                ring->queue_index = i;
                ring->dev = &adapter->pdev->dev;
+               ring->netdev = adapter->netdev;
                ring->numa_node = adapter->node;
 
                adapter->tx_ring[i] = ring;
@@ -4481,6 +4514,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
                ring->count = rx_count;
                ring->queue_index = i;
                ring->dev = &adapter->pdev->dev;
+               ring->netdev = adapter->netdev;
                ring->numa_node = adapter->node;
 
                adapter->rx_ring[i] = ring;
@@ -5260,8 +5294,8 @@ static int ixgbe_close(struct net_device *netdev)
 #ifdef CONFIG_PM
 static int ixgbe_resume(struct pci_dev *pdev)
 {
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+       struct net_device *netdev = adapter->netdev;
        u32 err;
 
        pci_set_power_state(pdev, PCI_D0);
@@ -5292,7 +5326,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
 
        if (netif_running(netdev)) {
-               err = ixgbe_open(adapter->netdev);
+               err = ixgbe_open(netdev);
                if (err)
                        return err;
        }
@@ -5305,8 +5339,8 @@ static int ixgbe_resume(struct pci_dev *pdev)
 
 static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+       struct net_device *netdev = adapter->netdev;
        struct ixgbe_hw *hw = &adapter->hw;
        u32 ctrl, fctrl;
        u32 wufc = adapter->wol;
@@ -5323,6 +5357,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
                ixgbe_free_all_rx_resources(adapter);
        }
 
+       ixgbe_clear_interrupt_scheme(adapter);
+
 #ifdef CONFIG_PM
        retval = pci_save_state(pdev);
        if (retval)
@@ -5356,8 +5392,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
 
        *enable_wake = !!wufc;
 
-       ixgbe_clear_interrupt_scheme(adapter);
-
        ixgbe_release_hw_control(adapter);
 
        pci_disable_device(pdev);
@@ -5406,10 +5440,12 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
        struct ixgbe_hw *hw = &adapter->hw;
+       struct ixgbe_hw_stats *hwstats = &adapter->stats;
        u64 total_mpc = 0;
        u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
-       u64 non_eop_descs = 0, restart_queue = 0;
-       struct ixgbe_hw_stats *hwstats = &adapter->stats;
+       u64 non_eop_descs = 0, restart_queue = 0, tx_busy = 0;
+       u64 alloc_rx_page_failed = 0, alloc_rx_buff_failed = 0;
+       u64 bytes = 0, packets = 0;
 
        if (test_bit(__IXGBE_DOWN, &adapter->state) ||
            test_bit(__IXGBE_RESETTING, &adapter->state))
@@ -5422,21 +5458,41 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
                        adapter->hw_rx_no_dma_resources +=
                                IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
                for (i = 0; i < adapter->num_rx_queues; i++) {
-                       rsc_count += adapter->rx_ring[i]->rsc_count;
-                       rsc_flush += adapter->rx_ring[i]->rsc_flush;
+                       rsc_count += adapter->rx_ring[i]->rx_stats.rsc_count;
+                       rsc_flush += adapter->rx_ring[i]->rx_stats.rsc_flush;
                }
                adapter->rsc_total_count = rsc_count;
                adapter->rsc_total_flush = rsc_flush;
        }
 
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               struct ixgbe_ring *rx_ring = adapter->rx_ring[i];
+               non_eop_descs += rx_ring->rx_stats.non_eop_descs;
+               alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed;
+               alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed;
+               bytes += rx_ring->stats.bytes;
+               packets += rx_ring->stats.packets;
+       }
+       adapter->non_eop_descs = non_eop_descs;
+       adapter->alloc_rx_page_failed = alloc_rx_page_failed;
+       adapter->alloc_rx_buff_failed = alloc_rx_buff_failed;
+       netdev->stats.rx_bytes = bytes;
+       netdev->stats.rx_packets = packets;
+
+       bytes = 0;
+       packets = 0;
        /* gather some stats to the adapter struct that are per queue */
-       for (i = 0; i < adapter->num_tx_queues; i++)
-               restart_queue += adapter->tx_ring[i]->restart_queue;
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
+               restart_queue += tx_ring->tx_stats.restart_queue;
+               tx_busy += tx_ring->tx_stats.tx_busy;
+               bytes += tx_ring->stats.bytes;
+               packets += tx_ring->stats.packets;
+       }
        adapter->restart_queue = restart_queue;
-
-       for (i = 0; i < adapter->num_rx_queues; i++)
-               non_eop_descs += adapter->rx_ring[i]->non_eop_descs;
-       adapter->non_eop_descs = non_eop_descs;
+       adapter->tx_busy = tx_busy;
+       netdev->stats.tx_bytes = bytes;
+       netdev->stats.tx_packets = packets;
 
        hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
        for (i = 0; i < 8; i++) {
@@ -6207,10 +6263,9 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
        ixgbe_fdir_add_signature_filter_82599(&adapter->hw, &atr_input, queue);
 }
 
-static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
-                                struct ixgbe_ring *tx_ring, int size)
+static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size)
 {
-       netif_stop_subqueue(netdev, tx_ring->queue_index);
+       netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
        /* Herbert's original patch had:
         *  smp_mb__after_netif_stop_queue();
         * but since that doesn't exist yet, just open code it. */
@@ -6222,17 +6277,16 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
                return -EBUSY;
 
        /* A reprieve! - use start_queue because it doesn't call schedule */
-       netif_start_subqueue(netdev, tx_ring->queue_index);
-       ++tx_ring->restart_queue;
+       netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index);
+       ++tx_ring->tx_stats.restart_queue;
        return 0;
 }
 
-static int ixgbe_maybe_stop_tx(struct net_device *netdev,
-                             struct ixgbe_ring *tx_ring, int size)
+static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size)
 {
        if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
                return 0;
-       return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
+       return __ixgbe_maybe_stop_tx(tx_ring, size);
 }
 
 static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
@@ -6277,10 +6331,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
        return skb_tx_hash(dev, skb);
 }
 
-netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev,
+netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
                          struct ixgbe_adapter *adapter,
                          struct ixgbe_ring *tx_ring)
 {
+       struct net_device *netdev = tx_ring->netdev;
        struct netdev_queue *txq;
        unsigned int first;
        unsigned int tx_flags = 0;
@@ -6338,8 +6393,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
        for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
                count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
 
-       if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) {
-               adapter->tx_busy++;
+       if (ixgbe_maybe_stop_tx(tx_ring, count)) {
+               tx_ring->tx_stats.tx_busy++;
                return NETDEV_TX_BUSY;
        }
 
@@ -6390,7 +6445,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
                txq->tx_bytes += skb->len;
                txq->tx_packets++;
                ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len);
-               ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
+               ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
 
        } else {
                dev_kfree_skb_any(skb);
@@ -6407,7 +6462,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netd
        struct ixgbe_ring *tx_ring;
 
        tx_ring = adapter->tx_ring[skb->queue_mapping];
-       return ixgbe_xmit_frame_ring(skb, netdev, adapter, tx_ring);
+       return ixgbe_xmit_frame_ring(skb, adapter, tx_ring);
 }
 
 /**
@@ -6746,8 +6801,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 
        SET_NETDEV_DEV(netdev, &pdev->dev);
 
-       pci_set_drvdata(pdev, netdev);
        adapter = netdev_priv(netdev);
+       pci_set_drvdata(pdev, adapter);
 
        adapter->netdev = netdev;
        adapter->pdev = pdev;
@@ -7070,8 +7125,8 @@ err_dma:
  **/
 static void __devexit ixgbe_remove(struct pci_dev *pdev)
 {
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+       struct net_device *netdev = adapter->netdev;
 
        set_bit(__IXGBE_DOWN, &adapter->state);
        /* clear the module not found bit to make sure the worker won't
@@ -7141,8 +7196,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
                                                pci_channel_state_t state)
 {
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+       struct net_device *netdev = adapter->netdev;
 
        netif_device_detach(netdev);
 
@@ -7165,8 +7220,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
  */
 static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
 {
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
        pci_ers_result_t result;
        int err;
 
@@ -7204,8 +7258,8 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
  */
 static void ixgbe_io_resume(struct pci_dev *pdev)
 {
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+       struct net_device *netdev = adapter->netdev;
 
        if (netif_running(netdev)) {
                if (ixgbe_up(adapter)) {