drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c
Extension
.c
Size
14836 bytes
Lines
555
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(!page)) {
			dev_err(oq->dev, "Rx buffer alloc failed\n");
			goto rx_buf_alloc_err;
		}
		desc_ring[i].buffer_ptr = dma_map_page(oq->dev, page, 0,
						       PAGE_SIZE,
						       DMA_FROM_DEVICE);
		if (dma_mapping_error(oq->dev, desc_ring[i].buffer_ptr)) {
			dev_err(oq->dev,
				"OQ-%d buffer alloc: DMA mapping error!\n",
				oq->q_no);
			goto dma_map_err;
		}
		oq->buff_info[i].page = page;
	}

	return 0;

dma_map_err:
	put_page(page);
rx_buf_alloc_err:
	while (i) {
		i--;
		dma_unmap_page(oq->dev, desc_ring[i].buffer_ptr, PAGE_SIZE, DMA_FROM_DEVICE);
		put_page(oq->buff_info[i].page);
		oq->buff_info[i].page = NULL;
	}

	return -ENOMEM;
}

/**
 * octep_vf_oq_refill() - refill buffers for used Rx ring descriptors.
 *
 * @oct: Octeon device private data structure.
 * @oq: Octeon Rx queue data structure.
 *
 * Return: number of descriptors successfully refilled with receive buffers.
 */
static int octep_vf_oq_refill(struct octep_vf_device *oct, struct octep_vf_oq *oq)
{
	struct octep_vf_oq_desc_hw *desc_ring = oq->desc_ring;
	struct page *page;
	u32 refill_idx, i;

	refill_idx = oq->host_refill_idx;
	for (i = 0; i < oq->refill_count; i++) {
		page = dev_alloc_page();
		if (unlikely(!page)) {
			dev_err(oq->dev, "refill: rx buffer alloc failed\n");
			oq->stats->alloc_failures++;
			break;
		}

		desc_ring[refill_idx].buffer_ptr = dma_map_page(oq->dev, page, 0,
								PAGE_SIZE, DMA_FROM_DEVICE);
		if (dma_mapping_error(oq->dev, desc_ring[refill_idx].buffer_ptr)) {
			dev_err(oq->dev,
				"OQ-%d buffer refill: DMA mapping error!\n",
				oq->q_no);
			put_page(page);
			oq->stats->alloc_failures++;
			break;
		}
		oq->buff_info[refill_idx].page = page;
		refill_idx++;
		if (refill_idx == oq->max_count)
			refill_idx = 0;
	}
	oq->host_refill_idx = refill_idx;
	oq->refill_count -= i;

	return i;
}

/**
 * octep_vf_setup_oq() - Setup a Rx queue.
 *
 * @oct: Octeon device private data structure.
 * @q_no: Rx queue number to be setup.
 *
 * Allocate resources for a Rx queue.
 */
static int octep_vf_setup_oq(struct octep_vf_device *oct, int q_no)
{
	struct octep_vf_oq *oq;
	u32 desc_ring_size;

	oq = vzalloc(sizeof(*oq));
	if (!oq)

Annotation

Implementation Notes