aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igbvf/netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/igbvf/netdev.c')
-rw-r--r--drivers/net/igbvf/netdev.c83
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:
372static void igbvf_put_txbuf(struct igbvf_adapter *adapter, 366static 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
2151dma_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
2144static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter, 2175static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,