diff options
Diffstat (limited to 'drivers/net/ixgb/ixgb_main.c')
-rw-r--r-- | drivers/net/ixgb/ixgb_main.c | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 73646062e8dd..bcd0f01d5feb 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -892,10 +892,18 @@ static void | |||
892 | ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter, | 892 | ixgb_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 | |||
1363 | dma_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 | ||
1358 | static void | 1380 | static void |