drivers/net/ethernet/intel/libeth/rx.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/libeth/rx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/libeth/rx.c
Extension
.c
Size
7687 bytes
Lines
274
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2024-2025 Intel Corporation */

#define DEFAULT_SYMBOL_NAMESPACE	"LIBETH"

#include <linux/export.h>

#include <net/libeth/rx.h>

/* Rx buffer management */

/**
 * libeth_rx_hw_len_mtu - get the actual buffer size to be passed to HW
 * @pp: &page_pool_params of the netdev to calculate the size for
 * @max_len: maximum buffer size for a single descriptor
 *
 * Return: HW-writeable length per one buffer to pass it to the HW accounting:
 * MTU the @dev has, HW required alignment, minimum and maximum allowed values,
 * and system's page size.
 */
static u32 libeth_rx_hw_len_mtu(const struct page_pool_params *pp, u32 max_len)
{
	u32 len;

	len = READ_ONCE(pp->netdev->mtu) + LIBETH_RX_LL_LEN;
	len = ALIGN(len, LIBETH_RX_BUF_STRIDE);
	len = min3(len, ALIGN_DOWN(max_len ? : U32_MAX, LIBETH_RX_BUF_STRIDE),
		   pp->max_len);

	return len;
}

/**
 * libeth_rx_hw_len_truesize - get the short buffer size to be passed to HW
 * @pp: &page_pool_params of the netdev to calculate the size for
 * @max_len: maximum buffer size for a single descriptor
 * @truesize: desired truesize for the buffers
 *
 * Return: HW-writeable length per one buffer to pass it to the HW ignoring the
 * MTU and closest to the passed truesize. Can be used for "short" buffer
 * queues to fragment pages more efficiently.
 */
static u32 libeth_rx_hw_len_truesize(const struct page_pool_params *pp,
				     u32 max_len, u32 truesize)
{
	u32 min, len;

	min = SKB_HEAD_ALIGN(pp->offset + LIBETH_RX_BUF_STRIDE);
	truesize = clamp(roundup_pow_of_two(truesize), roundup_pow_of_two(min),
			 PAGE_SIZE << LIBETH_RX_PAGE_ORDER);

	len = SKB_WITH_OVERHEAD(truesize - pp->offset);
	len = ALIGN_DOWN(len, LIBETH_RX_BUF_STRIDE) ? : LIBETH_RX_BUF_STRIDE;
	len = min3(len, ALIGN_DOWN(max_len ? : U32_MAX, LIBETH_RX_BUF_STRIDE),
		   pp->max_len);

	return len;
}

/**
 * libeth_rx_page_pool_params - calculate params with the stack overhead
 * @fq: buffer queue to calculate the size for
 * @pp: &page_pool_params of the netdev
 *
 * Set the PP params to will all needed stack overhead (headroom, tailroom) and
 * both the HW buffer length and the truesize for all types of buffers. For
 * "short" buffers, truesize never exceeds the "wanted" one; for the rest,
 * it can be up to the page size.
 *
 * Return: true on success, false on invalid input params.
 */
static bool libeth_rx_page_pool_params(struct libeth_fq *fq,
				       struct page_pool_params *pp)
{
	pp->offset = fq->xdp ? LIBETH_XDP_HEADROOM : LIBETH_SKB_HEADROOM;
	/* HW-writeable / syncable length per one page */
	pp->max_len = LIBETH_RX_PAGE_LEN(pp->offset);

	/* HW-writeable length per buffer */
	switch (fq->type) {
	case LIBETH_FQE_MTU:
		fq->buf_len = libeth_rx_hw_len_mtu(pp, fq->buf_len);
		break;
	case LIBETH_FQE_SHORT:
		fq->buf_len = libeth_rx_hw_len_truesize(pp, fq->buf_len,
							fq->truesize);
		break;
	case LIBETH_FQE_HDR:
		fq->buf_len = ALIGN(LIBETH_MAX_HEAD, LIBETH_RX_BUF_STRIDE);
		break;

Annotation

Implementation Notes