Commit 6f5740b1 authored by Benjamin Poirier's avatar Benjamin Poirier Committed by Greg Kroah-Hartman

staging: qlge: Fix dma_sync_single calls

Using the unmap addr elsewhere than unmap calls is a misuse of the dma api.
In prevision of this fix, qlge kept two copies of the dma address around ;)

Fixes: c4e84bde ("qlge: New Qlogic 10Gb Ethernet Driver.")
Fixes: 7c734359 ("qlge: Size RX buffers based on MTU.")
Fixes: 2c9a266a ("qlge: Fix receive packets drop.")
Signed-off-by: default avatarBenjamin Poirier <bpoirier@suse.com>
Link: https://lore.kernel.org/r/20190927101210.23856-10-bpoirier@suse.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 03a0e14b
...@@ -1410,12 +1410,9 @@ struct qlge_bq_desc { ...@@ -1410,12 +1410,9 @@ struct qlge_bq_desc {
struct sk_buff *skb; struct sk_buff *skb;
} p; } p;
dma_addr_t dma_addr; dma_addr_t dma_addr;
/* address in ring where the buffer address (dma_addr) is written for /* address in ring where the buffer address is written for the device */
* the device
*/
__le64 *buf_ptr; __le64 *buf_ptr;
u32 index; u32 index;
DEFINE_DMA_UNMAP_ADDR(mapaddr);
}; };
/* buffer queue */ /* buffer queue */
......
...@@ -995,15 +995,13 @@ static struct qlge_bq_desc *ql_get_curr_lchunk(struct ql_adapter *qdev, ...@@ -995,15 +995,13 @@ static struct qlge_bq_desc *ql_get_curr_lchunk(struct ql_adapter *qdev,
{ {
struct qlge_bq_desc *lbq_desc = qlge_get_curr_buf(&rx_ring->lbq); struct qlge_bq_desc *lbq_desc = qlge_get_curr_buf(&rx_ring->lbq);
pci_dma_sync_single_for_cpu(qdev->pdev, pci_dma_sync_single_for_cpu(qdev->pdev, lbq_desc->dma_addr,
dma_unmap_addr(lbq_desc, mapaddr),
qdev->lbq_buf_size, PCI_DMA_FROMDEVICE); qdev->lbq_buf_size, PCI_DMA_FROMDEVICE);
if ((lbq_desc->p.pg_chunk.offset + qdev->lbq_buf_size) == if ((lbq_desc->p.pg_chunk.offset + qdev->lbq_buf_size) ==
ql_lbq_block_size(qdev)) { ql_lbq_block_size(qdev)) {
/* last chunk of the master page */ /* last chunk of the master page */
pci_unmap_page(qdev->pdev, lbq_desc->dma_addr - pci_unmap_page(qdev->pdev, lbq_desc->dma_addr,
lbq_desc->p.pg_chunk.offset,
ql_lbq_block_size(qdev), PCI_DMA_FROMDEVICE); ql_lbq_block_size(qdev), PCI_DMA_FROMDEVICE);
} }
...@@ -1031,7 +1029,7 @@ static const char * const bq_type_name[] = { ...@@ -1031,7 +1029,7 @@ static const char * const bq_type_name[] = {
[QLGE_LB] = "lbq", [QLGE_LB] = "lbq",
}; };
/* return size of allocated buffer (may be 0) or negative error */ /* return 0 or negative error */
static int qlge_refill_sb(struct rx_ring *rx_ring, static int qlge_refill_sb(struct rx_ring *rx_ring,
struct qlge_bq_desc *sbq_desc) struct qlge_bq_desc *sbq_desc)
{ {
...@@ -1058,12 +1056,13 @@ static int qlge_refill_sb(struct rx_ring *rx_ring, ...@@ -1058,12 +1056,13 @@ static int qlge_refill_sb(struct rx_ring *rx_ring,
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return -EIO; return -EIO;
} }
*sbq_desc->buf_ptr = cpu_to_le64(sbq_desc->dma_addr);
sbq_desc->p.skb = skb; sbq_desc->p.skb = skb;
return SMALL_BUFFER_SIZE; return 0;
} }
/* return size of allocated buffer or negative error */ /* return 0 or negative error */
static int qlge_refill_lb(struct rx_ring *rx_ring, static int qlge_refill_lb(struct rx_ring *rx_ring,
struct qlge_bq_desc *lbq_desc) struct qlge_bq_desc *lbq_desc)
{ {
...@@ -1094,7 +1093,9 @@ static int qlge_refill_lb(struct rx_ring *rx_ring, ...@@ -1094,7 +1093,9 @@ static int qlge_refill_lb(struct rx_ring *rx_ring,
} }
lbq_desc->p.pg_chunk = *master_chunk; lbq_desc->p.pg_chunk = *master_chunk;
lbq_desc->dma_addr = rx_ring->chunk_dma_addr + master_chunk->offset; lbq_desc->dma_addr = rx_ring->chunk_dma_addr;
*lbq_desc->buf_ptr = cpu_to_le64(lbq_desc->dma_addr +
lbq_desc->p.pg_chunk.offset);
/* Adjust the master page chunk for next /* Adjust the master page chunk for next
* buffer get. * buffer get.
...@@ -1107,7 +1108,7 @@ static int qlge_refill_lb(struct rx_ring *rx_ring, ...@@ -1107,7 +1108,7 @@ static int qlge_refill_lb(struct rx_ring *rx_ring,
get_page(master_chunk->page); get_page(master_chunk->page);
} }
return qdev->lbq_buf_size; return 0;
} }
static void qlge_refill_bq(struct qlge_bq *bq) static void qlge_refill_bq(struct qlge_bq *bq)
...@@ -1138,13 +1139,7 @@ static void qlge_refill_bq(struct qlge_bq *bq) ...@@ -1138,13 +1139,7 @@ static void qlge_refill_bq(struct qlge_bq *bq)
retval = qlge_refill_sb(rx_ring, bq_desc); retval = qlge_refill_sb(rx_ring, bq_desc);
else else
retval = qlge_refill_lb(rx_ring, bq_desc); retval = qlge_refill_lb(rx_ring, bq_desc);
if (retval < 0) {
if (retval > 0) {
dma_unmap_addr_set(bq_desc, mapaddr,
bq_desc->dma_addr);
*bq_desc->buf_ptr =
cpu_to_le64(bq_desc->dma_addr);
} else if (retval < 0) {
bq->clean_idx = clean_idx; bq->clean_idx = clean_idx;
netif_err(qdev, ifup, qdev->ndev, netif_err(qdev, ifup, qdev->ndev,
"ring %u %s: Could not get a page chunk, i=%d, clean_idx =%d .\n", "ring %u %s: Could not get a page chunk, i=%d, clean_idx =%d .\n",
...@@ -1567,8 +1562,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, ...@@ -1567,8 +1562,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
} }
skb_reserve(new_skb, NET_IP_ALIGN); skb_reserve(new_skb, NET_IP_ALIGN);
pci_dma_sync_single_for_cpu(qdev->pdev, pci_dma_sync_single_for_cpu(qdev->pdev, sbq_desc->dma_addr,
dma_unmap_addr(sbq_desc, mapaddr),
SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE); SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE);
skb_put_data(new_skb, skb->data, length); skb_put_data(new_skb, skb->data, length);
...@@ -1690,9 +1684,8 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, ...@@ -1690,9 +1684,8 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
* Headers fit nicely into a small buffer. * Headers fit nicely into a small buffer.
*/ */
sbq_desc = qlge_get_curr_buf(&rx_ring->sbq); sbq_desc = qlge_get_curr_buf(&rx_ring->sbq);
pci_unmap_single(qdev->pdev, pci_unmap_single(qdev->pdev, sbq_desc->dma_addr,
dma_unmap_addr(sbq_desc, mapaddr), SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE);
SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE);
skb = sbq_desc->p.skb; skb = sbq_desc->p.skb;
ql_realign_skb(skb, hdr_len); ql_realign_skb(skb, hdr_len);
skb_put(skb, hdr_len); skb_put(skb, hdr_len);
...@@ -1722,8 +1715,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, ...@@ -1722,8 +1715,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
*/ */
sbq_desc = qlge_get_curr_buf(&rx_ring->sbq); sbq_desc = qlge_get_curr_buf(&rx_ring->sbq);
pci_dma_sync_single_for_cpu(qdev->pdev, pci_dma_sync_single_for_cpu(qdev->pdev,
dma_unmap_addr(sbq_desc, sbq_desc->dma_addr,
mapaddr),
SMALL_BUF_MAP_SIZE, SMALL_BUF_MAP_SIZE,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
skb_put_data(skb, sbq_desc->p.skb->data, length); skb_put_data(skb, sbq_desc->p.skb->data, length);
...@@ -1735,8 +1727,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, ...@@ -1735,8 +1727,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
skb = sbq_desc->p.skb; skb = sbq_desc->p.skb;
ql_realign_skb(skb, length); ql_realign_skb(skb, length);
skb_put(skb, length); skb_put(skb, length);
pci_unmap_single(qdev->pdev, pci_unmap_single(qdev->pdev, sbq_desc->dma_addr,
dma_unmap_addr(sbq_desc, mapaddr),
SMALL_BUF_MAP_SIZE, SMALL_BUF_MAP_SIZE,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
sbq_desc->p.skb = NULL; sbq_desc->p.skb = NULL;
...@@ -1774,8 +1765,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, ...@@ -1774,8 +1765,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
"No skb available, drop the packet.\n"); "No skb available, drop the packet.\n");
return NULL; return NULL;
} }
pci_unmap_page(qdev->pdev, pci_unmap_page(qdev->pdev, lbq_desc->dma_addr,
dma_unmap_addr(lbq_desc, mapaddr),
qdev->lbq_buf_size, qdev->lbq_buf_size,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
skb_reserve(skb, NET_IP_ALIGN); skb_reserve(skb, NET_IP_ALIGN);
...@@ -1808,8 +1798,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, ...@@ -1808,8 +1798,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
*/ */
int size, i = 0; int size, i = 0;
sbq_desc = qlge_get_curr_buf(&rx_ring->sbq); sbq_desc = qlge_get_curr_buf(&rx_ring->sbq);
pci_unmap_single(qdev->pdev, pci_unmap_single(qdev->pdev, sbq_desc->dma_addr,
dma_unmap_addr(sbq_desc, mapaddr),
SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE); SMALL_BUF_MAP_SIZE, PCI_DMA_FROMDEVICE);
if (!(ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS)) { if (!(ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS)) {
/* /*
...@@ -2736,8 +2725,8 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring ...@@ -2736,8 +2725,8 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
struct qlge_bq_desc *lbq_desc = &rx_ring->lbq.queue[curr_idx]; struct qlge_bq_desc *lbq_desc = &rx_ring->lbq.queue[curr_idx];
if (lbq_desc->p.pg_chunk.offset == last_offset) if (lbq_desc->p.pg_chunk.offset == last_offset)
pci_unmap_page(qdev->pdev, lbq_desc->dma_addr - pci_unmap_page(qdev->pdev, lbq_desc->dma_addr,
last_offset, ql_lbq_block_size(qdev), ql_lbq_block_size(qdev),
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
put_page(lbq_desc->p.pg_chunk.page); put_page(lbq_desc->p.pg_chunk.page);
...@@ -2768,8 +2757,7 @@ static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring ...@@ -2768,8 +2757,7 @@ static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
return; return;
} }
if (sbq_desc->p.skb) { if (sbq_desc->p.skb) {
pci_unmap_single(qdev->pdev, pci_unmap_single(qdev->pdev, sbq_desc->dma_addr,
dma_unmap_addr(sbq_desc, mapaddr),
SMALL_BUF_MAP_SIZE, SMALL_BUF_MAP_SIZE,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
dev_kfree_skb(sbq_desc->p.skb); dev_kfree_skb(sbq_desc->p.skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment