igbvf: do not modify tx_queue_len on link speed change
[safe/jmp/linux-2.6] / drivers / net / igbvf / netdev.c
index 5f7ba1a..b41037e 100644 (file)
@@ -96,8 +96,6 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter,
                                         E1000_RXD_SPC_VLAN_MASK);
        else
                netif_receive_skb(skb);
-
-       netdev->last_rx = jiffies;
 }
 
 static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
@@ -149,7 +147,6 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
                bufsz = adapter->rx_ps_hdr_size;
        else
                bufsz = adapter->rx_buffer_len;
-       bufsz += NET_IP_ALIGN;
 
        while (cleaned_count--) {
                rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
@@ -173,18 +170,12 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
                }
 
                if (!buffer_info->skb) {
-                       skb = netdev_alloc_skb(netdev, bufsz);
+                       skb = netdev_alloc_skb_ip_align(netdev, bufsz);
                        if (!skb) {
                                adapter->alloc_rx_buff_failed++;
                                goto no_buffers;
                        }
 
-                       /* Make buffer alignment 2 beyond a 16 byte boundary
-                        * this will result in a 16 byte aligned IP header after
-                        * the 14 byte MAC header is removed
-                        */
-                       skb_reserve(skb, NET_IP_ALIGN);
-
                        buffer_info->skb = skb;
                        buffer_info->dma = pci_map_single(pdev, skb->data,
                                                          bufsz,
@@ -286,7 +277,7 @@ static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,
 
                if (!skb_shinfo(skb)->nr_frags) {
                        pci_unmap_single(pdev, buffer_info->dma,
-                                        adapter->rx_ps_hdr_size + NET_IP_ALIGN,
+                                        adapter->rx_ps_hdr_size,
                                         PCI_DMA_FROMDEVICE);
                        skb_put(skb, hlen);
                }
@@ -343,8 +334,6 @@ send_up:
                igbvf_receive_skb(adapter, netdev, skb, staterr,
                                  rx_desc->wb.upper.vlan);
 
-               netdev->last_rx = jiffies;
-
 next_desc:
                rx_desc->wb.upper.status_error = 0;
 
@@ -377,10 +366,20 @@ next_desc:
 static void igbvf_put_txbuf(struct igbvf_adapter *adapter,
                             struct igbvf_buffer *buffer_info)
 {
-       buffer_info->dma = 0;
+       if (buffer_info->dma) {
+               if (buffer_info->mapped_as_page)
+                       pci_unmap_page(adapter->pdev,
+                                      buffer_info->dma,
+                                      buffer_info->length,
+                                      PCI_DMA_TODEVICE);
+               else
+                       pci_unmap_single(adapter->pdev,
+                                        buffer_info->dma,
+                                        buffer_info->length,
+                                        PCI_DMA_TODEVICE);
+               buffer_info->dma = 0;
+       }
        if (buffer_info->skb) {
-               skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
-                             DMA_TO_DEVICE);
                dev_kfree_skb_any(buffer_info->skb);
                buffer_info->skb = NULL;
        }
@@ -828,8 +827,8 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring)
                adapter->detect_tx_hung = false;
                if (tx_ring->buffer_info[i].time_stamp &&
                    time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
-                              (adapter->tx_timeout_factor * HZ))
-                   && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
+                              (adapter->tx_timeout_factor * HZ)) &&
+                   !(er32(STATUS) & E1000_STATUS_TXOFF)) {
 
                        tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
                        /* detected Tx unit hang */
@@ -1054,7 +1053,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
        }
 
        err = request_irq(adapter->msix_entries[vector].vector,
-                         &igbvf_intr_msix_tx, 0, adapter->tx_ring->name,
+                         igbvf_intr_msix_tx, 0, adapter->tx_ring->name,
                          netdev);
        if (err)
                goto out;
@@ -1064,7 +1063,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
        vector++;
 
        err = request_irq(adapter->msix_entries[vector].vector,
-                         &igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
+                         igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
                          netdev);
        if (err)
                goto out;
