diff options
Diffstat (limited to 'drivers/net/igbvf/netdev.c')
-rw-r--r-- | drivers/net/igbvf/netdev.c | 83 |
1 files changed, 57 insertions, 26 deletions
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 91024a3cdad3..a127620dc653 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c | |||
@@ -170,18 +170,12 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring, | |||
170 | } | 170 | } |
171 | 171 | ||
172 | if (!buffer_info->skb) { | 172 | if (!buffer_info->skb) { |
173 | skb = netdev_alloc_skb(netdev, bufsz + NET_IP_ALIGN); | 173 | skb = netdev_alloc_skb_ip_align(netdev, bufsz); |
174 | if (!skb) { | 174 | if (!skb) { |
175 | adapter->alloc_rx_buff_failed++; | 175 | adapter->alloc_rx_buff_failed++; |
176 | goto no_buffers; | 176 | goto no_buffers; |
177 | } | 177 | } |
178 | 178 | ||
179 | /* Make buffer alignment 2 beyond a 16 byte boundary | ||
180 | * this will result in a 16 byte aligned IP header after | ||
181 | * the 14 byte MAC header is removed | ||
182 | */ | ||
183 | skb_reserve(skb, NET_IP_ALIGN); | ||
184 | |||
185 | buffer_info->skb = skb; | 179 | buffer_info->skb = skb; |
186 | buffer_info->dma = pci_map_single(pdev, skb->data, | 180 | buffer_info->dma = pci_map_single(pdev, skb->data, |
187 | bufsz, | 181 | bufsz, |
@@ -372,10 +366,20 @@ next_desc: | |||
372 | static void igbvf_put_txbuf(struct igbvf_adapter *adapter, | 366 | static void igbvf_put_txbuf(struct igbvf_adapter *adapter, |
373 | struct igbvf_buffer *buffer_info) | 367 | struct igbvf_buffer *buffer_info) |
374 | { | 368 | { |
375 | buffer_info->dma = 0; | 369 | if (buffer_info->dma) { |
370 | if (buffer_info->mapped_as_page) | ||
371 | pci_unmap_page(adapter->pdev, | ||
372 | buffer_info->dma, | ||
373 | buffer_info->length, | ||
374 | PCI_DMA_TODEVICE); | ||
375 | else | ||
376 | pci_unmap_single(adapter->pdev, | ||
377 | buffer_info->dma, | ||
378 | buffer_info->length, | ||
379 | PCI_DMA_TODEVICE); | ||
380 | buffer_info->dma = 0; | ||
381 | } | ||
376 | if (buffer_info->skb) { | 382 | if (buffer_info->skb) { |
377 | skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb, | ||
378 | DMA_TO_DEVICE); | ||
379 | dev_kfree_skb_any(buffer_info->skb); | 383 | dev_kfree_skb_any(buffer_info->skb); |
380 | buffer_info->skb = NULL; | 384 | buffer_info->skb = NULL; |
381 | } | 385 | } |
@@ -823,8 +827,8 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring) | |||
823 | adapter->detect_tx_hung = false; | 827 | adapter->detect_tx_hung = false; |
824 | if (tx_ring->buffer_info[i].time_stamp && | 828 | if (tx_ring->buffer_info[i].time_stamp && |
825 | time_after(jiffies, tx_ring->buffer_info[i].time_stamp + | 829 | time_after(jiffies, tx_ring->buffer_info[i].time_stamp + |
826 | (adapter->tx_timeout_factor * HZ)) | 830 | (adapter->tx_timeout_factor * HZ)) && |
827 | && !(er32(STATUS) & E1000_STATUS_TXOFF)) { | 831 | !(er32(STATUS) & E1000_STATUS_TXOFF)) { |
828 | 832 | ||
829 | tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i); | 833 | tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i); |
830 | /* detected Tx unit hang */ | 834 | /* detected Tx unit hang */ |
@@ -1049,7 +1053,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter) | |||
1049 | } | 1053 | } |
1050 | 1054 | ||
1051 | err = request_irq(adapter->msix_entries[vector].vector, | 1055 | err = request_irq(adapter->msix_entries[vector].vector, |
1052 | &igbvf_intr_msix_tx, 0, adapter->tx_ring->name, | 1056 | igbvf_intr_msix_tx, 0, adapter->tx_ring->name, |
1053 | netdev); | 1057 | netdev); |
1054 | if (err) | 1058 | if (err) |
1055 | goto out; | 1059 | goto out; |
@@ -1059,7 +1063,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter) | |||
1059 | vector++; | 1063 | vector++; |
1060 | 1064 | ||
1061 | err = request_irq(adapter->msix_entries[vector].vector, | 1065 | err = request_irq(adapter->msix_entries[vector].vector, |
1062 | &igbvf_intr_msix_rx, 0, adapter->rx_ring->name, | 1066 | igbvf_intr_msix_rx, 0, adapter->rx_ring->name, |
1063 | netdev); | 1067 | netdev); |
1064 | if (err) | 1068 | if (err) |
1065 | goto out; | 1069 | goto out; |
@@ -1069,7 +1073,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter) | |||
1069 | vector++; | 1073 | vector++; |
1070 | 1074 | ||
1071 | err = request_irq(adapter->msix_entries[vector].vector, | 1075 | err = request_irq(adapter->msix_entries[vector].vector, |
1072 | &igbvf_msix_other, 0, netdev->name, netdev); | 1076 | igbvf_msix_other, 0, netdev->name, netdev); |
1073 | if (err) | 1077 | if (err) |
1074 | goto out; | 1078 | goto out; |
1075 | 1079 | ||
@@ -2094,27 +2098,24 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, | |||
2094 | unsigned int first) | 2098 | unsigned int first) |
2095 | { | 2099 | { |
2096 | struct igbvf_buffer *buffer_info; | 2100 | struct igbvf_buffer *buffer_info; |
2101 | struct pci_dev *pdev = adapter->pdev; | ||
2097 | unsigned int len = skb_headlen(skb); | 2102 | unsigned int len = skb_headlen(skb); |
2098 | unsigned int count = 0, i; | 2103 | unsigned int count = 0, i; |
2099 | unsigned int f; | 2104 | unsigned int f; |
2100 | dma_addr_t *map; | ||
2101 | 2105 | ||
2102 | i = tx_ring->next_to_use; | 2106 | i = tx_ring->next_to_use; |
2103 | 2107 | ||
2104 | if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) { | ||
2105 | dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); | ||
2106 | return 0; | ||
2107 | } | ||
2108 | |||
2109 | map = skb_shinfo(skb)->dma_maps; | ||
2110 | |||
2111 | buffer_info = &tx_ring->buffer_info[i]; | 2108 | buffer_info = &tx_ring->buffer_info[i]; |
2112 | BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD); | 2109 | BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD); |
2113 | buffer_info->length = len; | 2110 | buffer_info->length = len; |
2114 | /* set time_stamp *before* dma to help avoid a possible race */ | 2111 | /* set time_stamp *before* dma to help avoid a possible race */ |
2115 | buffer_info->time_stamp = jiffies; | 2112 | buffer_info->time_stamp = jiffies; |
2116 | buffer_info->next_to_watch = i; | 2113 | buffer_info->next_to_watch = i; |
2117 | buffer_info->dma = skb_shinfo(skb)->dma_head; | 2114 | buffer_info->dma = pci_map_single(pdev, skb->data, len, |
2115 | PCI_DMA_TODEVICE); | ||
2116 | if (pci_dma_mapping_error(pdev, buffer_info->dma)) | ||
2117 | goto dma_error; | ||
2118 | |||
2118 | 2119 | ||
2119 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { | 2120 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { |
2120 | struct skb_frag_struct *frag; | 2121 | struct skb_frag_struct *frag; |
@@ -2131,14 +2132,44 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, | |||
2131 | buffer_info->length = len; | 2132 | buffer_info->length = len; |
2132 | buffer_info->time_stamp = jiffies; | 2133 | buffer_info->time_stamp = jiffies; |
2133 | buffer_info->next_to_watch = i; | 2134 | buffer_info->next_to_watch = i; |
2134 | buffer_info->dma = map[count]; | 2135 | buffer_info->mapped_as_page = true; |
2136 | buffer_info->dma = pci_map_page(pdev, | ||
2137 | frag->page, | ||
2138 | frag->page_offset, | ||
2139 | len, | ||
2140 | PCI_DMA_TODEVICE); | ||
2141 | if (pci_dma_mapping_error(pdev, buffer_info->dma)) | ||
2142 | goto dma_error; | ||
2135 | count++; | 2143 | count++; |
2136 | } | 2144 | } |
2137 | 2145 | ||
2138 | tx_ring->buffer_info[i].skb = skb; | 2146 | tx_ring->buffer_info[i].skb = skb; |
2139 | tx_ring->buffer_info[first].next_to_watch = i; | 2147 | tx_ring->buffer_info[first].next_to_watch = i; |
2140 | 2148 | ||
2141 | return count + 1; | 2149 | return ++count; |
2150 | |||
2151 | dma_error: | ||
2152 | dev_err(&pdev->dev, "TX DMA map failed\n"); | ||
2153 | |||
2154 | /* clear timestamp and dma mappings for failed buffer_info mapping */ | ||
2155 | buffer_info->dma = 0; | ||
2156 | buffer_info->time_stamp = 0; | ||
2157 | buffer_info->length = 0; | ||
2158 | buffer_info->next_to_watch = 0; | ||
2159 | buffer_info->mapped_as_page = false; | ||
2160 | count--; | ||
2161 | |||
2162 | /* clear timestamp and dma mappings for remaining portion of packet */ | ||
2163 | while (count >= 0) { | ||
2164 | count--; | ||
2165 | i--; | ||
2166 | if (i < 0) | ||
2167 | i += tx_ring->count; | ||
2168 | buffer_info = &tx_ring->buffer_info[i]; | ||
2169 | igbvf_put_txbuf(adapter, buffer_info); | ||
2170 | } | ||
2171 | |||
2172 | return 0; | ||
2142 | } | 2173 | } |
2143 | 2174 | ||
2144 | static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter, | 2175 | static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter, |