[RFC,net-next,07/34] libie: add Tx buffer completion helpers

Message ID 20231223025554.2316836-8-aleksander.lobakin@intel.com
State New
Headers
Series Christmas 3-serie XDP for idpf (+generic stuff) |

Commit Message

Alexander Lobakin Dec. 23, 2023, 2:55 a.m. UTC
  Software-side Tx buffers for storing DMA, frame size, skb pointers etc.
are pretty much generic and every driver defines them the same way. The
same can be said for software Tx completions -- same napi_consume_skb()s
and all that...
Add a couple simple wrappers for doing that to stop repeating the old
tale at least within the Intel code.

Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
---
 include/linux/net/intel/libie/tx.h | 88 ++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 include/linux/net/intel/libie/tx.h
  

Patch

diff --git a/include/linux/net/intel/libie/tx.h b/include/linux/net/intel/libie/tx.h
new file mode 100644
index 000000000000..07a19abb72fd
--- /dev/null
+++ b/include/linux/net/intel/libie/tx.h
@@ -0,0 +1,88 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2023 Intel Corporation. */
+
+#ifndef __LIBIE_TX_H
+#define __LIBIE_TX_H
+
+#include <linux/net/intel/libie/stats.h>
+#include <linux/skbuff.h>
+
+/**
+ * enum libie_tx_buf_type - type of &libie_tx_buf to act on Tx completion
+ * @LIBIE_TX_BUF_EMPTY: unused OR XSk frame, no action required
+ * @LIBIE_TX_BUF_SLAB: kmalloc-allocated buffer, unmap and kfree()
+ * @LIBIE_TX_BUF_FRAG: mapped skb OR &xdp_buff frag, only unmap DMA
+ * @LIBIE_TX_BUF_SKB: &sk_buff, unmap and consume_skb(), update stats
+ * @LIBIE_TX_BUF_XDP_TX: &skb_shared_info, page_pool_put_full_page(), stats
+ * @LIBIE_TX_BUF_XDP_XMIT: &xdp_frame, unmap and xdp_return_frame(), stats
+ * @LIBIE_TX_BUF_XSK_TX: &xdp_buff on XSk queue, xsk_buff_free(), stats
+ */
+enum libie_tx_buf_type {
+	LIBIE_TX_BUF_EMPTY	= 0U,
+	LIBIE_TX_BUF_SLAB,
+	LIBIE_TX_BUF_FRAG,
+	LIBIE_TX_BUF_SKB,
+	LIBIE_TX_BUF_XDP_TX,
+	LIBIE_TX_BUF_XDP_XMIT,
+	LIBIE_TX_BUF_XSK_TX,
+};
+
+struct libie_tx_buffer {
+	void			*next_to_watch;
+	union {
+		void			*raw;
+		struct sk_buff		*skb;
+		struct skb_shared_info	*sinfo;
+		struct xdp_frame	*xdpf;
+		struct xdp_buff		*xdp;
+	};
+
+	DEFINE_DMA_UNMAP_ADDR(dma);
+	DEFINE_DMA_UNMAP_LEN(len);
+
+	u32			bytecount;
+	u16			gso_segs;
+	enum libie_tx_buf_type	type:16;
+
+	union {
+		int			compl_tag;
+		bool			ctx_entry;
+	};
+};
+
+static inline void libie_tx_complete_buf(struct libie_tx_buffer *buf,
+					 struct device *dev, bool napi,
+					 struct libie_sq_onstack_stats *ss)
+{
+	switch (buf->type) {
+	case LIBIE_TX_BUF_EMPTY:
+		return;
+	case LIBIE_TX_BUF_SLAB:
+	case LIBIE_TX_BUF_FRAG:
+	case LIBIE_TX_BUF_SKB:
+		dma_unmap_page(dev, dma_unmap_addr(buf, dma),
+			       dma_unmap_len(buf, len),
+			       DMA_TO_DEVICE);
+		break;
+	default:
+		break;
+	}
+
+	switch (buf->type) {
+	case LIBIE_TX_BUF_SLAB:
+		kfree(buf->raw);
+		break;
+	case LIBIE_TX_BUF_SKB:
+		ss->packets += buf->gso_segs;
+		ss->bytes += buf->bytecount;
+
+		napi_consume_skb(buf->skb, napi);
+		break;
+	default:
+		break;
+	}
+
+	buf->type = LIBIE_TX_BUF_EMPTY;
+}
+
+#endif /* __LIBIE_TX_H */