Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/* Copyright (C) 2024 Intel Corporation */
  3
  4#ifndef __LIBETH_TX_H
  5#define __LIBETH_TX_H
  6
  7#include <linux/skbuff.h>
  8
  9#include <net/libeth/types.h>
 10
 11/* Tx buffer completion */
 12
 13/**
 14 * enum libeth_sqe_type - type of &libeth_sqe to act on Tx completion
 15 * @LIBETH_SQE_EMPTY: unused/empty, no action required
 16 * @LIBETH_SQE_CTX: context descriptor with empty SQE, no action required
 17 * @LIBETH_SQE_SLAB: kmalloc-allocated buffer, unmap and kfree()
 18 * @LIBETH_SQE_FRAG: mapped skb frag, only unmap DMA
 19 * @LIBETH_SQE_SKB: &sk_buff, unmap and napi_consume_skb(), update stats
 20 */
 21enum libeth_sqe_type {
 22	LIBETH_SQE_EMPTY		= 0U,
 23	LIBETH_SQE_CTX,
 24	LIBETH_SQE_SLAB,
 25	LIBETH_SQE_FRAG,
 26	LIBETH_SQE_SKB,
 27};
 28
 29/**
 30 * struct libeth_sqe - represents a Send Queue Element / Tx buffer
 31 * @type: type of the buffer, see the enum above
 32 * @rs_idx: index of the last buffer from the batch this one was sent in
 33 * @raw: slab buffer to free via kfree()
 34 * @skb: &sk_buff to consume
 35 * @dma: DMA address to unmap
 36 * @len: length of the mapped region to unmap
 37 * @nr_frags: number of frags in the frame this buffer belongs to
 38 * @packets: number of physical packets sent for this frame
 39 * @bytes: number of physical bytes sent for this frame
 40 * @priv: driver-private scratchpad
 41 */
 42struct libeth_sqe {
 43	enum libeth_sqe_type		type:32;
 44	u32				rs_idx;
 45
 46	union {
 47		void				*raw;
 48		struct sk_buff			*skb;
 49	};
 50
 51	DEFINE_DMA_UNMAP_ADDR(dma);
 52	DEFINE_DMA_UNMAP_LEN(len);
 53
 54	u32				nr_frags;
 55	u32				packets;
 56	u32				bytes;
 57
 58	unsigned long			priv;
 59} __aligned_largest;
 60
 61/**
 62 * LIBETH_SQE_CHECK_PRIV - check the driver's private SQE data
 63 * @p: type or name of the object the driver wants to fit into &libeth_sqe
 64 *
 65 * Make sure the driver's private data fits into libeth_sqe::priv. To be used
 66 * right after its declaration.
 67 */
 68#define LIBETH_SQE_CHECK_PRIV(p)					  \
 69	static_assert(sizeof(p) <= sizeof_field(struct libeth_sqe, priv))
 70
 71/**
 72 * struct libeth_cq_pp - completion queue poll params
 73 * @dev: &device to perform DMA unmapping
 74 * @ss: onstack NAPI stats to fill
 75 * @napi: whether it's called from the NAPI context
 76 *
 77 * libeth uses this structure to access objects needed for performing full
 78 * Tx complete operation without passing lots of arguments and change the
 79 * prototypes each time a new one is added.
 80 */
 81struct libeth_cq_pp {
 82	struct device			*dev;
 83	struct libeth_sq_napi_stats	*ss;
 84
 85	bool				napi;
 86};
 87
 88/**
 89 * libeth_tx_complete - perform Tx completion for one SQE
 90 * @sqe: SQE to complete
 91 * @cp: poll params
 92 *
 93 * Do Tx complete for all the types of buffers, incl. freeing, unmapping,
 94 * updating the stats etc.
 95 */
 96static inline void libeth_tx_complete(struct libeth_sqe *sqe,
 97				      const struct libeth_cq_pp *cp)
 98{
 99	switch (sqe->type) {
100	case LIBETH_SQE_EMPTY:
101		return;
102	case LIBETH_SQE_SKB:
103	case LIBETH_SQE_FRAG:
104	case LIBETH_SQE_SLAB:
105		dma_unmap_page(cp->dev, dma_unmap_addr(sqe, dma),
106			       dma_unmap_len(sqe, len), DMA_TO_DEVICE);
107		break;
108	default:
109		break;
110	}
111
112	switch (sqe->type) {
113	case LIBETH_SQE_SKB:
114		cp->ss->packets += sqe->packets;
115		cp->ss->bytes += sqe->bytes;
116
117		napi_consume_skb(sqe->skb, cp->napi);
118		break;
119	case LIBETH_SQE_SLAB:
120		kfree(sqe->raw);
121		break;
122	default:
123		break;
124	}
125
126	sqe->type = LIBETH_SQE_EMPTY;
127}
128
129#endif /* __LIBETH_TX_H */