diff options
-rw-r--r-- | drivers/net/ixgb/ixgb_main.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index c1dde795a837..365212b9e952 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -98,7 +98,7 @@ static bool ixgb_clean_rx_irq(struct ixgb_adapter *, int *, int); | |||
98 | #else | 98 | #else |
99 | static bool ixgb_clean_rx_irq(struct ixgb_adapter *); | 99 | static bool ixgb_clean_rx_irq(struct ixgb_adapter *); |
100 | #endif | 100 | #endif |
101 | static void ixgb_alloc_rx_buffers(struct ixgb_adapter *); | 101 | static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int); |
102 | 102 | ||
103 | static void ixgb_tx_timeout(struct net_device *dev); | 103 | static void ixgb_tx_timeout(struct net_device *dev); |
104 | static void ixgb_tx_timeout_task(struct work_struct *work); | 104 | static void ixgb_tx_timeout_task(struct work_struct *work); |
@@ -225,7 +225,7 @@ ixgb_up(struct ixgb_adapter *adapter) | |||
225 | ixgb_configure_tx(adapter); | 225 | ixgb_configure_tx(adapter); |
226 | ixgb_setup_rctl(adapter); | 226 | ixgb_setup_rctl(adapter); |
227 | ixgb_configure_rx(adapter); | 227 | ixgb_configure_rx(adapter); |
228 | ixgb_alloc_rx_buffers(adapter); | 228 | ixgb_alloc_rx_buffers(adapter, IXGB_DESC_UNUSED(&adapter->rx_ring)); |
229 | 229 | ||
230 | /* disable interrupts and get the hardware into a known state */ | 230 | /* disable interrupts and get the hardware into a known state */ |
231 | IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff); | 231 | IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff); |
@@ -1906,6 +1906,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) | |||
1906 | struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer; | 1906 | struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer; |
1907 | u32 length; | 1907 | u32 length; |
1908 | unsigned int i, j; | 1908 | unsigned int i, j; |
1909 | int cleaned_count = 0; | ||
1909 | bool cleaned = false; | 1910 | bool cleaned = false; |
1910 | 1911 | ||
1911 | i = rx_ring->next_to_clean; | 1912 | i = rx_ring->next_to_clean; |
@@ -1913,7 +1914,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) | |||
1913 | buffer_info = &rx_ring->buffer_info[i]; | 1914 | buffer_info = &rx_ring->buffer_info[i]; |
1914 | 1915 | ||
1915 | while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) { | 1916 | while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) { |
1916 | struct sk_buff *skb, *next_skb; | 1917 | struct sk_buff *skb; |
1917 | u8 status; | 1918 | u8 status; |
1918 | 1919 | ||
1919 | #ifdef CONFIG_IXGB_NAPI | 1920 | #ifdef CONFIG_IXGB_NAPI |
@@ -1926,7 +1927,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) | |||
1926 | skb = buffer_info->skb; | 1927 | skb = buffer_info->skb; |
1927 | buffer_info->skb = NULL; | 1928 | buffer_info->skb = NULL; |
1928 | 1929 | ||
1929 | prefetch(skb->data); | 1930 | prefetch(skb->data - NET_IP_ALIGN); |
1930 | 1931 | ||
1931 | if (++i == rx_ring->count) i = 0; | 1932 | if (++i == rx_ring->count) i = 0; |
1932 | next_rxd = IXGB_RX_DESC(*rx_ring, i); | 1933 | next_rxd = IXGB_RX_DESC(*rx_ring, i); |
@@ -1937,17 +1938,18 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) | |||
1937 | prefetch(next2_buffer); | 1938 | prefetch(next2_buffer); |
1938 | 1939 | ||
1939 | next_buffer = &rx_ring->buffer_info[i]; | 1940 | next_buffer = &rx_ring->buffer_info[i]; |
1940 | next_skb = next_buffer->skb; | ||
1941 | prefetch(next_skb); | ||
1942 | 1941 | ||
1943 | cleaned = true; | 1942 | cleaned = true; |
1943 | cleaned_count++; | ||
1944 | 1944 | ||
1945 | pci_unmap_single(pdev, | 1945 | pci_unmap_single(pdev, |
1946 | buffer_info->dma, | 1946 | buffer_info->dma, |
1947 | buffer_info->length, | 1947 | buffer_info->length, |
1948 | PCI_DMA_FROMDEVICE); | 1948 | PCI_DMA_FROMDEVICE); |
1949 | buffer_info->dma = 0; | ||
1949 | 1950 | ||
1950 | length = le16_to_cpu(rx_desc->length); | 1951 | length = le16_to_cpu(rx_desc->length); |
1952 | rx_desc->length = 0; | ||
1951 | 1953 | ||
1952 | if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) { | 1954 | if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) { |
1953 | 1955 | ||
@@ -2016,6 +2018,12 @@ rxdesc_done: | |||
2016 | /* clean up descriptor, might be written over by hw */ | 2018 | /* clean up descriptor, might be written over by hw */ |
2017 | rx_desc->status = 0; | 2019 | rx_desc->status = 0; |
2018 | 2020 | ||
2021 | /* return some buffers to hardware, one at a time is too slow */ | ||
2022 | if (unlikely(cleaned_count >= IXGB_RX_BUFFER_WRITE)) { | ||
2023 | ixgb_alloc_rx_buffers(adapter, cleaned_count); | ||
2024 | cleaned_count = 0; | ||
2025 | } | ||
2026 | |||
2019 | /* use prefetched values */ | 2027 | /* use prefetched values */ |
2020 | rx_desc = next_rxd; | 2028 | rx_desc = next_rxd; |
2021 | buffer_info = next_buffer; | 2029 | buffer_info = next_buffer; |
@@ -2023,7 +2031,9 @@ rxdesc_done: | |||
2023 | 2031 | ||
2024 | rx_ring->next_to_clean = i; | 2032 | rx_ring->next_to_clean = i; |
2025 | 2033 | ||
2026 | ixgb_alloc_rx_buffers(adapter); | 2034 | cleaned_count = IXGB_DESC_UNUSED(rx_ring); |
2035 | if (cleaned_count) | ||
2036 | ixgb_alloc_rx_buffers(adapter, cleaned_count); | ||
2027 | 2037 | ||
2028 | return cleaned; | 2038 | return cleaned; |
2029 | } | 2039 | } |
@@ -2034,7 +2044,7 @@ rxdesc_done: | |||
2034 | **/ | 2044 | **/ |
2035 | 2045 | ||
2036 | static void | 2046 | static void |
2037 | ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) | 2047 | ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count) |
2038 | { | 2048 | { |
2039 | struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; | 2049 | struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; |
2040 | struct net_device *netdev = adapter->netdev; | 2050 | struct net_device *netdev = adapter->netdev; |
@@ -2051,7 +2061,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) | |||
2051 | 2061 | ||
2052 | 2062 | ||
2053 | /* leave three descriptors unused */ | 2063 | /* leave three descriptors unused */ |
2054 | while (--cleancount > 2) { | 2064 | while (--cleancount > 2 && cleaned_count--) { |
2055 | /* recycle! its good for you */ | 2065 | /* recycle! its good for you */ |
2056 | skb = buffer_info->skb; | 2066 | skb = buffer_info->skb; |
2057 | if (skb) { | 2067 | if (skb) { |