/* Broadcom NetXtreme-C/E network driver. * * Copyright (c) 2016-2017 Broadcom Limited * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation.
*/ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/pci.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/bpf.h> #include <linux/bpf_trace.h> #include <linux/filter.h> #include <net/netdev_lock.h> #include <net/page_pool/helpers.h> #include <linux/bnxt/hsi.h> #include"bnxt.h" #include"bnxt_xdp.h"
/* fill up the first buffer */
prod = txr->tx_prod;
tx_buf = &txr->tx_buf_ring[RING_TX(bp, prod)];
tx_buf->nr_frags = num_frags; if (xdp)
tx_buf->page = virt_to_head_page(xdp->data);
/* now let us fill up the frags into the next buffers */ for (i = 0; i < num_frags ; i++) {
skb_frag_t *frag = &sinfo->frags[i]; struct bnxt_sw_tx_bd *frag_tx_buf;
dma_addr_t frag_mapping; int frag_len;
tx_avail = bnxt_tx_avail(bp, txr); /* If the tx ring is not full, we must not update the rx producer yet * because we may still be transmitting on some BDs.
*/ if (tx_avail != bp->tx_ring_size)
*event &= ~BNXT_RX_EVENT;
*event |= BNXT_TX_EVENT;
__bnxt_xmit_xdp(bp, txr, mapping + offset, *len,
NEXT_RX(rxr->rx_prod), xdp);
bnxt_reuse_rx_data(rxr, cons, page); returntrue; case XDP_REDIRECT: /* if we are calling this here then we know that the * redirect is coming from a frame received by the * bnxt_en driver.
*/
/* if we are unable to allocate a new buffer, abort and reuse */ if (bnxt_alloc_rx_data(bp, rxr, rxr->rx_prod, GFP_ATOMIC)) {
trace_xdp_exception(bp->dev, xdp_prog, act);
bnxt_xdp_buff_frags_free(rxr, xdp);
bnxt_reuse_rx_data(rxr, cons, page); returntrue;
}
if (prog && !prog->aux->xdp_has_frags &&
bp->dev->mtu > BNXT_MAX_PAGE_MODE_MTU) {
netdev_warn(dev, "MTU %d larger than %d without XDP frag support.\n",
bp->dev->mtu, BNXT_MAX_PAGE_MODE_MTU); return -EOPNOTSUPP;
} if (prog && bp->flags & BNXT_FLAG_HDS) {
netdev_warn(dev, "XDP is disallowed when HDS is enabled.\n"); return -EOPNOTSUPP;
} if (!(bp->flags & BNXT_FLAG_SHARED_RINGS)) {
netdev_warn(dev, "ethtool rx/tx channels must be combined to support XDP.\n"); return -EOPNOTSUPP;
} if (prog)
tx_xdp = bp->rx_nr_rings;
tc = bp->num_tc; if (!tc)
tc = 1;
rc = bnxt_check_rings(bp, bp->tx_nr_rings_per_tc, bp->rx_nr_rings, true, tc, tx_xdp); if (rc) {
netdev_warn(dev, "Unable to reserve enough TX rings to support XDP.\n"); return rc;
} if (netif_running(dev))
bnxt_close_nic(bp, true, false);
old = xchg(&bp->xdp_prog, prog); if (old)
bpf_prog_put(old);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.