|
Michal Kubecek |
ec8941 |
From: Benjamin Poirier <bpoirier@suse.com>
|
|
Michal Kubecek |
ec8941 |
Date: Tue, 7 May 2019 14:43:18 +0900
|
|
Michal Kubecek |
ec8941 |
Subject: qlge: Fix dma_sync_single calls
|
|
Michal Kubecek |
ec8941 |
Patch-mainline: Not yet, submitted v1, will submit v2 after v5.4-rc1
|
|
Michal Kubecek |
ec8941 |
References: bsc#1106061
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
Using the unmap addr elsewhere than unmap calls is a misuse of the dma api.
|
|
Michal Kubecek |
ec8941 |
In prevision of this fix, qlge kept two copies of the dma address around ;)
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
Fixes: c4e84bde1d59 ("qlge: New Qlogic 10Gb Ethernet Driver.")
|
|
Michal Kubecek |
ec8941 |
Fixes: 7c734359d350 ("qlge: Size RX buffers based on MTU.")
|
|
Michal Kubecek |
ec8941 |
Fixes: 2c9a266afefe ("qlge: Fix receive packets drop.")
|
|
Michal Kubecek |
ec8941 |
Signed-off-by: Benjamin Poirier <bpoirier@suse.com>
|
|
Michal Kubecek |
ec8941 |
---
|
|
Michal Kubecek |
ec8941 |
drivers/net/ethernet/qlogic/qlge/qlge.h | 5 --
|
|
Michal Kubecek |
ec8941 |
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 54 ++++++++++-----------------
|
|
Michal Kubecek |
ec8941 |
2 files changed, 22 insertions(+), 37 deletions(-)
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
--- a/drivers/net/ethernet/qlogic/qlge/qlge.h
|
|
Michal Kubecek |
ec8941 |
+++ b/drivers/net/ethernet/qlogic/qlge/qlge.h
|
|
Michal Kubecek |
ec8941 |
@@ -1410,12 +1410,9 @@ struct qlge_bq_desc {
|
|
Michal Kubecek |
ec8941 |
struct sk_buff *skb;
|
|
Michal Kubecek |
ec8941 |
} p;
|
|
Michal Kubecek |
ec8941 |
dma_addr_t dma_addr;
|
|
Michal Kubecek |
ec8941 |
- /* address in ring where the buffer address (dma_addr) is written for
|
|
Michal Kubecek |
ec8941 |
- * the device
|
|
Michal Kubecek |
ec8941 |
- */
|
|
Michal Kubecek |
ec8941 |
+ /* address in ring where the buffer address is written for the device */
|
|
Michal Kubecek |
ec8941 |
__le64 *buf_ptr;
|
|
Michal Kubecek |
ec8941 |
u32 index;
|
|
Michal Kubecek |
ec8941 |
- DEFINE_DMA_UNMAP_ADDR(mapaddr);
|
|
Michal Kubecek |
ec8941 |
};
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
/* buffer queue */
|
|
Michal Kubecek |
ec8941 |
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
|
|
Michal Kubecek |
ec8941 |
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
|
|
Michal Kubecek |
ec8941 |
@@ -995,15 +995,13 @@ static struct qlge_bq_desc *ql_get_curr_
|
|
Michal Kubecek |
ec8941 |
{
|
|
Michal Kubecek |
ec8941 |
struct qlge_bq_desc *lbq_desc = qlge_get_curr_buf(&rx_ring->lbq);
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
- pci_dma_sync_single_for_cpu(qdev->pdev,
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr(lbq_desc, mapaddr),
|
|
Michal Kubecek |
ec8941 |
+ pci_dma_sync_single_for_cpu(qdev->pdev, lbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
qdev->lbq_buf_size, PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
if ((lbq_desc->p.pg_chunk.offset + qdev->lbq_buf_size) ==
|
|
Michal Kubecek |
ec8941 |
ql_lbq_block_size(qdev)) {
|
|
Michal Kubecek |
ec8941 |
/* last chunk of the master page */
|
|
Michal Kubecek |
ec8941 |
- pci_unmap_page(qdev->pdev, lbq_desc->dma_addr -
|
|
Michal Kubecek |
ec8941 |
- lbq_desc->p.pg_chunk.offset,
|
|
Michal Kubecek |
ec8941 |
+ pci_unmap_page(qdev->pdev, lbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
ql_lbq_block_size(qdev), PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
@@ -1031,7 +1029,7 @@ static const char * const bq_type_name[]
|
|
Michal Kubecek |
ec8941 |
[QLGE_LB] = "lbq",
|
|
Michal Kubecek |
ec8941 |
};
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
-/* return size of allocated buffer (may be 0) or negative error */
|
|
Michal Kubecek |
ec8941 |
+/* return 0 or negative error */
|
|
Michal Kubecek |
ec8941 |
static int qlge_refill_sb(struct rx_ring *rx_ring,
|
|
Michal Kubecek |
ec8941 |
struct qlge_bq_desc *sbq_desc)
|
|
Michal Kubecek |
ec8941 |
{
|
|
Michal Kubecek |
ec8941 |
@@ -1058,12 +1056,13 @@ static int qlge_refill_sb(struct rx_ring
|
|
Michal Kubecek |
ec8941 |
dev_kfree_skb_any(skb);
|
|
Michal Kubecek |
ec8941 |
return -EIO;
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
+ *sbq_desc->buf_ptr = cpu_to_le64(sbq_desc->dma_addr);
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
sbq_desc->p.skb = skb;
|
|
Michal Kubecek |
ec8941 |
- return SMALL_BUFFER_SIZE;
|
|
Michal Kubecek |
ec8941 |
+ return 0;
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
-/* return size of allocated buffer or negative error */
|
|
Michal Kubecek |
ec8941 |
+/* return 0 or negative error */
|
|
Michal Kubecek |
ec8941 |
static int qlge_refill_lb(struct rx_ring *rx_ring,
|
|
Michal Kubecek |
ec8941 |
struct qlge_bq_desc *lbq_desc)
|
|
Michal Kubecek |
ec8941 |
{
|
|
Michal Kubecek |
ec8941 |
@@ -1094,7 +1093,9 @@ static int qlge_refill_lb(struct rx_ring
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
lbq_desc->p.pg_chunk = *master_chunk;
|
|
Michal Kubecek |
ec8941 |
- lbq_desc->dma_addr = rx_ring->chunk_dma_addr + master_chunk->offset;
|
|
Michal Kubecek |
ec8941 |
+ lbq_desc->dma_addr = rx_ring->chunk_dma_addr;
|
|
Michal Kubecek |
ec8941 |
+ *lbq_desc->buf_ptr = cpu_to_le64(lbq_desc->dma_addr +
|
|
Michal Kubecek |
ec8941 |
+ lbq_desc->p.pg_chunk.offset);
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
/* Adjust the master page chunk for next
|
|
Michal Kubecek |
ec8941 |
* buffer get.
|
|
Michal Kubecek |
ec8941 |
@@ -1107,7 +1108,7 @@ static int qlge_refill_lb(struct rx_ring
|
|
Michal Kubecek |
ec8941 |
get_page(master_chunk->page);
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
- return qdev->lbq_buf_size;
|
|
Michal Kubecek |
ec8941 |
+ return 0;
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
static void qlge_refill_bq(struct qlge_bq *bq)
|
|
Michal Kubecek |
ec8941 |
@@ -1138,13 +1139,7 @@ static void qlge_refill_bq(struct qlge_b
|
|
Michal Kubecek |
ec8941 |
retval = qlge_refill_sb(rx_ring, bq_desc);
|
|
Michal Kubecek |
ec8941 |
else
|
|
Michal Kubecek |
ec8941 |
retval = qlge_refill_lb(rx_ring, bq_desc);
|
|
Michal Kubecek |
ec8941 |
-
|
|
Michal Kubecek |
ec8941 |
- if (retval > 0) {
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr_set(bq_desc, mapaddr,
|
|
Michal Kubecek |
ec8941 |
- bq_desc->dma_addr);
|
|
Michal Kubecek |
ec8941 |
- *bq_desc->buf_ptr =
|
|
Michal Kubecek |
ec8941 |
- cpu_to_le64(bq_desc->dma_addr);
|
|
Michal Kubecek |
ec8941 |
- } else if (retval < 0) {
|
|
Michal Kubecek |
ec8941 |
+ if (retval < 0) {
|
|
Michal Kubecek |
ec8941 |
bq->clean_idx = clean_idx;
|
|
Michal Kubecek |
ec8941 |
netif_err(qdev, ifup, qdev->ndev,
|
|
Michal Kubecek |
ec8941 |
"ring %u %s: Could not get a page chunk, i=%d, clean_idx =%d .\n",
|
|
Michal Kubecek |
ec8941 |
@@ -1567,8 +1562,7 @@ static void ql_process_mac_rx_skb(struct
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
skb_reserve(new_skb, NET_IP_ALIGN);
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
- pci_dma_sync_single_for_cpu(qdev->pdev,
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr(sbq_desc, mapaddr),
|
|
Michal Kubecek |
ec8941 |
+ pci_dma_sync_single_for_cpu(qdev->pdev, sbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
skb_put_data(new_skb, skb->data, length);
|
|
Michal Kubecek |
ec8941 |
@@ -1690,9 +1684,8 @@ static struct sk_buff *ql_build_rx_skb(s
|
|
Michal Kubecek |
ec8941 |
* Headers fit nicely into a small buffer.
|
|
Michal Kubecek |
ec8941 |
*/
|
|
Michal Kubecek |
ec8941 |
sbq_desc = qlge_get_curr_buf(&rx_ring->sbq);
|
|
Michal Kubecek |
ec8941 |
- pci_unmap_single(qdev->pdev,
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr(sbq_desc, mapaddr),
|
|
Michal Kubecek |
ec8941 |
- SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
+ pci_unmap_single(qdev->pdev, sbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
+ SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
skb = sbq_desc->p.skb;
|
|
Michal Kubecek |
ec8941 |
ql_realign_skb(skb, hdr_len);
|
|
Michal Kubecek |
ec8941 |
skb_put(skb, hdr_len);
|
|
Michal Kubecek |
ec8941 |
@@ -1722,8 +1715,7 @@ static struct sk_buff *ql_build_rx_skb(s
|
|
Michal Kubecek |
ec8941 |
*/
|
|
Michal Kubecek |
ec8941 |
sbq_desc = qlge_get_curr_buf(&rx_ring->sbq);
|
|
Michal Kubecek |
ec8941 |
pci_dma_sync_single_for_cpu(qdev->pdev,
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr(sbq_desc,
|
|
Michal Kubecek |
ec8941 |
- mapaddr),
|
|
Michal Kubecek |
ec8941 |
+ sbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
SMALL_BUF_MAP_SIZE,
|
|
Michal Kubecek |
ec8941 |
PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
skb_put_data(skb, sbq_desc->p.skb->data, length);
|
|
Michal Kubecek |
ec8941 |
@@ -1735,8 +1727,7 @@ static struct sk_buff *ql_build_rx_skb(s
|
|
Michal Kubecek |
ec8941 |
skb = sbq_desc->p.skb;
|
|
Michal Kubecek |
ec8941 |
ql_realign_skb(skb, length);
|
|
Michal Kubecek |
ec8941 |
skb_put(skb, length);
|
|
Michal Kubecek |
ec8941 |
- pci_unmap_single(qdev->pdev,
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr(sbq_desc, mapaddr),
|
|
Michal Kubecek |
ec8941 |
+ pci_unmap_single(qdev->pdev, sbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
SMALL_BUF_MAP_SIZE,
|
|
Michal Kubecek |
ec8941 |
PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
sbq_desc->p.skb = NULL;
|
|
Michal Kubecek |
ec8941 |
@@ -1774,8 +1765,7 @@ static struct sk_buff *ql_build_rx_skb(s
|
|
Michal Kubecek |
ec8941 |
"No skb available, drop the packet.\n");
|
|
Michal Kubecek |
ec8941 |
return NULL;
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
- pci_unmap_page(qdev->pdev,
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr(lbq_desc, mapaddr),
|
|
Michal Kubecek |
ec8941 |
+ pci_unmap_page(qdev->pdev, lbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
qdev->lbq_buf_size,
|
|
Michal Kubecek |
ec8941 |
PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
skb_reserve(skb, NET_IP_ALIGN);
|
|
Michal Kubecek |
ec8941 |
@@ -1808,8 +1798,7 @@ static struct sk_buff *ql_build_rx_skb(s
|
|
Michal Kubecek |
ec8941 |
*/
|
|
Michal Kubecek |
ec8941 |
int size, i = 0;
|
|
Michal Kubecek |
ec8941 |
sbq_desc = qlge_get_curr_buf(&rx_ring->sbq);
|
|
Michal Kubecek |
ec8941 |
- pci_unmap_single(qdev->pdev,
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr(sbq_desc, mapaddr),
|
|
Michal Kubecek |
ec8941 |
+ pci_unmap_single(qdev->pdev, sbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
if (!(ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS)) {
|
|
Michal Kubecek |
ec8941 |
/*
|
|
Michal Kubecek |
ec8941 |
@@ -2735,8 +2724,8 @@ static void ql_free_lbq_buffers(struct q
|
|
Michal Kubecek |
ec8941 |
struct qlge_bq_desc *lbq_desc = &rx_ring->lbq.queue[curr_idx];
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
if (lbq_desc->p.pg_chunk.offset == last_offset)
|
|
Michal Kubecek |
ec8941 |
- pci_unmap_page(qdev->pdev, lbq_desc->dma_addr -
|
|
Michal Kubecek |
ec8941 |
- last_offset, ql_lbq_block_size(qdev),
|
|
Michal Kubecek |
ec8941 |
+ pci_unmap_page(qdev->pdev, lbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
+ ql_lbq_block_size(qdev),
|
|
Michal Kubecek |
ec8941 |
PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
|
|
Michal Kubecek |
ec8941 |
put_page(lbq_desc->p.pg_chunk.page);
|
|
Michal Kubecek |
ec8941 |
@@ -2767,8 +2756,7 @@ static void ql_free_sbq_buffers(struct q
|
|
Michal Kubecek |
ec8941 |
return;
|
|
Michal Kubecek |
ec8941 |
}
|
|
Michal Kubecek |
ec8941 |
if (sbq_desc->p.skb) {
|
|
Michal Kubecek |
ec8941 |
- pci_unmap_single(qdev->pdev,
|
|
Michal Kubecek |
ec8941 |
- dma_unmap_addr(sbq_desc, mapaddr),
|
|
Michal Kubecek |
ec8941 |
+ pci_unmap_single(qdev->pdev, sbq_desc->dma_addr,
|
|
Michal Kubecek |
ec8941 |
SMALL_BUF_MAP_SIZE,
|
|
Michal Kubecek |
ec8941 |
PCI_DMA_FROMDEVICE);
|
|
Michal Kubecek |
ec8941 |
dev_kfree_skb(sbq_desc->p.skb);
|