@@ -1074,7 +1073,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
        vector++;
 
        err = request_irq(adapter->msix_entries[vector].vector,
-                         &igbvf_msix_other, 0, netdev->name, netdev);
+                         igbvf_msix_other, 0, netdev->name, netdev);
        if (err)
                goto out;
 
@@ -1281,7 +1280,7 @@ static void igbvf_configure_tx(struct igbvf_adapter *adapter)
        /* Setup the HW Tx Head and Tail descriptor pointers */
        ew32(TDLEN(0), tx_ring->count * sizeof(union e1000_adv_tx_desc));
        tdba = tx_ring->dma;
-       ew32(TDBAL(0), (tdba & DMA_32BIT_MASK));
+       ew32(TDBAL(0), (tdba & DMA_BIT_MASK(32)));
        ew32(TDBAH(0), (tdba >> 32));
        ew32(TDH(0), 0);
        ew32(TDT(0), 0);
@@ -1305,8 +1304,6 @@ static void igbvf_configure_tx(struct igbvf_adapter *adapter)
 
        /* enable Report Status bit */
        adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS;
-
-       adapter->tx_queue_len = adapter->netdev->tx_queue_len;
 }
 
 /**
@@ -1367,7 +1364,7 @@ static void igbvf_configure_rx(struct igbvf_adapter *adapter)
         * the Base and Length of the Rx Descriptor Ring
         */
        rdba = rx_ring->dma;
-       ew32(RDBAL(0), (rdba & DMA_32BIT_MASK));
+       ew32(RDBAL(0), (rdba & DMA_BIT_MASK(32)));
        ew32(RDBAH(0), (rdba >> 32));
        ew32(RDLEN(0), rx_ring->count * sizeof(union e1000_adv_rx_desc));
        rx_ring->head = E1000_RDH(0);
@@ -1404,8 +1401,8 @@ static void igbvf_set_multi(struct net_device *netdev)
        u8  *mta_list = NULL;
        int i;
 
-       if (netdev->mc_count) {
-               mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
+       if (!netdev_mc_empty(netdev)) {
+               mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC);
                if (!mta_list) {
                        dev_err(&adapter->pdev->dev,
                                "failed to allocate multicast filter list\n");
@@ -1414,15 +1411,9 @@ static void igbvf_set_multi(struct net_device *netdev)
        }
 
        /* prepare a packed array of only addresses. */
-       mc_ptr = netdev->mc_list;
-
-       for (i = 0; i < netdev->mc_count; i++) {
-               if (!mc_ptr)
-                       break;
-               memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr,
-                      ETH_ALEN);
-               mc_ptr = mc_ptr->next;
-       }
+       i = 0;
+       netdev_for_each_mc_addr(mc_ptr, netdev)
+               memcpy(mta_list + (i++ * ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
 
        hw->mac.ops.update_mc_addr_list(hw, mta_list, i, 0, 0);
        kfree(mta_list);
@@ -1470,6 +1461,8 @@ static void igbvf_reset(struct igbvf_adapter *adapter)
                memcpy(netdev->perm_addr, adapter->hw.mac.addr,
                       netdev->addr_len);
        }
+
+       adapter->last_reset = jiffies;
 }
 
 int igbvf_up(struct igbvf_adapter *adapter)
@@ -1529,7 +1522,6 @@ void igbvf_down(struct igbvf_adapter *adapter)
 
        del_timer_sync(&adapter->watchdog_timer);
 
-       netdev->tx_queue_len = adapter->tx_queue_len;
        netif_carrier_off(netdev);
 
        /* record the stats before reset*/
@@ -1813,11 +1805,15 @@ static bool igbvf_has_link(struct igbvf_adapter *adapter)
        s32 ret_val = E1000_SUCCESS;
        bool link_active;
 
+       /* If interface is down, stay link down */
+       if (test_bit(__IGBVF_DOWN, &adapter->state))
+               return false;
+
        ret_val = hw->mac.ops.check_for_link(hw);
        link_active = !hw->mac.get_link_status;
 
        /* if check for link returns error we will need to reset */
