git: 1e066e460403 - stable/14 - nvme: Add SGL structure and constants for use in NVMe commands

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Tue, 27 Aug 2024 01:06:25 UTC
The branch stable/14 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=1e066e46040354f244561894911e0938c9ef4df7

commit 1e066e46040354f244561894911e0938c9ef4df7
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-03-23 00:23:09 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2024-08-26 18:27:28 +0000

    nvme: Add SGL structure and constants for use in NVMe commands
    
    Fabrics capsules use an SGL structure instead of prp1/2 addresses to
    describe the data buffer used for a command.  The SGL structure is
    added to a union with the existing prp1/2 fields.
    
    Reviewed by:    imp
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D44442
    
    (cherry picked from commit f21a54d19080510bce279183f4bf07d5315bd179)
---
 sys/dev/nvme/nvme.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h
index ee387d54985e..f00090731dff 100644
--- a/sys/dev/nvme/nvme.h
+++ b/sys/dev/nvme/nvme.h
@@ -433,6 +433,25 @@
 #define NVME_CTRLR_DATA_VWC_ALL_NO			(2)
 #define NVME_CTRLR_DATA_VWC_ALL_YES			(3)
 
+/** SGL Support */
+/* NVM command set SGL support */
+#define	NVME_CTRLR_DATA_SGLS_NVM_COMMAND_SET_SHIFT	(0)
+#define	NVME_CTRLR_DATA_SGLS_NVM_COMMAND_SET_MASK	(0x3)
+#define	NVME_CTRLR_DATA_SGLS_KEYED_DATA_BLOCK_SHIFT	(2)
+#define	NVME_CTRLR_DATA_SGLS_KEYED_DATA_BLOCK_MASK	(0x1)
+#define	NVME_CTRLR_DATA_SGLS_BIT_BUCKET_SHIFT		(16)
+#define	NVME_CTRLR_DATA_SGLS_BIT_BUCKET_MASK		(0x1)
+#define	NVME_CTRLR_DATA_SGLS_CONTIG_MPTR_SHIFT		(17)
+#define	NVME_CTRLR_DATA_SGLS_CONTIG_MPTR_MASK		(0x1)
+#define	NVME_CTRLR_DATA_SGLS_OVERSIZED_SHIFT		(18)
+#define	NVME_CTRLR_DATA_SGLS_OVERSIZED_MASK		(0x1)
+#define	NVME_CTRLR_DATA_SGLS_MPTR_SGL_SHIFT		(19)
+#define	NVME_CTRLR_DATA_SGLS_MPTR_SGL_MASK		(0x1)
+#define	NVME_CTRLR_DATA_SGLS_ADDRESS_AS_OFFSET_SHIFT	(20)
+#define	NVME_CTRLR_DATA_SGLS_ADDRESS_AS_OFFSET_MASK	(0x1)
+#define	NVME_CTRLR_DATA_SGLS_TRANSPORT_DATA_BLOCK_SHIFT	(21)
+#define	NVME_CTRLR_DATA_SGLS_TRANSPORT_DATA_BLOCK_MASK	(0x1)
+
 /** namespace features */
 /* thin provisioning */
 #define NVME_NS_DATA_NSFEAT_THIN_PROV_SHIFT		(0)
@@ -674,6 +693,38 @@ struct nvme_registers {
 
 _Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_registers");
 
+#define NVME_SGL_SUBTYPE_SHIFT				(0)
+#define NVME_SGL_SUBTYPE_MASK				(0xF)
+#define NVME_SGL_TYPE_SHIFT				(4)
+#define NVME_SGL_TYPE_MASK				(0xF)
+
+#define	NVME_SGL_TYPE(type, subtype)		\
+	((subtype) << NVME_SGL_SUBTYPE_SHIFT | (type) << NVME_SGL_TYPE_SHIFT)
+
+enum nvme_sgl_type {
+	NVME_SGL_TYPE_DATA_BLOCK		= 0x0,
+	NVME_SGL_TYPE_BIT_BUCKET		= 0x1,
+	NVME_SGL_TYPE_SEGMENT			= 0x2,
+	NVME_SGL_TYPE_LAST_SEGMENT		= 0x3,
+	NVME_SGL_TYPE_KEYED_DATA_BLOCK		= 0x4,
+	NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK	= 0x5,
+};
+
+enum nvme_sgl_subtype {
+	NVME_SGL_SUBTYPE_ADDRESS		= 0x0,
+	NVME_SGL_SUBTYPE_OFFSET			= 0x1,
+	NVME_SGL_SUBTYPE_TRANSPORT		= 0xa,
+};
+
+struct nvme_sgl_descriptor {
+	uint64_t address;
+	uint32_t length;
+	uint8_t reserved[3];
+	uint8_t type;
+};
+
+_Static_assert(sizeof(struct nvme_sgl_descriptor) == 16, "bad size for nvme_sgl_descriptor");
+
 struct nvme_command {
 	/* dword 0 */
 	uint8_t opc;		/* opcode */
@@ -690,11 +741,14 @@ struct nvme_command {
 	/* dword 4-5 */
 	uint64_t mptr;		/* metadata pointer */
 
-	/* dword 6-7 */
-	uint64_t prp1;		/* prp entry 1 */
-
-	/* dword 8-9 */
-	uint64_t prp2;		/* prp entry 2 */
+	/* dword 6-9 */
+	union {
+		struct {
+			uint64_t prp1;	/* prp entry 1 */
+			uint64_t prp2;	/* prp entry 2 */
+		};
+		struct nvme_sgl_descriptor sgl;
+	};
 
 	/* dword 10-15 */
 	uint32_t cdw10;		/* command-specific */