Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03b1320d authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller
Browse files

e1000e: remove use of skb_dma_map from e1000e driver



In testing we have found that skb_dma_map/unmap is incompatible with HW
IOMMU due to the fact that multiple mappings will return different results.
In order to correct this we need to remove skb_dma_map/unmap calls from the
e1000e driver.

Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 614c12a1
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -194,13 +194,16 @@ struct e1000_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;
		};
		};
		/* Rx */
		/* Rx */
		struct {
			/* arrays of page information for packet split */
			/* arrays of page information for packet split */
			struct e1000_ps_page *ps_pages;
			struct e1000_ps_page *ps_pages;
	};
			struct page *page;
			struct page *page;
		};
		};
	};
};


struct e1000_ring {
struct e1000_ring {
	void *desc;			/* pointer to ring memory  */
	void *desc;			/* pointer to ring memory  */
+41 −18
Original line number Original line Diff line number Diff line
@@ -534,10 +534,17 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
static void e1000_put_txbuf(struct e1000_adapter *adapter,
static void e1000_put_txbuf(struct e1000_adapter *adapter,
			     struct e1000_buffer *buffer_info)
			     struct e1000_buffer *buffer_info)
{
{
	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;
		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;
	}
	}
@@ -3884,23 +3891,14 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
			unsigned int mss)
			unsigned int mss)
{
{
	struct e1000_ring *tx_ring = adapter->tx_ring;
	struct e1000_ring *tx_ring = adapter->tx_ring;
	struct pci_dev *pdev = adapter->pdev;
	struct e1000_buffer *buffer_info;
	struct e1000_buffer *buffer_info;
	unsigned int len = skb_headlen(skb);
	unsigned int len = skb_headlen(skb);
	unsigned int offset, size, count = 0, i;
	unsigned int offset = 0, size, count = 0, i;
	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");
		adapter->tx_dma_failed++;
		return 0;
	}

	map = skb_shinfo(skb)->dma_maps;
	offset = 0;

	while (len) {
	while (len) {
		buffer_info = &tx_ring->buffer_info[i];
		buffer_info = &tx_ring->buffer_info[i];
		size = min(len, max_per_txd);
		size = min(len, max_per_txd);
@@ -3908,11 +3906,15 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
		buffer_info->length = size;
		buffer_info->length = size;
		buffer_info->time_stamp = jiffies;
		buffer_info->time_stamp = jiffies;
		buffer_info->next_to_watch = i;
		buffer_info->next_to_watch = i;
		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
		buffer_info->dma = pci_map_single(pdev,	skb->data + offset,
		count++;
						  size,	PCI_DMA_TODEVICE);
		buffer_info->mapped_as_page = false;
		if (pci_dma_mapping_error(pdev, buffer_info->dma))
			goto dma_error;


		len -= size;
		len -= size;
		offset += size;
		offset += size;
		count++;


		if (len) {
		if (len) {
			i++;
			i++;
@@ -3926,7 +3928,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,


		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++;
@@ -3939,7 +3941,12 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
			buffer_info->length = size;
			buffer_info->length = size;
			buffer_info->time_stamp = jiffies;
			buffer_info->time_stamp = jiffies;
			buffer_info->next_to_watch = i;
			buffer_info->next_to_watch = i;
			buffer_info->dma = map[f] + offset;
			buffer_info->dma = pci_map_page(pdev, frag->page,
							offset, size,
							PCI_DMA_TODEVICE);
			buffer_info->mapped_as_page = true;
			if (pci_dma_mapping_error(pdev, buffer_info->dma))
				goto dma_error;


			len -= size;
			len -= size;
			offset += size;
			offset += size;
@@ -3951,6 +3958,22 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
	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];
		e1000_put_txbuf(adapter, buffer_info);;
	}

	return 0;
}
}


static void e1000_tx_queue(struct e1000_adapter *adapter,
static void e1000_tx_queue(struct e1000_adapter *adapter,