-       if (ret_val)
+       if (ret_val && time_after(jiffies, adapter->last_reset + (10 * HZ)))
                schedule_work(&adapter->reset_task);
 
        return link_active;
@@ -1858,21 +1854,15 @@ static void igbvf_watchdog_task(struct work_struct *work)
                                                  &adapter->link_duplex);
                        igbvf_print_link_info(adapter);
 
-                       /*
-                        * tweak tx_queue_len according to speed/duplex
-                        * and adjust the timeout factor
-                        */
-                       netdev->tx_queue_len = adapter->tx_queue_len;
+                       /* adjust timeout factor according to speed/duplex */
                        adapter->tx_timeout_factor = 1;
                        switch (adapter->link_speed) {
                        case SPEED_10:
                                txb2b = 0;
-                               netdev->tx_queue_len = 10;
                                adapter->tx_timeout_factor = 16;
                                break;
                        case SPEED_100:
                                txb2b = 0;
-                               netdev->tx_queue_len = 100;
                                /* maybe add some timeout factor ? */
                                break;
                        }
@@ -1958,7 +1948,7 @@ static int igbvf_tso(struct igbvf_adapter *adapter,
                                                         iph->daddr, 0,
                                                         IPPROTO_TCP,
                                                         0);
-       } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
+       } else if (skb_is_gso_v6(skb)) {
                ipv6_hdr(skb)->payload_len = 0;
                tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
                                                       &ipv6_hdr(skb)->daddr,
@@ -2099,32 +2089,30 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
                                    unsigned int first)
 {
        struct igbvf_buffer *buffer_info;
+       struct pci_dev *pdev = adapter->pdev;
        unsigned int len = skb_headlen(skb);
        unsigned int count = 0, i;
        unsigned int f;
-       dma_addr_t *map;
 
        i = tx_ring->next_to_use;
 
-       if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
-               dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-               return 0;
-       }
-
-       map = skb_shinfo(skb)->dma_maps;
-
        buffer_info = &tx_ring->buffer_info[i];
        BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD);
        buffer_info->length = len;
        /* set time_stamp *before* dma to help avoid a possible race */
        buffer_info->time_stamp = jiffies;
        buffer_info->next_to_watch = i;
-       buffer_info->dma = map[count];
-       count++;
+       buffer_info->mapped_as_page = false;
+       buffer_info->dma = pci_map_single(pdev, skb->data, len,
+                                         PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(pdev, buffer_info->dma))
+               goto dma_error;
+
 
        for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
                struct skb_frag_struct *frag;
 
+               count++;
                i++;
                if (i == tx_ring->count)
                        i = 0;
@@ -2137,14 +2125,43 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
                buffer_info->length = len;
                buffer_info->time_stamp = jiffies;
                buffer_info->next_to_watch = i;
-               buffer_info->dma = map[count];
-               count++;
+               buffer_info->mapped_as_page = true;
+               buffer_info->dma = pci_map_page(pdev,
+                                               frag->page,
+                                               frag->page_offset,
+                                               len,
+                                               PCI_DMA_TODEVICE);
+               if (pci_dma_mapping_error(pdev, buffer_info->dma))
+                       goto dma_error;
        }
 
        tx_ring->buffer_info[i].skb = skb;
        tx_ring->buffer_info[first].next_to_watch = i;
 
-       return count;
+       return ++count;
+
+dma_error:
+       dev_err(&pdev->dev, "TX DMA map failed\n");
+
+       /* clear timestamp and dma mappings for failed buffer_info mapping */
+       buffer_info->dma = 0;
+       buffer_info->time_stamp = 0;
+       buffer_info->length = 0;
+       buffer_info->next_to_watch = 0;
+       buffer_info->mapped_as_page = false;
+       if (count)
+               count--;
+
+       /* clear timestamp and dma mappings for remaining portion of packet */
+       while (count--) {
+               if (i==0)
+                       i += tx_ring->count;
+               i--;
+               buffer_info = &tx_ring->buffer_info[i];
+               igbvf_put_txbuf(adapter, buffer_info);
+       }
+
+       return 0;
 }
 
 static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
