drivers/net/ethernet/netronome/nfp/nfd3/xsk.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/netronome/nfp/nfd3/xsk.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/nfd3/xsk.c
Extension
.c
Size
10151 bytes
Lines
410
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (unlikely(!netdev)) {
			nfp_net_xsk_rx_drop(r_vec, xrxbuf);
			return;
		}
		nfp_repr_inc_rx_stats(netdev, pkt_len);
	}

	skb = napi_alloc_skb(&r_vec->napi, pkt_len);
	if (!skb) {
		nfp_net_xsk_rx_drop(r_vec, xrxbuf);
		return;
	}
	skb_put_data(skb, xrxbuf->xdp->data, pkt_len);

	skb->mark = meta->mark;
	skb_set_hash(skb, meta->hash, meta->hash_type);

	skb_record_rx_queue(skb, rx_ring->idx);
	skb->protocol = eth_type_trans(skb, netdev);

	nfp_nfd3_rx_csum(dp, r_vec, rxd, meta, skb);

	if (unlikely(!nfp_net_vlan_strip(skb, rxd, meta))) {
		dev_kfree_skb_any(skb);
		nfp_net_xsk_rx_drop(r_vec, xrxbuf);
		return;
	}

	if (meta_xdp)
		skb_metadata_set(skb,
				 xrxbuf->xdp->data - xrxbuf->xdp->data_meta);

	napi_gro_receive(&rx_ring->r_vec->napi, skb);

	nfp_net_xsk_rx_free(xrxbuf);

	(*skbs_polled)++;
}

static unsigned int
nfp_nfd3_xsk_rx(struct nfp_net_rx_ring *rx_ring, int budget,
		unsigned int *skbs_polled)
{
	struct nfp_net_r_vector *r_vec = rx_ring->r_vec;
	struct nfp_net_dp *dp = &r_vec->nfp_net->dp;
	struct nfp_net_tx_ring *tx_ring;
	struct bpf_prog *xdp_prog;
	bool xdp_redir = false;
	int pkts_polled = 0;

	xdp_prog = READ_ONCE(dp->xdp_prog);
	tx_ring = r_vec->xdp_ring;

	while (pkts_polled < budget) {
		unsigned int meta_len, data_len, pkt_len, pkt_off;
		struct nfp_net_xsk_rx_buf *xrxbuf;
		struct nfp_net_rx_desc *rxd;
		struct nfp_meta_parsed meta;
		int idx, act;

		idx = D_IDX(rx_ring, rx_ring->rd_p);

		rxd = &rx_ring->rxds[idx];
		if (!(rxd->rxd.meta_len_dd & PCIE_DESC_RX_DD))
			break;

		rx_ring->rd_p++;
		pkts_polled++;

		xrxbuf = &rx_ring->xsk_rxbufs[idx];

		/* If starved of buffers "drop" it and scream. */
		if (rx_ring->rd_p >= rx_ring->wr_p) {
			nn_dp_warn(dp, "Starved of RX buffers\n");
			nfp_net_xsk_rx_drop(r_vec, xrxbuf);
			break;
		}

		/* Memory barrier to ensure that we won't do other reads
		 * before the DD bit.
		 */
		dma_rmb();

		memset(&meta, 0, sizeof(meta));

		/* Only supporting AF_XDP with dynamic metadata so buffer layout
		 * is always:
		 *
		 *  ---------------------------------------------------------
		 * |  off | metadata  |             packet           | XXXX  |

Annotation

Implementation Notes