ixgb: remove use of skb_dma_map from ixgb
skb_dma_map is incompatible with HW iommu due to the fact that multiple mappings can result in different results each time. For this reason it is best to just remove use of these function calls. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
602c0554d7
commit
adeaa90863
|
@ -117,6 +117,7 @@ struct ixgb_buffer {
|
||||||
unsigned long time_stamp;
|
unsigned long time_stamp;
|
||||||
u16 length;
|
u16 length;
|
||||||
u16 next_to_watch;
|
u16 next_to_watch;
|
||||||
|
u16 mapped_as_page;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ixgb_desc_ring {
|
struct ixgb_desc_ring {
|
||||||
|
|
|
@ -892,10 +892,18 @@ static void
|
||||||
ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
|
ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
|
||||||
struct ixgb_buffer *buffer_info)
|
struct ixgb_buffer *buffer_info)
|
||||||
{
|
{
|
||||||
buffer_info->dma = 0;
|
if (buffer_info->dma) {
|
||||||
|
if (buffer_info->mapped_as_page)
|
||||||
|
pci_unmap_page(adapter->pdev, buffer_info->dma,
|
||||||
|
buffer_info->length, PCI_DMA_TODEVICE);
|
||||||
|
else
|
||||||
|
pci_unmap_single(adapter->pdev, buffer_info->dma,
|
||||||
|
buffer_info->length,
|
||||||
|
PCI_DMA_TODEVICE);
|
||||||
|
buffer_info->dma = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer_info->skb) {
|
if (buffer_info->skb) {
|
||||||
skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
|
|
||||||
DMA_TO_DEVICE);
|
|
||||||
dev_kfree_skb_any(buffer_info->skb);
|
dev_kfree_skb_any(buffer_info->skb);
|
||||||
buffer_info->skb = NULL;
|
buffer_info->skb = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1272,24 +1280,16 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
|
||||||
unsigned int first)
|
unsigned int first)
|
||||||
{
|
{
|
||||||
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
|
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
|
||||||
|
struct pci_dev *pdev = adapter->pdev;
|
||||||
struct ixgb_buffer *buffer_info;
|
struct ixgb_buffer *buffer_info;
|
||||||
int len = skb_headlen(skb);
|
int len = skb_headlen(skb);
|
||||||
unsigned int offset = 0, size, count = 0, i;
|
unsigned int offset = 0, size, count = 0, i;
|
||||||
unsigned int mss = skb_shinfo(skb)->gso_size;
|
unsigned int mss = skb_shinfo(skb)->gso_size;
|
||||||
|
|
||||||
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
|
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
|
||||||
unsigned int f;
|
unsigned int f;
|
||||||
dma_addr_t *map;
|
|
||||||
|
|
||||||
i = tx_ring->next_to_use;
|
i = tx_ring->next_to_use;
|
||||||
|
|
||||||
if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
|
|
||||||
dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
map = skb_shinfo(skb)->dma_maps;
|
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
buffer_info = &tx_ring->buffer_info[i];
|
buffer_info = &tx_ring->buffer_info[i];
|
||||||
size = min(len, IXGB_MAX_DATA_PER_TXD);
|
size = min(len, IXGB_MAX_DATA_PER_TXD);
|
||||||
|
@ -1301,11 +1301,11 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
|
||||||
buffer_info->length = size;
|
buffer_info->length = size;
|
||||||
WARN_ON(buffer_info->dma != 0);
|
WARN_ON(buffer_info->dma != 0);
|
||||||
buffer_info->time_stamp = jiffies;
|
buffer_info->time_stamp = jiffies;
|
||||||
buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
|
buffer_info->mapped_as_page = false;
|
||||||
pci_map_single(adapter->pdev,
|
buffer_info->dma = pci_map_single(pdev, skb->data + offset,
|
||||||
skb->data + offset,
|
size, PCI_DMA_TODEVICE);
|
||||||
size,
|
if (pci_dma_mapping_error(pdev, buffer_info->dma))
|
||||||
PCI_DMA_TODEVICE);
|
goto dma_error;
|
||||||
buffer_info->next_to_watch = 0;
|
buffer_info->next_to_watch = 0;
|
||||||
|
|
||||||
len -= size;
|
len -= size;
|
||||||
|
@ -1323,7 +1323,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
|
||||||
|
|
||||||
frag = &skb_shinfo(skb)->frags[f];
|
frag = &skb_shinfo(skb)->frags[f];
|
||||||
len = frag->size;
|
len = frag->size;
|
||||||
offset = 0;
|
offset = frag->page_offset;
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
i++;
|
i++;
|
||||||
|
@ -1341,7 +1341,13 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
|
||||||
|
|
||||||
buffer_info->length = size;
|
buffer_info->length = size;
|
||||||
buffer_info->time_stamp = jiffies;
|
buffer_info->time_stamp = jiffies;
|
||||||
buffer_info->dma = map[f] + offset;
|
buffer_info->mapped_as_page = true;
|
||||||
|
buffer_info->dma =
|
||||||
|
pci_map_page(pdev, frag->page,
|
||||||
|
offset, size,
|
||||||
|
PCI_DMA_TODEVICE);
|
||||||
|
if (pci_dma_mapping_error(pdev, buffer_info->dma))
|
||||||
|
goto dma_error;
|
||||||
buffer_info->next_to_watch = 0;
|
buffer_info->next_to_watch = 0;
|
||||||
|
|
||||||
len -= size;
|
len -= size;
|
||||||
|
@ -1353,6 +1359,22 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
|
||||||
tx_ring->buffer_info[first].next_to_watch = i;
|
tx_ring->buffer_info[first].next_to_watch = i;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
||||||
|
dma_error:
|
||||||
|
dev_err(&pdev->dev, "TX DMA map failed\n");
|
||||||
|
buffer_info->dma = 0;
|
||||||
|
count--;
|
||||||
|
|
||||||
|
while (count >= 0) {
|
||||||
|
count--;
|
||||||
|
i--;
|
||||||
|
if (i < 0)
|
||||||
|
i += tx_ring->count;
|
||||||
|
buffer_info = &tx_ring->buffer_info[i];
|
||||||
|
ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue