aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c63
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
111struct ixgbe_rx_buffer { 112struct 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
5118dma_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
5105static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, 5140static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,