aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgb')
-rw-r--r--drivers/net/ixgb/ixgb.h1
-rw-r--r--drivers/net/ixgb/ixgb_main.c60
2 files changed, 42 insertions, 19 deletions
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index e95d9b6f1f2..5257ae08b9f 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -117,6 +117,7 @@ struct ixgb_buffer {
117 unsigned long time_stamp; 117 unsigned long time_stamp;
118 u16 length; 118 u16 length;
119 u16 next_to_watch; 119 u16 next_to_watch;
120 u16 mapped_as_page;
120}; 121};
121 122
122struct ixgb_desc_ring { 123struct ixgb_desc_ring {
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 73646062e8d..bcd0f01d5fe 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -892,10 +892,18 @@ static void
892ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter, 892ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
893 struct ixgb_buffer *buffer_info) 893 struct ixgb_buffer *buffer_info)
894{ 894{
895 buffer_info->dma = 0; 895 if (buffer_info->dma) {
896 if (buffer_info->mapped_as_page)
897 pci_unmap_page(adapter->pdev, buffer_info->dma,
898 buffer_info->length, PCI_DMA_TODEVICE);
899 else
900 pci_unmap_single(adapter->pdev, buffer_info->dma,
901 buffer_info->length,
902 PCI_DMA_TODEVICE);
903 buffer_info->dma = 0;
904 }
905
896 if (buffer_info->skb) { 906 if (buffer_info->skb) {
897 skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
898 DMA_TO_DEVICE);
899 dev_kfree_skb_any(buffer_info->skb); 907 dev_kfree_skb_any(buffer_info->skb);
900 buffer_info->skb = NULL; 908 buffer_info->skb = NULL;
901 } 909 }
@@ -1272,24 +1280,16 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
1272 unsigned int first) 1280 unsigned int first)
1273{ 1281{
1274 struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; 1282 struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
1283 struct pci_dev *pdev = adapter->pdev;
1275 struct ixgb_buffer *buffer_info; 1284 struct ixgb_buffer *buffer_info;
1276 int len = skb_headlen(skb); 1285 int len = skb_headlen(skb);
1277 unsigned int offset = 0, size, count = 0, i; 1286 unsigned int offset = 0, size, count = 0, i;
1278 unsigned int mss = skb_shinfo(skb)->gso_size; 1287 unsigned int mss = skb_shinfo(skb)->gso_size;
1279
1280 unsigned int nr_frags = skb_shinfo(skb)->nr_frags; 1288 unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
1281 unsigned int f; 1289 unsigned int f;
1282 dma_addr_t *map;
1283 1290
1284 i = tx_ring->next_to_use; 1291 i = tx_ring->next_to_use;
1285 1292
1286 if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
1287 dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
1288 return 0;
1289 }
1290
1291 map = skb_shinfo(skb)->dma_maps;
1292
1293 while (len) { 1293 while (len) {
1294 buffer_info = &tx_ring->buffer_info[i]; 1294 buffer_info = &tx_ring->buffer_info[i];
1295 size = min(len, IXGB_MAX_DATA_PER_TXD); 1295 size = min(len, IXGB_MAX_DATA_PER_TXD);
@@ -1301,11 +1301,11 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
1301 buffer_info->length = size; 1301 buffer_info->length = size;
1302 WARN_ON(buffer_info->dma != 0); 1302 WARN_ON(buffer_info->dma != 0);
1303 buffer_info->time_stamp = jiffies; 1303 buffer_info->time_stamp = jiffies;
1304 buffer_info->dma = skb_shinfo(skb)->dma_head + offset; 1304 buffer_info->mapped_as_page = false;
1305 pci_map_single(adapter->pdev, 1305 buffer_info->dma = pci_map_single(pdev, skb->data + offset,
1306 skb->data + offset, 1306 size, PCI_DMA_TODEVICE);
1307 size, 1307 if (pci_dma_mapping_error(pdev, buffer_info->dma))
1308 PCI_DMA_TODEVICE); 1308 goto dma_error;
1309 buffer_info->next_to_watch = 0; 1309 buffer_info->next_to_watch = 0;
1310 1310
1311 len -= size; 1311 len -= size;
@@ -1323,7 +1323,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
1323 1323
1324 frag = &skb_shinfo(skb)->frags[f]; 1324 frag = &skb_shinfo(skb)->frags[f];
1325 len = frag->size; 1325 len = frag->size;
1326 offset = 0; 1326 offset = frag->page_offset;
1327 1327
1328 while (len) { 1328 while (len) {
1329 i++; 1329 i++;
@@ -1341,7 +1341,13 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
1341 1341
1342 buffer_info->length = size; 1342 buffer_info->length = size;
1343 buffer_info->time_stamp = jiffies; 1343 buffer_info->time_stamp = jiffies;
1344 buffer_info->dma = map[f] + offset; 1344 buffer_info->mapped_as_page = true;
1345 buffer_info->dma =
1346 pci_map_page(pdev, frag->page,
1347 offset, size,
1348 PCI_DMA_TODEVICE);
1349 if (pci_dma_mapping_error(pdev, buffer_info->dma))
1350 goto dma_error;
1345 buffer_info->next_to_watch = 0; 1351 buffer_info->next_to_watch = 0;
1346 1352
1347 len -= size; 1353 len -= size;
@@ -1353,6 +1359,22 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
1353 tx_ring->buffer_info[first].next_to_watch = i; 1359 tx_ring->buffer_info[first].next_to_watch = i;
1354 1360
1355 return count; 1361 return count;
1362
1363dma_error:
1364 dev_err(&pdev->dev, "TX DMA map failed\n");
1365 buffer_info->dma = 0;
1366 count--;
1367
1368 while (count >= 0) {
1369 count--;
1370 i--;
1371 if (i < 0)
1372 i += tx_ring->count;
1373 buffer_info = &tx_ring->buffer_info[i];
1374 ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
1375 }
1376
1377 return 0;
1356} 1378}
1357 1379
1358static void 1380static void