diff options
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 1 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 63 |
2 files changed, 50 insertions, 14 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 76b052fa3643..7e35e97227bd 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -106,6 +106,7 @@ struct ixgbe_tx_buffer { | |||
106 | unsigned long time_stamp; | 106 | unsigned long time_stamp; |
107 | u16 length; | 107 | u16 length; |
108 | u16 next_to_watch; | 108 | u16 next_to_watch; |
109 | u16 mapped_as_page; | ||
109 | }; | 110 | }; |
110 | 111 | ||
111 | struct ixgbe_rx_buffer { | 112 | struct ixgbe_rx_buffer { |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5c56f2a741f3..9ba506f6ef29 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -218,10 +218,20 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, | |||
218 | struct ixgbe_tx_buffer | 218 | struct ixgbe_tx_buffer |
219 | *tx_buffer_info) | 219 | *tx_buffer_info) |
220 | { | 220 | { |
221 | tx_buffer_info->dma = 0; | 221 | if (tx_buffer_info->dma) { |
222 | if (tx_buffer_info->mapped_as_page) | ||
223 | pci_unmap_page(adapter->pdev, | ||
224 | tx_buffer_info->dma, | ||
225 | tx_buffer_info->length, | ||
226 | PCI_DMA_TODEVICE); | ||
227 | else | ||
228 | pci_unmap_single(adapter->pdev, | ||
229 | tx_buffer_info->dma, | ||
230 | tx_buffer_info->length, | ||
231 | PCI_DMA_TODEVICE); | ||
232 | tx_buffer_info->dma = 0; | ||
233 | } | ||
222 | if (tx_buffer_info->skb) { | 234 | if (tx_buffer_info->skb) { |
223 | skb_dma_unmap(&adapter->pdev->dev, tx_buffer_info->skb, | ||
224 | DMA_TO_DEVICE); | ||
225 | dev_kfree_skb_any(tx_buffer_info->skb); | 235 | dev_kfree_skb_any(tx_buffer_info->skb); |
226 | tx_buffer_info->skb = NULL; | 236 | tx_buffer_info->skb = NULL; |
227 | } | 237 | } |
@@ -5024,23 +5034,16 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, | |||
5024 | struct sk_buff *skb, u32 tx_flags, | 5034 | struct sk_buff *skb, u32 tx_flags, |
5025 | unsigned int first) | 5035 | unsigned int first) |
5026 | { | 5036 | { |
5037 | struct pci_dev *pdev = adapter->pdev; | ||
5027 | struct ixgbe_tx_buffer *tx_buffer_info; | 5038 | struct ixgbe_tx_buffer *tx_buffer_info; |
5028 | unsigned int len; | 5039 | unsigned int len; |
5029 | unsigned int total = skb->len; | 5040 | unsigned int total = skb->len; |
5030 | unsigned int offset = 0, size, count = 0, i; | 5041 | unsigned int offset = 0, size, count = 0, i; |
5031 | unsigned int nr_frags = skb_shinfo(skb)->nr_frags; | 5042 | unsigned int nr_frags = skb_shinfo(skb)->nr_frags; |
5032 | unsigned int f; | 5043 | unsigned int f; |
5033 | dma_addr_t *map; | ||
5034 | 5044 | ||
5035 | i = tx_ring->next_to_use; | 5045 | i = tx_ring->next_to_use; |
5036 | 5046 | ||
5037 | if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) { | ||
5038 | dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); | ||
5039 | return 0; | ||
5040 | } | ||
5041 | |||
5042 | map = skb_shinfo(skb)->dma_maps; | ||
5043 | |||
5044 | if (tx_flags & IXGBE_TX_FLAGS_FCOE) | 5047 | if (tx_flags & IXGBE_TX_FLAGS_FCOE) |
5045 | /* excluding fcoe_crc_eof for FCoE */ | 5048 | /* excluding fcoe_crc_eof for FCoE */ |
5046 | total -= sizeof(struct fcoe_crc_eof); | 5049 | total -= sizeof(struct fcoe_crc_eof); |
@@ -5051,7 +5054,12 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, | |||
5051 | size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); | 5054 | size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); |
5052 | 5055 | ||
5053 | tx_buffer_info->length = size; | 5056 | tx_buffer_info->length = size; |
5054 | tx_buffer_info->dma = skb_shinfo(skb)->dma_head + offset; | 5057 | tx_buffer_info->mapped_as_page = false; |
5058 | tx_buffer_info->dma = pci_map_single(pdev, | ||
5059 | skb->data + offset, | ||
5060 | size, PCI_DMA_TODEVICE); | ||
5061 | if (pci_dma_mapping_error(pdev, tx_buffer_info->dma)) | ||
5062 | goto dma_error; | ||
5055 | tx_buffer_info->time_stamp = jiffies; | 5063 | tx_buffer_info->time_stamp = jiffies; |
5056 | tx_buffer_info->next_to_watch = i; | 5064 | tx_buffer_info->next_to_watch = i; |
5057 | 5065 | ||
@@ -5072,7 +5080,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, | |||
5072 | 5080 | ||
5073 | frag = &skb_shinfo(skb)->frags[f]; | 5081 | frag = &skb_shinfo(skb)->frags[f]; |
5074 | len = min((unsigned int)frag->size, total); | 5082 | len = min((unsigned int)frag->size, total); |
5075 | offset = 0; | 5083 | offset = frag->page_offset; |
5076 | 5084 | ||
5077 | while (len) { | 5085 | while (len) { |
5078 | i++; | 5086 | i++; |
@@ -5083,7 +5091,13 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, | |||
5083 | size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); | 5091 | size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); |
5084 | 5092 | ||
5085 | tx_buffer_info->length = size; | 5093 | tx_buffer_info->length = size; |
5086 | tx_buffer_info->dma = map[f] + offset; | 5094 | tx_buffer_info->dma = pci_map_page(adapter->pdev, |
5095 | frag->page, | ||
5096 | offset, size, | ||
5097 | PCI_DMA_TODEVICE); | ||
5098 | tx_buffer_info->mapped_as_page = true; | ||
5099 | if (pci_dma_mapping_error(pdev, tx_buffer_info->dma)) | ||
5100 | goto dma_error; | ||
5087 | tx_buffer_info->time_stamp = jiffies; | 5101 | tx_buffer_info->time_stamp = jiffies; |
5088 | tx_buffer_info->next_to_watch = i; | 5102 | tx_buffer_info->next_to_watch = i; |
5089 | 5103 | ||
@@ -5100,6 +5114,27 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, | |||
5100 | tx_ring->tx_buffer_info[first].next_to_watch = i; | 5114 | tx_ring->tx_buffer_info[first].next_to_watch = i; |
5101 | 5115 | ||
5102 | return count; | 5116 | return count; |
5117 | |||
5118 | dma_error: | ||
5119 | dev_err(&pdev->dev, "TX DMA map failed\n"); | ||
5120 | |||
5121 | /* clear timestamp and dma mappings for failed tx_buffer_info map */ | ||
5122 | tx_buffer_info->dma = 0; | ||
5123 | tx_buffer_info->time_stamp = 0; | ||
5124 | tx_buffer_info->next_to_watch = 0; | ||
5125 | count--; | ||
5126 | |||
5127 | /* clear timestamp and dma mappings for remaining portion of packet */ | ||
5128 | while (count >= 0) { | ||
5129 | count--; | ||
5130 | i--; | ||
5131 | if (i < 0) | ||
5132 | i += tx_ring->count; | ||
5133 | tx_buffer_info = &tx_ring->tx_buffer_info[i]; | ||
5134 | ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); | ||
5135 | } | ||
5136 | |||
5137 | return count; | ||
5103 | } | 5138 | } |
5104 | 5139 | ||
5105 | static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, | 5140 | static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, |