@@ -2206,9 +2223,9 @@ static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
        mmiowb();
 }
 
-static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
-                                   struct net_device *netdev,
-                                   struct igbvf_ring *tx_ring)
+static netdev_tx_t igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
+                                            struct net_device *netdev,
+                                            struct igbvf_ring *tx_ring)
 {
        struct igbvf_adapter *adapter = netdev_priv(netdev);
        unsigned int first, tx_flags = 0;
@@ -2281,11 +2298,11 @@ static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
        return NETDEV_TX_OK;
 }
 
-static int igbvf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t igbvf_xmit_frame(struct sk_buff *skb,
+                                   struct net_device *netdev)
 {
        struct igbvf_adapter *adapter = netdev_priv(netdev);
        struct igbvf_ring *tx_ring;
-       int retval;
 
        if (test_bit(__IGBVF_DOWN, &adapter->state)) {
                dev_kfree_skb_any(skb);
@@ -2294,9 +2311,7 @@ static int igbvf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        tx_ring = &adapter->tx_ring[0];
 
-       retval = igbvf_xmit_frame_ring_adv(skb, netdev, tx_ring);
-
-       return retval;
+       return igbvf_xmit_frame_ring_adv(skb, netdev, tx_ring);
 }
 
 /**
@@ -2513,6 +2528,9 @@ static pci_ers_result_t igbvf_io_error_detected(struct pci_dev *pdev,
 
        netif_device_detach(netdev);
 
+       if (state == pci_channel_io_perm_failure)
+               return PCI_ERS_RESULT_DISCONNECT;
+
        if (netif_running(netdev))
                igbvf_down(adapter);
        pci_disable_device(pdev);
@@ -2576,11 +2594,7 @@ static void igbvf_print_device_info(struct igbvf_adapter *adapter)
        struct pci_dev *pdev = adapter->pdev;
 
        dev_info(&pdev->dev, "Intel(R) 82576 Virtual Function\n");
-       dev_info(&pdev->dev, "Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                /* MAC address */
-                netdev->dev_addr[0], netdev->dev_addr[1],
-                netdev->dev_addr[2], netdev->dev_addr[3],
-                netdev->dev_addr[4], netdev->dev_addr[5]);
+       dev_info(&pdev->dev, "Address: %pM\n", netdev->dev_addr);
        dev_info(&pdev->dev, "MAC: %d\n", hw->mac.type);
 }
 
@@ -2629,15 +2643,16 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
                return err;
 
        pci_using_dac = 0;
-       err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
        if (!err) {
-               err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
                if (!err)
                        pci_using_dac = 1;
        } else {
-               err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (err) {
-                       err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+                       err = pci_set_consistent_dma_mask(pdev,
+                                                         DMA_BIT_MASK(32));
                        if (err) {
                                dev_err(&pdev->dev, "No usable DMA "
                                        "configuration, aborting\n");
@@ -2730,7 +2745,8 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
        err = hw->mac.ops.reset_hw(hw);
        if (err) {
                dev_info(&pdev->dev,
-                        "PF still in reset state, assigning new address\n");
+                        "PF still in reset state, assigning new address."
+                        " Is the PF interface up?\n");
                random_ether_addr(hw->mac.addr);
        } else {
                err = hw->mac.ops.read_mac_addr(hw);
@@ -2744,11 +2760,8 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
        memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
 
        if (!is_valid_ether_addr(netdev->perm_addr)) {
-               dev_err(&pdev->dev, "Invalid MAC Address: "
-                       "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       netdev->dev_addr[0], netdev->dev_addr[1],
-                       netdev->dev_addr[2], netdev->dev_addr[3],
-                       netdev->dev_addr[4], netdev->dev_addr[5]);
+               dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
+                       netdev->dev_addr);
                err = -EIO;
                goto err_hw_init;
        }
@@ -2850,7 +2863,7 @@ static struct pci_error_handlers igbvf_err_handler = {
        .resume = igbvf_io_resume,
 };
 
-static struct pci_device_id igbvf_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(igbvf_pci_tbl) = {
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_VF), board_vf },
        { } /* terminate list */
 };