aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-12-02 11:46:56 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-02 22:57:11 -0500
commite5a43549f7a58509a91b299a51337d386697b92c (patch)
treecca78d4803f46fcb6947f77c60c213a239f4f8a7 /drivers/net/ixgbe
parentadeaa9086399780688679f2a7de4243bdbf77295 (diff)
ixgbe: remove skb_dma_map/unmap calls from driver
This patch removes skb_dma_map/unmap calls from the ixgbe driver due to the fact that the calls don't work with HW IOMMU enabled systems. The problem is that multiple mappings will give different results when HW IOMMU is enabled and the skb_dma_map/unmap calls only have one location to store mappings. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe')
-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,