drivers/net/ethernet/netronome/nfp/nfp_net_dp.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/nfp_net_dp.c
Extension
.c
Size
11958 bytes
Lines
465
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 (!rxbufs[i].frag) {
			nfp_net_rx_ring_bufs_free(dp, rx_ring);
			return -ENOMEM;
		}
	}

	return 0;
}

int nfp_net_tx_rings_prepare(struct nfp_net *nn, struct nfp_net_dp *dp)
{
	unsigned int r;

	dp->tx_rings = kzalloc_objs(*dp->tx_rings, dp->num_tx_rings);
	if (!dp->tx_rings)
		return -ENOMEM;

	if (dp->ctrl & NFP_NET_CFG_CTRL_TXRWB) {
		dp->txrwb = dma_alloc_coherent(dp->dev,
					       dp->num_tx_rings * sizeof(u64),
					       &dp->txrwb_dma, GFP_KERNEL);
		if (!dp->txrwb)
			goto err_free_rings;
	}

	for (r = 0; r < dp->num_tx_rings; r++) {
		int bias = 0;

		if (r >= dp->num_stack_tx_rings)
			bias = dp->num_stack_tx_rings;

		nfp_net_tx_ring_init(&dp->tx_rings[r], dp,
				     &nn->r_vecs[r - bias], r, bias);

		if (nfp_net_tx_ring_alloc(dp, &dp->tx_rings[r]))
			goto err_free_prev;

		if (nfp_net_tx_ring_bufs_alloc(dp, &dp->tx_rings[r]))
			goto err_free_ring;
	}

	return 0;

err_free_prev:
	while (r--) {
		nfp_net_tx_ring_bufs_free(dp, &dp->tx_rings[r]);
err_free_ring:
		nfp_net_tx_ring_free(dp, &dp->tx_rings[r]);
	}
	if (dp->txrwb)
		dma_free_coherent(dp->dev, dp->num_tx_rings * sizeof(u64),
				  dp->txrwb, dp->txrwb_dma);
err_free_rings:
	kfree(dp->tx_rings);
	return -ENOMEM;
}

void nfp_net_tx_rings_free(struct nfp_net_dp *dp)
{
	unsigned int r;

	for (r = 0; r < dp->num_tx_rings; r++) {
		nfp_net_tx_ring_bufs_free(dp, &dp->tx_rings[r]);
		nfp_net_tx_ring_free(dp, &dp->tx_rings[r]);
	}

	if (dp->txrwb)
		dma_free_coherent(dp->dev, dp->num_tx_rings * sizeof(u64),
				  dp->txrwb, dp->txrwb_dma);
	kfree(dp->tx_rings);
}

/**
 * nfp_net_rx_ring_free() - Free resources allocated to a RX ring
 * @rx_ring:  RX ring to free
 */
static void nfp_net_rx_ring_free(struct nfp_net_rx_ring *rx_ring)
{
	struct nfp_net_r_vector *r_vec = rx_ring->r_vec;
	struct nfp_net_dp *dp = &r_vec->nfp_net->dp;

	if (dp->netdev)
		xdp_rxq_info_unreg(&rx_ring->xdp_rxq);

	if (nfp_net_has_xsk_pool_slow(dp, rx_ring->idx))
		kvfree(rx_ring->xsk_rxbufs);
	else
		kvfree(rx_ring->rxbufs);

	if (rx_ring->rxds)

Annotation

Implementation Notes