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:05:01 +0300
committerDavid S. Miller <davem@davemloft.net>2017-04-07 06:26:14 -0700
commit059eeb07e175086db1f84c1d8d29bb9aa8057797 (patch)
treefd69702322ca50528093e42bd87167809e3f3c5e /drivers/net/ethernet/qlogic/qede/qede_fp.c
parent15ed8a47ff0571dd268e37002511993b47e996bd (diff)
downloadlinux-059eeb07e175086db1f84c1d8d29bb9aa8057797.tar.gz
linux-059eeb07e175086db1f84c1d8d29bb9aa8057797.tar.bz2
linux-059eeb07e175086db1f84c1d8d29bb9aa8057797.zip
qede: Support XDP adjustment of headers
In case an XDP program is attached, reserve XDP_PACKET_HEADROOM bytes at the beginning of the packet for the program to play with. Modify the XDP logic in the driver to fill-in the missing bits and re-calculate offsets and length after the program has finished running to properly reflect the current status of the packet. We can then go and remove the limitation of not supporting XDP programs where xdp_adjust_head is set. 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, 11 insertions, 6 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index e382d4bdf430..961b1d36b9eb 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -994,14 +994,14 @@ static bool qede_rx_xdp(struct qede_dev *edev,
struct bpf_prog *prog,
struct sw_rx_data *bd,
struct eth_fast_path_rx_reg_cqe *cqe,
- u16 data_offset)
+ u16 *data_offset, u16 *len)
{
- u16 len = le16_to_cpu(cqe->len_on_first_bd);
struct xdp_buff xdp;
enum xdp_action act;
- xdp.data = page_address(bd->data) + data_offset;
- xdp.data_end = xdp.data + len;
+ xdp.data_hard_start = page_address(bd->data);
+ xdp.data = xdp.data_hard_start + *data_offset;
+ xdp.data_end = xdp.data + *len;
/* Queues always have a full reset currently, so for the time
* being until there's atomic program replace just mark read
@@ -1011,6 +1011,10 @@ static bool qede_rx_xdp(struct qede_dev *edev,
act = bpf_prog_run_xdp(prog, &xdp);
rcu_read_unlock();
+ /* Recalculate, as XDP might have changed the headers */
+ *data_offset = xdp.data - xdp.data_hard_start;
+ *len = xdp.data_end - xdp.data;
+
if (act == XDP_PASS)
return true;
@@ -1029,7 +1033,7 @@ static bool qede_rx_xdp(struct qede_dev *edev,
/* Now if there's a transmission problem, we'd still have to
* throw current buffer, as replacement was already allocated.
*/
- if (qede_xdp_xmit(edev, fp, bd, data_offset, len)) {
+ if (qede_xdp_xmit(edev, fp, bd, *data_offset, *len)) {
dma_unmap_page(rxq->dev, bd->mapping,
PAGE_SIZE, DMA_BIDIRECTIONAL);
__free_page(bd->data);
@@ -1231,7 +1235,8 @@ static int qede_rx_process_cqe(struct qede_dev *edev,
/* Run eBPF program if one is attached */
if (xdp_prog)
- if (!qede_rx_xdp(edev, fp, rxq, xdp_prog, bd, fp_cqe, pad))
+ if (!qede_rx_xdp(edev, fp, rxq, xdp_prog, bd, fp_cqe,
+ &pad, &len))
return 0;
/* If this is an error packet then drop it */