xref: /linux/include/net/libeth/tx.h (revision 9410645520e9b820069761f3450ef6661418e279)
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  */
21 enum 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  */
42 struct 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  */
81 struct 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  */
libeth_tx_complete(struct libeth_sqe * sqe,const struct libeth_cq_pp * cp)96 static 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 */
130