]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/e1000/e1000_main.c
[PATCH] e1000: General Fixes
[linux-2.6-omap-h63xx.git] / drivers / net / e1000 / e1000_main.c
index 6b72f6acdd54eca353552cba53c111bff4efb66d..22c8286a484962bb2b5f6c77c376ca0e626d9b10 100644 (file)
  */
 
 char e1000_driver_name[] = "e1000";
-char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
+static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
 #ifndef CONFIG_E1000_NAPI
 #define DRIVERNAPI
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION "6.1.16-k2"DRIVERNAPI
+#define DRV_VERSION "6.3.9-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
-char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
+static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
  *
@@ -112,14 +112,14 @@ int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
 int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-int e1000_setup_tx_resources(struct e1000_adapter *adapter,
-                             struct e1000_tx_ring *txdr);
-int e1000_setup_rx_resources(struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rxdr);
-void e1000_free_tx_resources(struct e1000_adapter *adapter,
-                             struct e1000_tx_ring *tx_ring);
-void e1000_free_rx_resources(struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rx_ring);
+static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
+                                   struct e1000_tx_ring *txdr);
+static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
+                                   struct e1000_rx_ring *rxdr);
+static void e1000_free_tx_resources(struct e1000_adapter *adapter,
+                                   struct e1000_tx_ring *tx_ring);
+static void e1000_free_rx_resources(struct e1000_adapter *adapter,
+                                   struct e1000_rx_ring *rx_ring);
 void e1000_update_stats(struct e1000_adapter *adapter);
 
 /* Local Function Prototypes */
@@ -191,8 +191,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 static int e1000_resume(struct pci_dev *pdev);
 #endif
 
@@ -296,7 +296,8 @@ e1000_irq_enable(struct e1000_adapter *adapter)
                E1000_WRITE_FLUSH(&adapter->hw);
        }
 }
-void
+
+static void
 e1000_update_mng_vlan(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
@@ -448,7 +449,7 @@ e1000_reset(struct e1000_adapter *adapter)
        }
 
        if((adapter->hw.mac_type != e1000_82573) &&
-          (adapter->rx_buffer_len > E1000_RXBUFFER_8192)) {
+          (adapter->netdev->mtu > E1000_RXBUFFER_8192)) {
                pba -= 8; /* allocate more FIFO for Tx */
                /* send an XOFF when there is enough space in the
                 * Rx FIFO to hold one extra full size Rx packet 
@@ -710,6 +711,7 @@ e1000_probe(struct pci_dev *pdev,
                break;
        case e1000_82546:
        case e1000_82546_rev_3:
+       case e1000_82571:
                if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
                   && (adapter->hw.media_type == e1000_media_type_copper)) {
                        e1000_read_eeprom(&adapter->hw,
@@ -1141,7 +1143,7 @@ e1000_check_64k_bound(struct e1000_adapter *adapter,
  * Return 0 on success, negative on failure
  **/
 
-int
+static int
 e1000_setup_tx_resources(struct e1000_adapter *adapter,
                          struct e1000_tx_ring *txdr)
 {
@@ -1149,14 +1151,14 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter,
        int size;
 
        size = sizeof(struct e1000_buffer) * txdr->count;
-       txdr->buffer_info = vmalloc(size);
+
+       txdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
        if(!txdr->buffer_info) {
                DPRINTK(PROBE, ERR,
                "Unable to allocate memory for the transmit descriptor ring\n");
                return -ENOMEM;
        }
        memset(txdr->buffer_info, 0, size);
-       memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
 
        /* round up to nearest 4K */
 
@@ -1358,7 +1360,7 @@ e1000_configure_tx(struct e1000_adapter *adapter)
  * Returns 0 on success, negative on failure
  **/
 
-int
+static int
 e1000_setup_rx_resources(struct e1000_adapter *adapter,
                          struct e1000_rx_ring *rxdr)
 {
@@ -1366,7 +1368,7 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter,
        int size, desc_len;
 
        size = sizeof(struct e1000_buffer) * rxdr->count;
-       rxdr->buffer_info = vmalloc(size);
+       rxdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
        if (!rxdr->buffer_info) {
                DPRINTK(PROBE, ERR,
                "Unable to allocate memory for the receive descriptor ring\n");
@@ -1746,7 +1748,7 @@ e1000_configure_rx(struct e1000_adapter *adapter)
  * Free all transmit software resources
  **/
 
-void
+static void
 e1000_free_tx_resources(struct e1000_adapter *adapter,
                         struct e1000_tx_ring *tx_ring)
 {
@@ -1811,11 +1813,6 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
 
        /* Free all the Tx ring sk_buffs */
 
-       if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
-               e1000_unmap_and_free_tx_resource(adapter,
-                               &tx_ring->previous_buffer_info);
-       }
-
        for(i = 0; i < tx_ring->count; i++) {
                buffer_info = &tx_ring->buffer_info[i];
                e1000_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -1830,6 +1827,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
 
        tx_ring->next_to_use = 0;
        tx_ring->next_to_clean = 0;
+       tx_ring->last_tx_tso = 0;
 
        writel(0, adapter->hw.hw_addr + tx_ring->tdh);
        writel(0, adapter->hw.hw_addr + tx_ring->tdt);
@@ -1857,7 +1855,7 @@ e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
  * Free all receive software resources
  **/
 
-void
+static void
 e1000_free_rx_resources(struct e1000_adapter *adapter,
                         struct e1000_rx_ring *rx_ring)
 {
@@ -2206,7 +2204,7 @@ static void
 e1000_watchdog_task(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       struct e1000_tx_ring *txdr = &adapter->tx_ring[0];
+       struct e1000_tx_ring *txdr = adapter->tx_ring;
        uint32_t link;
 
        e1000_check_for_link(&adapter->hw);
@@ -2316,6 +2314,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
 {
 #ifdef NETIF_F_TSO
        struct e1000_context_desc *context_desc;
+       struct e1000_buffer *buffer_info;
        unsigned int i;
        uint32_t cmd_length = 0;
        uint16_t ipcse = 0, tucse, mss;
@@ -2365,6 +2364,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
 
                i = tx_ring->next_to_use;
                context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
+               buffer_info = &tx_ring->buffer_info[i];
 
                context_desc->lower_setup.ip_fields.ipcss  = ipcss;
                context_desc->lower_setup.ip_fields.ipcso  = ipcso;
@@ -2376,6 +2376,8 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
                context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
                context_desc->cmd_and_length = cpu_to_le32(cmd_length);
 
+               buffer_info->time_stamp = jiffies;
+
                if (++i == tx_ring->count) i = 0;
                tx_ring->next_to_use = i;
 
@@ -2391,6 +2393,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
               struct sk_buff *skb)
 {
        struct e1000_context_desc *context_desc;
+       struct e1000_buffer *buffer_info;
        unsigned int i;
        uint8_t css;
 
@@ -2398,6 +2401,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
                css = skb->h.raw - skb->data;
 
                i = tx_ring->next_to_use;
+               buffer_info = &tx_ring->buffer_info[i];
                context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
 
                context_desc->upper_setup.tcp_fields.tucss = css;
@@ -2406,6 +2410,8 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
                context_desc->tcp_seg_setup.data = 0;
                context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
 
+               buffer_info->time_stamp = jiffies;
+
                if (unlikely(++i == tx_ring->count)) i = 0;
                tx_ring->next_to_use = i;
 
@@ -2435,6 +2441,16 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
                buffer_info = &tx_ring->buffer_info[i];
                size = min(len, max_per_txd);
 #ifdef NETIF_F_TSO
+               /* Workaround for Controller erratum --
+                * descriptor for non-tso packet in a linear SKB that follows a
+                * tso gets written back prematurely before the data is fully
+                * DMAd to the controller */
+               if (!skb->data_len && tx_ring->last_tx_tso &&
+                               !skb_shinfo(skb)->tso_size) {
+                       tx_ring->last_tx_tso = 0;
+                       size -= 4;
+               }
+
                /* Workaround for premature desc write-backs
                 * in TSO mode.  Append 4-byte sentinel desc */
                if(unlikely(mss && !nr_frags && size == len && size > 8))
@@ -2619,19 +2635,7 @@ e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
                          E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
                        return 0;
        }
-       if(htons(ETH_P_IP) == skb->protocol) {
-               const struct iphdr *ip = skb->nh.iph;
-               if(IPPROTO_UDP == ip->protocol) {
-                       struct udphdr *udp = (struct udphdr *)(skb->h.uh);
-                       if(ntohs(udp->dest) == 67) {
-                               offset = (uint8_t *)udp + 8 - skb->data;
-                               length = skb->len - offset;
-
-                               return e1000_mng_write_dhcp_info(hw,
-                                               (uint8_t *)udp + 8, length);
-                       }
-               }
-       } else if((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
+       if ((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
                struct ethhdr *eth = (struct ethhdr *) skb->data;
                if((htons(ETH_P_IP) == eth->h_proto)) {
                        const struct iphdr *ip = 
@@ -2692,17 +2696,37 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
         * overrun the FIFO, adjust the max buffer len if mss
         * drops. */
        if(mss) {
+               uint8_t hdr_len;
                max_per_txd = min(mss << 2, max_per_txd);
                max_txd_pwr = fls(max_per_txd) - 1;
+
+       /* TSO Workaround for 82571/2 Controllers -- if skb->data
+        * points to just header, pull a few bytes of payload from
+        * frags into skb->data */
+               hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+               if (skb->data_len && (hdr_len == (skb->len - skb->data_len)) &&
+                       (adapter->hw.mac_type == e1000_82571 ||
+                       adapter->hw.mac_type == e1000_82572)) {
+                       len = skb->len - skb->data_len;
+               }
        }
 
        if((mss) || (skb->ip_summed == CHECKSUM_HW))
+       /* reserve a descriptor for the offload context */
                count++;
        count++;
 #else
        if(skb->ip_summed == CHECKSUM_HW)
                count++;
 #endif
+
+#ifdef NETIF_F_TSO
+       /* Controller Erratum workaround */
+       if (!skb->data_len && tx_ring->last_tx_tso &&
+               !skb_shinfo(skb)->tso_size)
+               count++;
+#endif
+
        count += TXD_USE_COUNT(len, max_txd_pwr);
 
        if(adapter->pcix_82544)
@@ -2722,26 +2746,13 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        if(adapter->pcix_82544)
                count += nr_frags;
 
-#ifdef NETIF_F_TSO
-       /* TSO Workaround for 82571/2 Controllers -- if skb->data
-        * points to just header, pull a few bytes of payload from 
-        * frags into skb->data */
-       if (skb_shinfo(skb)->tso_size) {
-               uint8_t hdr_len;
-               hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
-               if (skb->data_len && (hdr_len < (skb->len - skb->data_len)) && 
-                       (adapter->hw.mac_type == e1000_82571 ||
-                       adapter->hw.mac_type == e1000_82572)) {
-                       unsigned int pull_size;
-                       pull_size = min((unsigned int)4, skb->data_len);
-                       if (!__pskb_pull_tail(skb, pull_size)) {
-                               printk(KERN_ERR "__pskb_pull_tail failed.\n");
-                               dev_kfree_skb_any(skb);
-                               return -EFAULT;
-                       }
+               unsigned int pull_size;
+               pull_size = min((unsigned int)4, skb->data_len);
+               if (!__pskb_pull_tail(skb, pull_size)) {
+                       printk(KERN_ERR "__pskb_pull_tail failed.\n");
+                       dev_kfree_skb_any(skb);
+                       return -EFAULT;
                }
-       }
-#endif
 
        if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
                e1000_transfer_dhcp_info(adapter, skb);
@@ -2784,9 +2795,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                return NETDEV_TX_OK;
        }
 
-       if (likely(tso))
+       if (likely(tso)) {
+               tx_ring->last_tx_tso = 1;
                tx_flags |= E1000_TX_FLAGS_TSO;
-       else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
+       else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
                tx_flags |= E1000_TX_FLAGS_CSUM;
 
        /* Old method was to assume IPv4 packet by default if TSO was enabled.
@@ -3237,37 +3249,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
        eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
        while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-               /* Premature writeback of Tx descriptors clear (free buffers
-                * and unmap pci_mapping) previous_buffer_info */
-               if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
-                       e1000_unmap_and_free_tx_resource(adapter,
-                                       &tx_ring->previous_buffer_info);
-               }
-
                for(cleaned = FALSE; !cleaned; ) {
                        tx_desc = E1000_TX_DESC(*tx_ring, i);
                        buffer_info = &tx_ring->buffer_info[i];
                        cleaned = (i == eop);
 
-#ifdef NETIF_F_TSO
-                       if (!(netdev->features & NETIF_F_TSO)) {
-#endif
-                               e1000_unmap_and_free_tx_resource(adapter,
-                                                                buffer_info);
-#ifdef NETIF_F_TSO
-                       } else {
-                               if (cleaned) {
-                                       memcpy(&tx_ring->previous_buffer_info,
-                                              buffer_info,
-                                              sizeof(struct e1000_buffer));
-                                       memset(buffer_info, 0,
-                                              sizeof(struct e1000_buffer));
-                               } else {
-                                       e1000_unmap_and_free_tx_resource(
-                                           adapter, buffer_info);
-                               }
-                       }
-#endif
+                       e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 
                        tx_desc->buffer_addr = 0;
                        tx_desc->lower.data = 0;
@@ -3276,8 +3263,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
                        if(unlikely(++i == tx_ring->count)) i = 0;
                }
 
-               tx_ring->pkt++;
-               
                eop = tx_ring->buffer_info[i].next_to_watch;
                eop_desc = E1000_TX_DESC(*tx_ring, eop);
        }
@@ -3328,12 +3313,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
                        netif_stop_queue(netdev);
                }
        }
-#ifdef NETIF_F_TSO
-       if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
-           time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
-               e1000_unmap_and_free_tx_resource(
-                   adapter, &tx_ring->previous_buffer_info);
-#endif
        return cleaned;
 }
 
@@ -3488,7 +3467,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
                }
 #endif /* CONFIG_E1000_NAPI */
                netdev->last_rx = jiffies;
-               rx_ring->pkt++;
 
 next_desc:
                rx_desc->status = 0;
@@ -3619,7 +3597,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                }
 #endif /* CONFIG_E1000_NAPI */
                netdev->last_rx = jiffies;
-               rx_ring->pkt++;
 
 next_desc:
                rx_desc->wb.middle.status_error &= ~0xFF;
@@ -4193,6 +4170,7 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int
 e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 {
@@ -4289,7 +4267,6 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
        return 0;
 }
 
-#ifdef CONFIG_PM
 static int
 e1000_resume(struct pci_dev *pdev)
 {