]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/igb/igb_main.c
drivers/net: avoid some skb->ip_summed initializations
[net-next-2.6.git] / drivers / net / igb / igb_main.c
index cea37e0837ff64d3ed4ae16ccc78f85557be9700..c4d861b557ca43c367d16db99113cd8135d0ad9a 100644 (file)
@@ -630,9 +630,6 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
                        for (; i < adapter->rss_queues; i++)
                                adapter->rx_ring[i]->reg_idx = rbase_offset +
                                                               Q_IDX_82576(i);
-                       for (; j < adapter->rss_queues; j++)
-                               adapter->tx_ring[j]->reg_idx = rbase_offset +
-                                                              Q_IDX_82576(j);
                }
        case e1000_82575:
        case e1000_82580:
@@ -996,7 +993,10 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
 
        /* Number of supported queues. */
        adapter->num_rx_queues = adapter->rss_queues;
-       adapter->num_tx_queues = adapter->rss_queues;
+       if (adapter->vfs_allocated_count)
+               adapter->num_tx_queues = 1;
+       else
+               adapter->num_tx_queues = adapter->rss_queues;
 
        /* start with one vector for every rx queue */
        numvecs = adapter->num_rx_queues;
@@ -1290,7 +1290,13 @@ static void igb_irq_disable(struct igb_adapter *adapter)
        wr32(E1000_IAM, 0);
        wr32(E1000_IMC, ~0);
        wrfl();
-       synchronize_irq(adapter->pdev->irq);
+       if (adapter->msix_entries) {
+               int i;
+               for (i = 0; i < adapter->num_q_vectors; i++)
+                       synchronize_irq(adapter->msix_entries[i].vector);
+       } else {
+               synchronize_irq(adapter->pdev->irq);
+       }
 }
 
 /**
@@ -1882,9 +1888,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                goto err_eeprom;
        }
 
-       setup_timer(&adapter->watchdog_timer, &igb_watchdog,
+       setup_timer(&adapter->watchdog_timer, igb_watchdog,
                    (unsigned long) adapter);
-       setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
+       setup_timer(&adapter->phy_info_timer, igb_update_phy_info,
                    (unsigned long) adapter);
 
        INIT_WORK(&adapter->reset_task, igb_reset_task);
@@ -2100,9 +2106,6 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter)
 #ifdef CONFIG_PCI_IOV
        struct pci_dev *pdev = adapter->pdev;
 
-       if (adapter->vfs_allocated_count > 7)
-               adapter->vfs_allocated_count = 7;
-
        if (adapter->vfs_allocated_count) {
                adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
                                           sizeof(struct vf_data_storage),
@@ -2267,7 +2270,7 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
 
 #ifdef CONFIG_PCI_IOV
        if (hw->mac.type == e1000_82576)
-               adapter->vfs_allocated_count = max_vfs;
+               adapter->vfs_allocated_count = (max_vfs > 7) ? 7 : max_vfs;
 
 #endif /* CONFIG_PCI_IOV */
        adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
@@ -2729,14 +2732,16 @@ static void igb_setup_mrqc(struct igb_adapter *adapter)
        }
        igb_vmm_control(adapter);
 
-       mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
-                E1000_MRQC_RSS_FIELD_IPV4_TCP);
-       mrqc |= (E1000_MRQC_RSS_FIELD_IPV6 |
-                E1000_MRQC_RSS_FIELD_IPV6_TCP);
-       mrqc |= (E1000_MRQC_RSS_FIELD_IPV4_UDP |
-                E1000_MRQC_RSS_FIELD_IPV6_UDP);
-       mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
-                E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
+       /*
+        * Generate RSS hash based on TCP port numbers and/or
+        * IPv4/v6 src and dst addresses since UDP cannot be
+        * hashed reliably due to IP fragmentation
+        */
+       mrqc |= E1000_MRQC_RSS_FIELD_IPV4 |
+               E1000_MRQC_RSS_FIELD_IPV4_TCP |
+               E1000_MRQC_RSS_FIELD_IPV6 |
+               E1000_MRQC_RSS_FIELD_IPV6_TCP |
+               E1000_MRQC_RSS_FIELD_IPV6_TCP_EX;
 
        wr32(E1000_MRQC, mrqc);
 }
@@ -3949,7 +3954,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
        }
 
        tx_ring->buffer_info[i].skb = skb;
-       tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags;
+       tx_ring->buffer_info[i].tx_flags = skb_shinfo(skb)->tx_flags;
        /* multiply data chunks by size of headers */
        tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len;
        tx_ring->buffer_info[i].gso_segs = gso_segs;
@@ -4083,7 +4088,6 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
        u32 tx_flags = 0;
        u16 first;
        u8 hdr_len = 0;
-       union skb_shared_tx *shtx = skb_tx(skb);
 
        /* need: 1 descriptor per page,
         *       + 2 desc gap to keep tail from touching head,
@@ -4095,8 +4099,8 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
                return NETDEV_TX_BUSY;
        }
 
-       if (unlikely(shtx->hardware)) {
-               shtx->in_progress = 1;
+       if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+               skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
                tx_flags |= IGB_TX_FLAGS_TSTAMP;
        }
 
@@ -4986,6 +4990,10 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
 
 static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)
 {
+       /*
+        * The VF MAC Address is stored in a packed array of bytes
+        * starting at the second 32 bit word of the msg array
+        */
        unsigned char *addr = (char *)&msg[1];
        int err = -1;
 
@@ -5310,7 +5318,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *bu
        u64 regval;
 
        /* if skb does not support hw timestamp or TX stamp not valid exit */
-       if (likely(!buffer_info->shtx.hardware) ||
+       if (likely(!(buffer_info->tx_flags & SKBTX_HW_TSTAMP)) ||
            !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
                return;
 
@@ -5344,6 +5352,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
 
        while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
               (count < tx_ring->count)) {
+               rmb();  /* read buffer_info after eop_desc status */
                for (cleaned = false; !cleaned; count++) {
                        tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
                        buffer_info = &tx_ring->buffer_info[i];
@@ -5446,7 +5455,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector,
 static inline void igb_rx_checksum_adv(struct igb_ring *ring,
                                       u32 status_err, struct sk_buff *skb)
 {
-       skb->ip_summed = CHECKSUM_NONE;
+       skb_checksum_none_assert(skb);
 
        /* Ignore Checksum bit is set or checksum is disabled through ethtool */
        if (!(ring->flags & IGB_RING_FLAG_RX_CSUM) ||
@@ -5490,7 +5499,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr,
         * values must belong to this one here and therefore we don't need to
         * compare any of the additional attributes stored for it.
         *
-        * If nothing went wrong, then it should have a skb_shared_tx that we
+        * If nothing went wrong, then it should have a shared tx_flags that we
         * can turn into a skb_shared_hwtstamps.
         */
        if (staterr & E1000_RXDADV_STAT_TSIP) {
@@ -5549,6 +5558,7 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector,
                if (*work_done >= budget)
                        break;
                (*work_done)++;
+               rmb(); /* read descriptor and rx_buffer_info after status DD */
 
                skb = buffer_info->skb;
                prefetch(skb->data - NET_IP_ALIGN);