diff options
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 64 |
1 files changed, 24 insertions, 40 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index e0ae248b4313..438a931fd55d 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -711,6 +711,7 @@ e1000_probe(struct pci_dev *pdev, | |||
711 | break; | 711 | break; |
712 | case e1000_82546: | 712 | case e1000_82546: |
713 | case e1000_82546_rev_3: | 713 | case e1000_82546_rev_3: |
714 | case e1000_82571: | ||
714 | if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) | 715 | if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) |
715 | && (adapter->hw.media_type == e1000_media_type_copper)) { | 716 | && (adapter->hw.media_type == e1000_media_type_copper)) { |
716 | e1000_read_eeprom(&adapter->hw, | 717 | e1000_read_eeprom(&adapter->hw, |
@@ -1158,7 +1159,6 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter, | |||
1158 | return -ENOMEM; | 1159 | return -ENOMEM; |
1159 | } | 1160 | } |
1160 | memset(txdr->buffer_info, 0, size); | 1161 | memset(txdr->buffer_info, 0, size); |
1161 | memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer)); | ||
1162 | 1162 | ||
1163 | /* round up to nearest 4K */ | 1163 | /* round up to nearest 4K */ |
1164 | 1164 | ||
@@ -1813,11 +1813,6 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter, | |||
1813 | 1813 | ||
1814 | /* Free all the Tx ring sk_buffs */ | 1814 | /* Free all the Tx ring sk_buffs */ |
1815 | 1815 | ||
1816 | if (likely(tx_ring->previous_buffer_info.skb != NULL)) { | ||
1817 | e1000_unmap_and_free_tx_resource(adapter, | ||
1818 | &tx_ring->previous_buffer_info); | ||
1819 | } | ||
1820 | |||
1821 | for(i = 0; i < tx_ring->count; i++) { | 1816 | for(i = 0; i < tx_ring->count; i++) { |
1822 | buffer_info = &tx_ring->buffer_info[i]; | 1817 | buffer_info = &tx_ring->buffer_info[i]; |
1823 | e1000_unmap_and_free_tx_resource(adapter, buffer_info); | 1818 | e1000_unmap_and_free_tx_resource(adapter, buffer_info); |
@@ -1832,6 +1827,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter, | |||
1832 | 1827 | ||
1833 | tx_ring->next_to_use = 0; | 1828 | tx_ring->next_to_use = 0; |
1834 | tx_ring->next_to_clean = 0; | 1829 | tx_ring->next_to_clean = 0; |
1830 | tx_ring->last_tx_tso = 0; | ||
1835 | 1831 | ||
1836 | writel(0, adapter->hw.hw_addr + tx_ring->tdh); | 1832 | writel(0, adapter->hw.hw_addr + tx_ring->tdh); |
1837 | writel(0, adapter->hw.hw_addr + tx_ring->tdt); | 1833 | writel(0, adapter->hw.hw_addr + tx_ring->tdt); |
@@ -2437,6 +2433,16 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, | |||
2437 | buffer_info = &tx_ring->buffer_info[i]; | 2433 | buffer_info = &tx_ring->buffer_info[i]; |
2438 | size = min(len, max_per_txd); | 2434 | size = min(len, max_per_txd); |
2439 | #ifdef NETIF_F_TSO | 2435 | #ifdef NETIF_F_TSO |
2436 | /* Workaround for Controller erratum -- | ||
2437 | * descriptor for non-tso packet in a linear SKB that follows a | ||
2438 | * tso gets written back prematurely before the data is fully | ||
2439 | * DMAd to the controller */ | ||
2440 | if (!skb->data_len && tx_ring->last_tx_tso && | ||
2441 | !skb_shinfo(skb)->tso_size) { | ||
2442 | tx_ring->last_tx_tso = 0; | ||
2443 | size -= 4; | ||
2444 | } | ||
2445 | |||
2440 | /* Workaround for premature desc write-backs | 2446 | /* Workaround for premature desc write-backs |
2441 | * in TSO mode. Append 4-byte sentinel desc */ | 2447 | * in TSO mode. Append 4-byte sentinel desc */ |
2442 | if(unlikely(mss && !nr_frags && size == len && size > 8)) | 2448 | if(unlikely(mss && !nr_frags && size == len && size > 8)) |
@@ -2693,6 +2699,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2693 | if(skb->ip_summed == CHECKSUM_HW) | 2699 | if(skb->ip_summed == CHECKSUM_HW) |
2694 | count++; | 2700 | count++; |
2695 | #endif | 2701 | #endif |
2702 | |||
2703 | #ifdef NETIF_F_TSO | ||
2704 | /* Controller Erratum workaround */ | ||
2705 | if (!skb->data_len && tx_ring->last_tx_tso && | ||
2706 | !skb_shinfo(skb)->tso_size) | ||
2707 | count++; | ||
2708 | #endif | ||
2709 | |||
2696 | count += TXD_USE_COUNT(len, max_txd_pwr); | 2710 | count += TXD_USE_COUNT(len, max_txd_pwr); |
2697 | 2711 | ||
2698 | if(adapter->pcix_82544) | 2712 | if(adapter->pcix_82544) |
@@ -2774,9 +2788,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2774 | return NETDEV_TX_OK; | 2788 | return NETDEV_TX_OK; |
2775 | } | 2789 | } |
2776 | 2790 | ||
2777 | if (likely(tso)) | 2791 | if (likely(tso)) { |
2792 | tx_ring->last_tx_tso = 1; | ||
2778 | tx_flags |= E1000_TX_FLAGS_TSO; | 2793 | tx_flags |= E1000_TX_FLAGS_TSO; |
2779 | else if (likely(e1000_tx_csum(adapter, tx_ring, skb))) | 2794 | } else if (likely(e1000_tx_csum(adapter, tx_ring, skb))) |
2780 | tx_flags |= E1000_TX_FLAGS_CSUM; | 2795 | tx_flags |= E1000_TX_FLAGS_CSUM; |
2781 | 2796 | ||
2782 | /* Old method was to assume IPv4 packet by default if TSO was enabled. | 2797 | /* Old method was to assume IPv4 packet by default if TSO was enabled. |
@@ -3227,37 +3242,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3227 | eop_desc = E1000_TX_DESC(*tx_ring, eop); | 3242 | eop_desc = E1000_TX_DESC(*tx_ring, eop); |
3228 | 3243 | ||
3229 | while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { | 3244 | while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { |
3230 | /* Premature writeback of Tx descriptors clear (free buffers | ||
3231 | * and unmap pci_mapping) previous_buffer_info */ | ||
3232 | if (likely(tx_ring->previous_buffer_info.skb != NULL)) { | ||
3233 | e1000_unmap_and_free_tx_resource(adapter, | ||
3234 | &tx_ring->previous_buffer_info); | ||
3235 | } | ||
3236 | |||
3237 | for(cleaned = FALSE; !cleaned; ) { | 3245 | for(cleaned = FALSE; !cleaned; ) { |
3238 | tx_desc = E1000_TX_DESC(*tx_ring, i); | 3246 | tx_desc = E1000_TX_DESC(*tx_ring, i); |
3239 | buffer_info = &tx_ring->buffer_info[i]; | 3247 | buffer_info = &tx_ring->buffer_info[i]; |
3240 | cleaned = (i == eop); | 3248 | cleaned = (i == eop); |
3241 | 3249 | ||
3242 | #ifdef NETIF_F_TSO | 3250 | e1000_unmap_and_free_tx_resource(adapter, buffer_info); |
3243 | if (!(netdev->features & NETIF_F_TSO)) { | ||
3244 | #endif | ||
3245 | e1000_unmap_and_free_tx_resource(adapter, | ||
3246 | buffer_info); | ||
3247 | #ifdef NETIF_F_TSO | ||
3248 | } else { | ||
3249 | if (cleaned) { | ||
3250 | memcpy(&tx_ring->previous_buffer_info, | ||
3251 | buffer_info, | ||
3252 | sizeof(struct e1000_buffer)); | ||
3253 | memset(buffer_info, 0, | ||
3254 | sizeof(struct e1000_buffer)); | ||
3255 | } else { | ||
3256 | e1000_unmap_and_free_tx_resource( | ||
3257 | adapter, buffer_info); | ||
3258 | } | ||
3259 | } | ||
3260 | #endif | ||
3261 | 3251 | ||
3262 | tx_desc->buffer_addr = 0; | 3252 | tx_desc->buffer_addr = 0; |
3263 | tx_desc->lower.data = 0; | 3253 | tx_desc->lower.data = 0; |
@@ -3318,12 +3308,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3318 | netif_stop_queue(netdev); | 3308 | netif_stop_queue(netdev); |
3319 | } | 3309 | } |
3320 | } | 3310 | } |
3321 | #ifdef NETIF_F_TSO | ||
3322 | if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && | ||
3323 | time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ))) | ||
3324 | e1000_unmap_and_free_tx_resource( | ||
3325 | adapter, &tx_ring->previous_buffer_info); | ||
3326 | #endif | ||
3327 | return cleaned; | 3311 | return cleaned; |
3328 | } | 3312 | } |
3329 | 3313 | ||