summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qede/qede_fp.c
diff options
context:
space:
mode:
authorMintz, Yuval <Yuval.Mintz@cavium.com>2017-04-07 11:04:58 +0300
committerDavid S. Miller <davem@davemloft.net>2017-04-07 06:26:14 -0700
commit89e1afc44765d8b9f509d15df096494f14463e17 (patch)
tree460ee4d36a197507a2b7f79da2c90e34db6905cf /drivers/net/ethernet/qlogic/qede/qede_fp.c
parent10a0176e4e6eb6243c4b1c55e50372e03139d592 (diff)
downloadlinux-89e1afc44765d8b9f509d15df096494f14463e17.tar.gz
linux-89e1afc44765d8b9f509d15df096494f14463e17.tar.bz2
linux-89e1afc44765d8b9f509d15df096494f14463e17.zip
qede: Correct XDP forward unmapping
Driver is currently using dma_unmap_single() with the address it passed to device for the purpose of forwarding, but the XDP transmission buffer was originally a page allocated for the rx-queue. The mapped address is likely to differ from the original mapped address due to the placement offset. This difference is going to get even bigger once we support headroom. Cache the original mapped address of the page, and use it for unmapping of the buffer when completion arrives for the XDP forwarded packet. Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qede/qede_fp.c')
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_fp.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index c77e6972ab48..c61cfcfbbd56 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -360,7 +360,8 @@ static int qede_xdp_xmit(struct qede_dev *edev, struct qede_fastpath *fp,
metadata->mapping + padding,
length, PCI_DMA_TODEVICE);
- txq->sw_tx_ring.pages[idx] = metadata->data;
+ txq->sw_tx_ring.xdp[idx].page = metadata->data;
+ txq->sw_tx_ring.xdp[idx].mapping = metadata->mapping;
txq->sw_tx_prod++;
/* Mark the fastpath for future XDP doorbell */
@@ -384,19 +385,19 @@ int qede_txq_has_work(struct qede_tx_queue *txq)
static void qede_xdp_tx_int(struct qede_dev *edev, struct qede_tx_queue *txq)
{
- struct eth_tx_1st_bd *bd;
- u16 hw_bd_cons;
+ u16 hw_bd_cons, idx;
hw_bd_cons = le16_to_cpu(*txq->hw_cons_ptr);
barrier();
while (hw_bd_cons != qed_chain_get_cons_idx(&txq->tx_pbl)) {
- bd = (struct eth_tx_1st_bd *)qed_chain_consume(&txq->tx_pbl);
+ qed_chain_consume(&txq->tx_pbl);
+ idx = txq->sw_tx_cons & NUM_TX_BDS_MAX;
- dma_unmap_single(&edev->pdev->dev, BD_UNMAP_ADDR(bd),
- PAGE_SIZE, DMA_BIDIRECTIONAL);
- __free_page(txq->sw_tx_ring.pages[txq->sw_tx_cons &
- NUM_TX_BDS_MAX]);
+ dma_unmap_page(&edev->pdev->dev,
+ txq->sw_tx_ring.xdp[idx].mapping,
+ PAGE_SIZE, DMA_BIDIRECTIONAL);
+ __free_page(txq->sw_tx_ring.xdp[idx].page);
txq->sw_tx_cons++;
txq->xmit_pkts++;