xref: /freebsd-src/sys/dev/nvmf/nvmf_proto.h (revision 1d425ef3414cdb0362c982f1820e659f2deb81a3)
1f2e73768SJohn Baldwin /*   SPDX-License-Identifier: BSD-3-Clause
2f2e73768SJohn Baldwin  *   Copyright (C) 2016 Intel Corporation.
3f2e73768SJohn Baldwin  *   All rights reserved.
4f2e73768SJohn Baldwin  */
5f2e73768SJohn Baldwin 
6878d102aSJohn Baldwin /* Derived from include/spdk/nvmf_spec.h from Intel's SPDK. */
7f2e73768SJohn Baldwin 
8878d102aSJohn Baldwin #ifndef __NVMF_PROTO_H__
9878d102aSJohn Baldwin #define	__NVMF_PROTO_H__
10f2e73768SJohn Baldwin 
11878d102aSJohn Baldwin #include <sys/types.h>
12878d102aSJohn Baldwin #include <sys/cdefs.h>
13878d102aSJohn Baldwin #ifdef _KERNEL
14878d102aSJohn Baldwin #include <sys/stddef.h>
15878d102aSJohn Baldwin #else
16878d102aSJohn Baldwin #include <stddef.h>
17878d102aSJohn Baldwin #endif
18878d102aSJohn Baldwin #include <dev/nvme/nvme.h>
19f2e73768SJohn Baldwin 
20f2e73768SJohn Baldwin /**
21f2e73768SJohn Baldwin  * \file
22f2e73768SJohn Baldwin  * NVMe over Fabrics specification definitions
23f2e73768SJohn Baldwin  */
24f2e73768SJohn Baldwin 
25878d102aSJohn Baldwin #define	NVME_NQN_FIELD_SIZE		256
26878d102aSJohn Baldwin 
27878d102aSJohn Baldwin struct nvmf_capsule_cmd {
28f2e73768SJohn Baldwin 	uint8_t		opcode;
29f2e73768SJohn Baldwin 	uint8_t		reserved1;
30f2e73768SJohn Baldwin 	uint16_t	cid;
31f2e73768SJohn Baldwin 	uint8_t		fctype;
32f2e73768SJohn Baldwin 	uint8_t		reserved2[35];
33f2e73768SJohn Baldwin 	uint8_t		fabric_specific[24];
34f2e73768SJohn Baldwin };
35878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_capsule_cmd) == 64, "Incorrect size");
36f2e73768SJohn Baldwin 
37f2e73768SJohn Baldwin /* Fabric Command Set */
38878d102aSJohn Baldwin enum nvmf_fabric_cmd_types {
39878d102aSJohn Baldwin 	NVMF_FABRIC_COMMAND_PROPERTY_SET			= 0x00,
40878d102aSJohn Baldwin 	NVMF_FABRIC_COMMAND_CONNECT				= 0x01,
41878d102aSJohn Baldwin 	NVMF_FABRIC_COMMAND_PROPERTY_GET			= 0x04,
42878d102aSJohn Baldwin 	NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND			= 0x05,
43878d102aSJohn Baldwin 	NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV			= 0x06,
4452d5738dSJohn Baldwin 	NVMF_FABRIC_COMMAND_DISCONNECT				= 0x08,
45878d102aSJohn Baldwin 	NVMF_FABRIC_COMMAND_START_VENDOR_SPECIFIC		= 0xC0,
46f2e73768SJohn Baldwin };
47f2e73768SJohn Baldwin 
48878d102aSJohn Baldwin enum nvmf_fabric_cmd_status_code {
49878d102aSJohn Baldwin 	NVMF_FABRIC_SC_INCOMPATIBLE_FORMAT		= 0x80,
50878d102aSJohn Baldwin 	NVMF_FABRIC_SC_CONTROLLER_BUSY			= 0x81,
51878d102aSJohn Baldwin 	NVMF_FABRIC_SC_INVALID_PARAM			= 0x82,
52878d102aSJohn Baldwin 	NVMF_FABRIC_SC_RESTART_DISCOVERY		= 0x83,
53878d102aSJohn Baldwin 	NVMF_FABRIC_SC_INVALID_HOST			= 0x84,
5452d5738dSJohn Baldwin 	NVMF_FABRIC_SC_INVALID_QUEUE_TYPE		= 0x85,
55878d102aSJohn Baldwin 	NVMF_FABRIC_SC_LOG_RESTART_DISCOVERY		= 0x90,
56878d102aSJohn Baldwin 	NVMF_FABRIC_SC_AUTH_REQUIRED			= 0x91,
57f2e73768SJohn Baldwin };
58f2e73768SJohn Baldwin 
59f2e73768SJohn Baldwin /**
60f2e73768SJohn Baldwin  * RDMA Queue Pair service types
61f2e73768SJohn Baldwin  */
62878d102aSJohn Baldwin enum nvmf_rdma_qptype {
63f2e73768SJohn Baldwin 	/** Reliable connected */
64878d102aSJohn Baldwin 	NVMF_RDMA_QPTYPE_RELIABLE_CONNECTED		= 0x1,
65f2e73768SJohn Baldwin 
66f2e73768SJohn Baldwin 	/** Reliable datagram */
67878d102aSJohn Baldwin 	NVMF_RDMA_QPTYPE_RELIABLE_DATAGRAM		= 0x2,
68f2e73768SJohn Baldwin };
69f2e73768SJohn Baldwin 
70f2e73768SJohn Baldwin /**
71f2e73768SJohn Baldwin  * RDMA provider types
72f2e73768SJohn Baldwin  */
73878d102aSJohn Baldwin enum nvmf_rdma_prtype {
74f2e73768SJohn Baldwin 	/** No provider specified */
75878d102aSJohn Baldwin 	NVMF_RDMA_PRTYPE_NONE		= 0x1,
76f2e73768SJohn Baldwin 
77f2e73768SJohn Baldwin 	/** InfiniBand */
78878d102aSJohn Baldwin 	NVMF_RDMA_PRTYPE_IB		= 0x2,
79f2e73768SJohn Baldwin 
80f2e73768SJohn Baldwin 	/** RoCE v1 */
81878d102aSJohn Baldwin 	NVMF_RDMA_PRTYPE_ROCE		= 0x3,
82f2e73768SJohn Baldwin 
83f2e73768SJohn Baldwin 	/** RoCE v2 */
84878d102aSJohn Baldwin 	NVMF_RDMA_PRTYPE_ROCE2		= 0x4,
85f2e73768SJohn Baldwin 
86f2e73768SJohn Baldwin 	/** iWARP */
87878d102aSJohn Baldwin 	NVMF_RDMA_PRTYPE_IWARP		= 0x5,
88f2e73768SJohn Baldwin };
89f2e73768SJohn Baldwin 
90f2e73768SJohn Baldwin /**
91f2e73768SJohn Baldwin  * RDMA connection management service types
92f2e73768SJohn Baldwin  */
93878d102aSJohn Baldwin enum nvmf_rdma_cms {
94f2e73768SJohn Baldwin 	/** Sockets based endpoint addressing */
95878d102aSJohn Baldwin 	NVMF_RDMA_CMS_RDMA_CM		= 0x1,
96f2e73768SJohn Baldwin };
97f2e73768SJohn Baldwin 
98f2e73768SJohn Baldwin /**
99f2e73768SJohn Baldwin  * NVMe over Fabrics transport types
100f2e73768SJohn Baldwin  */
101878d102aSJohn Baldwin enum nvmf_trtype {
102f2e73768SJohn Baldwin 	/** RDMA */
103878d102aSJohn Baldwin 	NVMF_TRTYPE_RDMA		= 0x1,
104f2e73768SJohn Baldwin 
105f2e73768SJohn Baldwin 	/** Fibre Channel */
106878d102aSJohn Baldwin 	NVMF_TRTYPE_FC			= 0x2,
107f2e73768SJohn Baldwin 
108f2e73768SJohn Baldwin 	/** TCP */
109878d102aSJohn Baldwin 	NVMF_TRTYPE_TCP			= 0x3,
110f2e73768SJohn Baldwin 
111f2e73768SJohn Baldwin 	/** Intra-host transport (loopback) */
112878d102aSJohn Baldwin 	NVMF_TRTYPE_INTRA_HOST		= 0xfe,
113f2e73768SJohn Baldwin };
114f2e73768SJohn Baldwin 
115f2e73768SJohn Baldwin /**
116f2e73768SJohn Baldwin  * Address family types
117f2e73768SJohn Baldwin  */
118878d102aSJohn Baldwin enum nvmf_adrfam {
119f2e73768SJohn Baldwin 	/** IPv4 (AF_INET) */
120878d102aSJohn Baldwin 	NVMF_ADRFAM_IPV4		= 0x1,
121f2e73768SJohn Baldwin 
122f2e73768SJohn Baldwin 	/** IPv6 (AF_INET6) */
123878d102aSJohn Baldwin 	NVMF_ADRFAM_IPV6		= 0x2,
124f2e73768SJohn Baldwin 
125f2e73768SJohn Baldwin 	/** InfiniBand (AF_IB) */
126878d102aSJohn Baldwin 	NVMF_ADRFAM_IB			= 0x3,
127f2e73768SJohn Baldwin 
128f2e73768SJohn Baldwin 	/** Fibre Channel address family */
129878d102aSJohn Baldwin 	NVMF_ADRFAM_FC			= 0x4,
130f2e73768SJohn Baldwin 
131f2e73768SJohn Baldwin 	/** Intra-host transport (loopback) */
132878d102aSJohn Baldwin 	NVMF_ADRFAM_INTRA_HOST		= 0xfe,
133f2e73768SJohn Baldwin };
134f2e73768SJohn Baldwin 
135f2e73768SJohn Baldwin /**
136f2e73768SJohn Baldwin  * NVM subsystem types
137f2e73768SJohn Baldwin  */
138878d102aSJohn Baldwin enum nvmf_subtype {
139f2e73768SJohn Baldwin 	/** Referral to a discovery service */
140878d102aSJohn Baldwin 	NVMF_SUBTYPE_DISCOVERY		= 0x1,
141f2e73768SJohn Baldwin 
142f2e73768SJohn Baldwin 	/** NVM Subsystem */
143878d102aSJohn Baldwin 	NVMF_SUBTYPE_NVME		= 0x2,
144f2e73768SJohn Baldwin 
145f2e73768SJohn Baldwin 	/** Current Discovery Subsystem */
146878d102aSJohn Baldwin 	NVMF_SUBTYPE_DISCOVERY_CURRENT	= 0x3
147f2e73768SJohn Baldwin };
148f2e73768SJohn Baldwin 
149f2e73768SJohn Baldwin /* Discovery Log Entry Flags - Duplicate Returned Information */
150878d102aSJohn Baldwin #define NVMF_DISCOVERY_LOG_EFLAGS_DUPRETINFO (1u << 0u)
151f2e73768SJohn Baldwin 
152f2e73768SJohn Baldwin /* Discovery Log Entry Flags - Explicit Persistent Connection Support for Discovery */
153878d102aSJohn Baldwin #define NVMF_DISCOVERY_LOG_EFLAGS_EPCSD (1u << 1u)
154f2e73768SJohn Baldwin 
155f2e73768SJohn Baldwin /**
156f2e73768SJohn Baldwin  * Connections shall be made over a fabric secure channel
157f2e73768SJohn Baldwin  */
158878d102aSJohn Baldwin enum nvmf_treq_secure_channel {
159f2e73768SJohn Baldwin 	/** Not specified */
160878d102aSJohn Baldwin 	NVMF_TREQ_SECURE_CHANNEL_NOT_SPECIFIED		= 0x0,
161f2e73768SJohn Baldwin 
162f2e73768SJohn Baldwin 	/** Required */
163878d102aSJohn Baldwin 	NVMF_TREQ_SECURE_CHANNEL_REQUIRED		= 0x1,
164f2e73768SJohn Baldwin 
165f2e73768SJohn Baldwin 	/** Not required */
166878d102aSJohn Baldwin 	NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED		= 0x2,
167f2e73768SJohn Baldwin };
168f2e73768SJohn Baldwin 
16952d5738dSJohn Baldwin struct nvmf_fabric_cmd {
17052d5738dSJohn Baldwin 	uint8_t		opcode;
17152d5738dSJohn Baldwin 	uint8_t		reserved1;
17252d5738dSJohn Baldwin 	uint16_t	cid;
17352d5738dSJohn Baldwin 	uint8_t		fctype;
17452d5738dSJohn Baldwin 	uint8_t		reserved2[59];
175*1d425ef3SJohn Baldwin } __aligned(8);
17652d5738dSJohn Baldwin 
177878d102aSJohn Baldwin struct nvmf_fabric_auth_recv_cmd {
178f2e73768SJohn Baldwin 	uint8_t		opcode;
179f2e73768SJohn Baldwin 	uint8_t		reserved1;
180f2e73768SJohn Baldwin 	uint16_t	cid;
181f2e73768SJohn Baldwin 	uint8_t		fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV (0x06) */
182f2e73768SJohn Baldwin 	uint8_t		reserved2[19];
183878d102aSJohn Baldwin 	struct nvme_sgl_descriptor sgl1;
184f2e73768SJohn Baldwin 	uint8_t		reserved3;
185f2e73768SJohn Baldwin 	uint8_t		spsp0;
186f2e73768SJohn Baldwin 	uint8_t		spsp1;
187f2e73768SJohn Baldwin 	uint8_t		secp;
188f2e73768SJohn Baldwin 	uint32_t	al;
189f2e73768SJohn Baldwin 	uint8_t		reserved4[16];
190f2e73768SJohn Baldwin };
191878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_auth_recv_cmd) == 64, "Incorrect size");
192f2e73768SJohn Baldwin 
193878d102aSJohn Baldwin struct nvmf_fabric_auth_send_cmd {
194f2e73768SJohn Baldwin 	uint8_t		opcode;
195f2e73768SJohn Baldwin 	uint8_t		reserved1;
196f2e73768SJohn Baldwin 	uint16_t	cid;
197f2e73768SJohn Baldwin 	uint8_t		fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND (0x05) */
198f2e73768SJohn Baldwin 	uint8_t		reserved2[19];
199878d102aSJohn Baldwin 	struct nvme_sgl_descriptor sgl1;
200f2e73768SJohn Baldwin 	uint8_t		reserved3;
201f2e73768SJohn Baldwin 	uint8_t		spsp0;
202f2e73768SJohn Baldwin 	uint8_t		spsp1;
203f2e73768SJohn Baldwin 	uint8_t		secp;
204f2e73768SJohn Baldwin 	uint32_t	tl;
205f2e73768SJohn Baldwin 	uint8_t		reserved4[16];
206f2e73768SJohn Baldwin };
207878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_auth_send_cmd) == 64, "Incorrect size");
208f2e73768SJohn Baldwin 
209878d102aSJohn Baldwin struct nvmf_fabric_connect_data {
210f2e73768SJohn Baldwin 	uint8_t		hostid[16];
211f2e73768SJohn Baldwin 	uint16_t	cntlid;
212f2e73768SJohn Baldwin 	uint8_t		reserved5[238];
213878d102aSJohn Baldwin 	uint8_t		subnqn[NVME_NQN_FIELD_SIZE];
214878d102aSJohn Baldwin 	uint8_t		hostnqn[NVME_NQN_FIELD_SIZE];
215f2e73768SJohn Baldwin 	uint8_t		reserved6[256];
216f2e73768SJohn Baldwin };
217878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_connect_data) == 1024, "Incorrect size");
218f2e73768SJohn Baldwin 
219878d102aSJohn Baldwin struct nvmf_fabric_connect_cmd {
220f2e73768SJohn Baldwin 	uint8_t		opcode;
221f2e73768SJohn Baldwin 	uint8_t		reserved1;
222f2e73768SJohn Baldwin 	uint16_t	cid;
223f2e73768SJohn Baldwin 	uint8_t		fctype;
224f2e73768SJohn Baldwin 	uint8_t		reserved2[19];
225878d102aSJohn Baldwin 	struct nvme_sgl_descriptor sgl1;
226f2e73768SJohn Baldwin 	uint16_t	recfmt; /* Connect Record Format */
227f2e73768SJohn Baldwin 	uint16_t	qid; /* Queue Identifier */
228f2e73768SJohn Baldwin 	uint16_t	sqsize; /* Submission Queue Size */
229f2e73768SJohn Baldwin 	uint8_t		cattr; /* queue attributes */
230f2e73768SJohn Baldwin 	uint8_t		reserved3;
231f2e73768SJohn Baldwin 	uint32_t	kato; /* keep alive timeout */
232f2e73768SJohn Baldwin 	uint8_t		reserved4[12];
233f2e73768SJohn Baldwin };
234878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_connect_cmd) == 64, "Incorrect size");
235f2e73768SJohn Baldwin 
23652d5738dSJohn Baldwin #define	NVMF_CNTLID_DYNAMIC	0xFFFF
23752d5738dSJohn Baldwin #define	NVMF_CNTLID_STATIC_ANY	0xFFFE
23852d5738dSJohn Baldwin 
23952d5738dSJohn Baldwin /*
24052d5738dSJohn Baldwin  * XXX: 5.3 in NVMe-over-Fabrics 1.1 gives this as an upper bound in
24152d5738dSJohn Baldwin  * the Discovery Log Entry.
24252d5738dSJohn Baldwin  */
24352d5738dSJohn Baldwin #define	NVMF_CNTLID_STATIC_MAX	0xFFEF
24452d5738dSJohn Baldwin 
24552d5738dSJohn Baldwin /* 5.21.1.15 in NVMe 1.4b */
24652d5738dSJohn Baldwin #define	NVMF_KATO_DEFAULT			(120000)
24752d5738dSJohn Baldwin 
24852d5738dSJohn Baldwin #define NVMF_CONNECT_ATTR_PRIORITY_CLASS	(0x3)
24952d5738dSJohn Baldwin #define NVMF_CONNECT_ATTR_DISABLE_SQ_FC		(1u << 2)
25052d5738dSJohn Baldwin #define NVMF_CONNECT_ATTR_IO_QUEUE_DELETION	(1u << 3)
25152d5738dSJohn Baldwin 
252878d102aSJohn Baldwin struct nvmf_fabric_connect_rsp {
253f2e73768SJohn Baldwin 	union {
254f2e73768SJohn Baldwin 		struct {
255f2e73768SJohn Baldwin 			uint16_t cntlid;
256f2e73768SJohn Baldwin 			uint16_t authreq;
257f2e73768SJohn Baldwin 		} success;
258f2e73768SJohn Baldwin 
259f2e73768SJohn Baldwin 		struct {
260f2e73768SJohn Baldwin 			uint16_t	ipo;
261f2e73768SJohn Baldwin 			uint8_t		iattr;
262f2e73768SJohn Baldwin 			uint8_t		reserved;
263f2e73768SJohn Baldwin 		} invalid;
264f2e73768SJohn Baldwin 
265f2e73768SJohn Baldwin 		uint32_t raw;
266f2e73768SJohn Baldwin 	} status_code_specific;
267f2e73768SJohn Baldwin 
268f2e73768SJohn Baldwin 	uint32_t	reserved0;
269f2e73768SJohn Baldwin 	uint16_t	sqhd;
270f2e73768SJohn Baldwin 	uint16_t	reserved1;
271f2e73768SJohn Baldwin 	uint16_t	cid;
272878d102aSJohn Baldwin 	uint16_t	status;
273f2e73768SJohn Baldwin };
274878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_connect_rsp) == 16, "Incorrect size");
275f2e73768SJohn Baldwin 
27652d5738dSJohn Baldwin struct nvmf_fabric_disconnect_cmd {
27752d5738dSJohn Baldwin 	uint8_t		opcode;
27852d5738dSJohn Baldwin 	uint8_t		reserved1;
27952d5738dSJohn Baldwin 	uint16_t	cid;
28052d5738dSJohn Baldwin 	uint8_t		fctype;
28152d5738dSJohn Baldwin 	uint8_t		reserved2[19];
28252d5738dSJohn Baldwin 	struct nvme_sgl_descriptor sgl1;
28352d5738dSJohn Baldwin 	uint16_t	recfmt; /* Disconnect Record Format */
28452d5738dSJohn Baldwin 	uint8_t		reserved3[22];
28552d5738dSJohn Baldwin };
28652d5738dSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_disconnect_cmd) == 64, "Incorrect size");
28752d5738dSJohn Baldwin 
288878d102aSJohn Baldwin #define NVMF_PROP_SIZE_4	0
289878d102aSJohn Baldwin #define NVMF_PROP_SIZE_8	1
290f2e73768SJohn Baldwin 
29152d5738dSJohn Baldwin #define	NVMF_PROP_CAP		0x00	/* Controller Capabilities */
29252d5738dSJohn Baldwin #define	NVMF_PROP_VS		0x08	/* Version */
29352d5738dSJohn Baldwin #define	NVMF_PROP_CC		0x14	/* Controller Configuration */
29452d5738dSJohn Baldwin #define	NVMF_PROP_CSTS		0x1C	/* Controller Status */
29552d5738dSJohn Baldwin #define	NVMF_PROP_NSSR		0x20	/* NVM Subsystem Reset */
29652d5738dSJohn Baldwin 
297878d102aSJohn Baldwin struct nvmf_fabric_prop_get_cmd {
298f2e73768SJohn Baldwin 	uint8_t		opcode;
299f2e73768SJohn Baldwin 	uint8_t		reserved1;
300f2e73768SJohn Baldwin 	uint16_t	cid;
301f2e73768SJohn Baldwin 	uint8_t		fctype;
302f2e73768SJohn Baldwin 	uint8_t		reserved2[35];
303f2e73768SJohn Baldwin 	struct {
304f2e73768SJohn Baldwin 		uint8_t size		: 3;
305f2e73768SJohn Baldwin 		uint8_t reserved	: 5;
306f2e73768SJohn Baldwin 	} attrib;
307f2e73768SJohn Baldwin 	uint8_t		reserved3[3];
308f2e73768SJohn Baldwin 	uint32_t	ofst;
309f2e73768SJohn Baldwin 	uint8_t		reserved4[16];
310f2e73768SJohn Baldwin };
311878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_prop_get_cmd) == 64, "Incorrect size");
312f2e73768SJohn Baldwin 
313878d102aSJohn Baldwin struct nvmf_fabric_prop_get_rsp {
314f2e73768SJohn Baldwin 	union {
315f2e73768SJohn Baldwin 		uint64_t u64;
316f2e73768SJohn Baldwin 		struct {
317f2e73768SJohn Baldwin 			uint32_t low;
318f2e73768SJohn Baldwin 			uint32_t high;
319f2e73768SJohn Baldwin 		} u32;
320f2e73768SJohn Baldwin 	} value;
321f2e73768SJohn Baldwin 
322f2e73768SJohn Baldwin 	uint16_t	sqhd;
323f2e73768SJohn Baldwin 	uint16_t	reserved0;
324f2e73768SJohn Baldwin 	uint16_t	cid;
325878d102aSJohn Baldwin 	uint16_t	status;
326f2e73768SJohn Baldwin };
327878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_prop_get_rsp) == 16, "Incorrect size");
328f2e73768SJohn Baldwin 
329878d102aSJohn Baldwin struct nvmf_fabric_prop_set_cmd {
330f2e73768SJohn Baldwin 	uint8_t		opcode;
331f2e73768SJohn Baldwin 	uint8_t		reserved0;
332f2e73768SJohn Baldwin 	uint16_t	cid;
333f2e73768SJohn Baldwin 	uint8_t		fctype;
334f2e73768SJohn Baldwin 	uint8_t		reserved1[35];
335f2e73768SJohn Baldwin 	struct {
336f2e73768SJohn Baldwin 		uint8_t size		: 3;
337f2e73768SJohn Baldwin 		uint8_t reserved	: 5;
338f2e73768SJohn Baldwin 	} attrib;
339f2e73768SJohn Baldwin 	uint8_t		reserved2[3];
340f2e73768SJohn Baldwin 	uint32_t	ofst;
341f2e73768SJohn Baldwin 
342f2e73768SJohn Baldwin 	union {
343f2e73768SJohn Baldwin 		uint64_t u64;
344f2e73768SJohn Baldwin 		struct {
345f2e73768SJohn Baldwin 			uint32_t low;
346f2e73768SJohn Baldwin 			uint32_t high;
347f2e73768SJohn Baldwin 		} u32;
348f2e73768SJohn Baldwin 	} value;
349f2e73768SJohn Baldwin 
350f2e73768SJohn Baldwin 	uint8_t		reserved4[8];
351f2e73768SJohn Baldwin };
352878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_fabric_prop_set_cmd) == 64, "Incorrect size");
353f2e73768SJohn Baldwin 
354878d102aSJohn Baldwin #define NVMF_NQN_MIN_LEN 11 /* The prefix in the spec is 11 characters */
355878d102aSJohn Baldwin #define NVMF_NQN_MAX_LEN 223
356878d102aSJohn Baldwin #define NVMF_NQN_UUID_PRE_LEN 32
357878d102aSJohn Baldwin #define NVMF_UUID_STRING_LEN 36
358878d102aSJohn Baldwin #define NVMF_NQN_UUID_PRE "nqn.2014-08.org.nvmexpress:uuid:"
359878d102aSJohn Baldwin #define NVMF_DISCOVERY_NQN "nqn.2014-08.org.nvmexpress.discovery"
360f2e73768SJohn Baldwin 
361878d102aSJohn Baldwin #define NVMF_TRSTRING_MAX_LEN 32
362878d102aSJohn Baldwin #define NVMF_TRADDR_MAX_LEN 256
363878d102aSJohn Baldwin #define NVMF_TRSVCID_MAX_LEN 32
364f2e73768SJohn Baldwin 
365f2e73768SJohn Baldwin /** RDMA transport-specific address subtype */
366878d102aSJohn Baldwin struct nvmf_rdma_transport_specific_address_subtype {
367878d102aSJohn Baldwin 	/** RDMA QP service type (\ref nvmf_rdma_qptype) */
368f2e73768SJohn Baldwin 	uint8_t		rdma_qptype;
369f2e73768SJohn Baldwin 
370878d102aSJohn Baldwin 	/** RDMA provider type (\ref nvmf_rdma_prtype) */
371f2e73768SJohn Baldwin 	uint8_t		rdma_prtype;
372f2e73768SJohn Baldwin 
373878d102aSJohn Baldwin 	/** RDMA connection management service (\ref nvmf_rdma_cms) */
374f2e73768SJohn Baldwin 	uint8_t		rdma_cms;
375f2e73768SJohn Baldwin 
376f2e73768SJohn Baldwin 	uint8_t		reserved0[5];
377f2e73768SJohn Baldwin 
378f2e73768SJohn Baldwin 	/** RDMA partition key for AF_IB */
379f2e73768SJohn Baldwin 	uint16_t	rdma_pkey;
380f2e73768SJohn Baldwin 
381f2e73768SJohn Baldwin 	uint8_t		reserved2[246];
382f2e73768SJohn Baldwin };
383878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_rdma_transport_specific_address_subtype) == 256,
384f2e73768SJohn Baldwin 		   "Incorrect size");
385f2e73768SJohn Baldwin 
386f2e73768SJohn Baldwin /** TCP Secure Socket Type */
387878d102aSJohn Baldwin enum nvme_tcp_secure_socket_type {
388f2e73768SJohn Baldwin 	/** No security */
389878d102aSJohn Baldwin 	NVME_TCP_SECURITY_NONE				= 0,
390f2e73768SJohn Baldwin 
391f2e73768SJohn Baldwin 	/** TLS (Secure Sockets) version 1.2 */
392878d102aSJohn Baldwin 	NVME_TCP_SECURITY_TLS_1_2			= 1,
393f2e73768SJohn Baldwin 
394f2e73768SJohn Baldwin 	/** TLS (Secure Sockets) version 1.3 */
395878d102aSJohn Baldwin 	NVME_TCP_SECURITY_TLS_1_3			= 2,
396f2e73768SJohn Baldwin };
397f2e73768SJohn Baldwin 
398f2e73768SJohn Baldwin /** TCP transport-specific address subtype */
399878d102aSJohn Baldwin struct nvme_tcp_transport_specific_address_subtype {
400878d102aSJohn Baldwin 	/** Security type (\ref nvme_tcp_secure_socket_type) */
401f2e73768SJohn Baldwin 	uint8_t		sectype;
402f2e73768SJohn Baldwin 
403f2e73768SJohn Baldwin 	uint8_t		reserved0[255];
404f2e73768SJohn Baldwin };
405878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_transport_specific_address_subtype) == 256,
406f2e73768SJohn Baldwin 		   "Incorrect size");
407f2e73768SJohn Baldwin 
408f2e73768SJohn Baldwin /** Transport-specific address subtype */
409878d102aSJohn Baldwin union nvmf_transport_specific_address_subtype {
410f2e73768SJohn Baldwin 	uint8_t raw[256];
411f2e73768SJohn Baldwin 
412f2e73768SJohn Baldwin 	/** RDMA */
413878d102aSJohn Baldwin 	struct nvmf_rdma_transport_specific_address_subtype rdma;
414f2e73768SJohn Baldwin 
415f2e73768SJohn Baldwin 	/** TCP */
416878d102aSJohn Baldwin 	struct nvme_tcp_transport_specific_address_subtype tcp;
417f2e73768SJohn Baldwin };
418878d102aSJohn Baldwin _Static_assert(sizeof(union nvmf_transport_specific_address_subtype) == 256,
419f2e73768SJohn Baldwin 		   "Incorrect size");
420f2e73768SJohn Baldwin 
421878d102aSJohn Baldwin #define NVMF_MIN_ADMIN_MAX_SQ_SIZE 32
422f2e73768SJohn Baldwin 
423f2e73768SJohn Baldwin /**
424f2e73768SJohn Baldwin  * Discovery Log Page entry
425f2e73768SJohn Baldwin  */
426878d102aSJohn Baldwin struct nvmf_discovery_log_page_entry {
427878d102aSJohn Baldwin 	/** Transport type (\ref nvmf_trtype) */
428f2e73768SJohn Baldwin 	uint8_t		trtype;
429f2e73768SJohn Baldwin 
430878d102aSJohn Baldwin 	/** Address family (\ref nvmf_adrfam) */
431f2e73768SJohn Baldwin 	uint8_t		adrfam;
432f2e73768SJohn Baldwin 
433878d102aSJohn Baldwin 	/** Subsystem type (\ref nvmf_subtype) */
434f2e73768SJohn Baldwin 	uint8_t		subtype;
435f2e73768SJohn Baldwin 
436f2e73768SJohn Baldwin 	/** Transport requirements */
437f2e73768SJohn Baldwin 	struct {
438878d102aSJohn Baldwin 		/** Secure channel requirements (\ref nvmf_treq_secure_channel) */
439f2e73768SJohn Baldwin 		uint8_t secure_channel : 2;
440f2e73768SJohn Baldwin 
441f2e73768SJohn Baldwin 		uint8_t reserved : 6;
442f2e73768SJohn Baldwin 	} treq;
443f2e73768SJohn Baldwin 
444f2e73768SJohn Baldwin 	/** NVM subsystem port ID */
445f2e73768SJohn Baldwin 	uint16_t	portid;
446f2e73768SJohn Baldwin 
447f2e73768SJohn Baldwin 	/** Controller ID */
448f2e73768SJohn Baldwin 	uint16_t	cntlid;
449f2e73768SJohn Baldwin 
450f2e73768SJohn Baldwin 	/** Admin max SQ size */
451f2e73768SJohn Baldwin 	uint16_t	asqsz;
452f2e73768SJohn Baldwin 
453f2e73768SJohn Baldwin 	/** Entry Flags */
454f2e73768SJohn Baldwin 	uint16_t	eflags;
455f2e73768SJohn Baldwin 
456f2e73768SJohn Baldwin 	uint8_t		reserved0[20];
457f2e73768SJohn Baldwin 
458f2e73768SJohn Baldwin 	/** Transport service identifier */
459878d102aSJohn Baldwin 	uint8_t		trsvcid[NVMF_TRSVCID_MAX_LEN];
460f2e73768SJohn Baldwin 
461f2e73768SJohn Baldwin 	uint8_t		reserved1[192];
462f2e73768SJohn Baldwin 
463f2e73768SJohn Baldwin 	/** NVM subsystem qualified name */
464f2e73768SJohn Baldwin 	uint8_t		subnqn[256];
465f2e73768SJohn Baldwin 
466f2e73768SJohn Baldwin 	/** Transport address */
467878d102aSJohn Baldwin 	uint8_t		traddr[NVMF_TRADDR_MAX_LEN];
468f2e73768SJohn Baldwin 
469f2e73768SJohn Baldwin 	/** Transport-specific address subtype */
470878d102aSJohn Baldwin 	union nvmf_transport_specific_address_subtype tsas;
471f2e73768SJohn Baldwin };
472878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_discovery_log_page_entry) == 1024, "Incorrect size");
473f2e73768SJohn Baldwin 
474878d102aSJohn Baldwin struct nvmf_discovery_log_page {
475f2e73768SJohn Baldwin 	uint64_t	genctr;
476f2e73768SJohn Baldwin 	uint64_t	numrec;
477f2e73768SJohn Baldwin 	uint16_t	recfmt;
478f2e73768SJohn Baldwin 	uint8_t		reserved0[1006];
479878d102aSJohn Baldwin 	struct nvmf_discovery_log_page_entry entries[0];
480f2e73768SJohn Baldwin };
481878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_discovery_log_page) == 1024, "Incorrect size");
482f2e73768SJohn Baldwin 
483f2e73768SJohn Baldwin /* RDMA Fabric specific definitions below */
484f2e73768SJohn Baldwin 
485878d102aSJohn Baldwin #define NVME_SGL_SUBTYPE_INVALIDATE_KEY	0xF
486f2e73768SJohn Baldwin 
487878d102aSJohn Baldwin struct nvmf_rdma_request_private_data {
488f2e73768SJohn Baldwin 	uint16_t	recfmt; /* record format */
489f2e73768SJohn Baldwin 	uint16_t	qid;	/* queue id */
490f2e73768SJohn Baldwin 	uint16_t	hrqsize;	/* host receive queue size */
491f2e73768SJohn Baldwin 	uint16_t	hsqsize;	/* host send queue size */
492f2e73768SJohn Baldwin 	uint16_t	cntlid;		/* controller id */
493f2e73768SJohn Baldwin 	uint8_t		reserved[22];
494f2e73768SJohn Baldwin };
495878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_rdma_request_private_data) == 32, "Incorrect size");
496f2e73768SJohn Baldwin 
497878d102aSJohn Baldwin struct nvmf_rdma_accept_private_data {
498f2e73768SJohn Baldwin 	uint16_t	recfmt; /* record format */
499f2e73768SJohn Baldwin 	uint16_t	crqsize;	/* controller receive queue size */
500f2e73768SJohn Baldwin 	uint8_t		reserved[28];
501f2e73768SJohn Baldwin };
502878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_rdma_accept_private_data) == 32, "Incorrect size");
503f2e73768SJohn Baldwin 
504878d102aSJohn Baldwin struct nvmf_rdma_reject_private_data {
505f2e73768SJohn Baldwin 	uint16_t	recfmt; /* record format */
506f2e73768SJohn Baldwin 	uint16_t	sts; /* status */
507f2e73768SJohn Baldwin };
508878d102aSJohn Baldwin _Static_assert(sizeof(struct nvmf_rdma_reject_private_data) == 4, "Incorrect size");
509f2e73768SJohn Baldwin 
510878d102aSJohn Baldwin union nvmf_rdma_private_data {
511878d102aSJohn Baldwin 	struct nvmf_rdma_request_private_data	pd_request;
512878d102aSJohn Baldwin 	struct nvmf_rdma_accept_private_data	pd_accept;
513878d102aSJohn Baldwin 	struct nvmf_rdma_reject_private_data	pd_reject;
514f2e73768SJohn Baldwin };
515878d102aSJohn Baldwin _Static_assert(sizeof(union nvmf_rdma_private_data) == 32, "Incorrect size");
516f2e73768SJohn Baldwin 
517878d102aSJohn Baldwin enum nvmf_rdma_transport_error {
518878d102aSJohn Baldwin 	NVMF_RDMA_ERROR_INVALID_PRIVATE_DATA_LENGTH	= 0x1,
519878d102aSJohn Baldwin 	NVMF_RDMA_ERROR_INVALID_RECFMT			= 0x2,
520878d102aSJohn Baldwin 	NVMF_RDMA_ERROR_INVALID_QID			= 0x3,
521878d102aSJohn Baldwin 	NVMF_RDMA_ERROR_INVALID_HSQSIZE			= 0x4,
522878d102aSJohn Baldwin 	NVMF_RDMA_ERROR_INVALID_HRQSIZE			= 0x5,
523878d102aSJohn Baldwin 	NVMF_RDMA_ERROR_NO_RESOURCES			= 0x6,
524878d102aSJohn Baldwin 	NVMF_RDMA_ERROR_INVALID_IRD			= 0x7,
525878d102aSJohn Baldwin 	NVMF_RDMA_ERROR_INVALID_ORD			= 0x8,
526f2e73768SJohn Baldwin };
527f2e73768SJohn Baldwin 
528f2e73768SJohn Baldwin /* TCP transport specific definitions below */
529f2e73768SJohn Baldwin 
530f2e73768SJohn Baldwin /** NVMe/TCP PDU type */
531878d102aSJohn Baldwin enum nvme_tcp_pdu_type {
532f2e73768SJohn Baldwin 	/** Initialize Connection Request (ICReq) */
533878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_IC_REQ			= 0x00,
534f2e73768SJohn Baldwin 
535f2e73768SJohn Baldwin 	/** Initialize Connection Response (ICResp) */
536878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_IC_RESP			= 0x01,
537f2e73768SJohn Baldwin 
538f2e73768SJohn Baldwin 	/** Terminate Connection Request (TermReq) */
539878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_H2C_TERM_REQ			= 0x02,
540f2e73768SJohn Baldwin 
541f2e73768SJohn Baldwin 	/** Terminate Connection Response (TermResp) */
542878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_C2H_TERM_REQ			= 0x03,
543f2e73768SJohn Baldwin 
544f2e73768SJohn Baldwin 	/** Command Capsule (CapsuleCmd) */
545878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_CAPSULE_CMD			= 0x04,
546f2e73768SJohn Baldwin 
547f2e73768SJohn Baldwin 	/** Response Capsule (CapsuleRsp) */
548878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_CAPSULE_RESP			= 0x05,
549f2e73768SJohn Baldwin 
550f2e73768SJohn Baldwin 	/** Host To Controller Data (H2CData) */
551878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_H2C_DATA			= 0x06,
552f2e73768SJohn Baldwin 
553f2e73768SJohn Baldwin 	/** Controller To Host Data (C2HData) */
554878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_C2H_DATA			= 0x07,
555f2e73768SJohn Baldwin 
556f2e73768SJohn Baldwin 	/** Ready to Transfer (R2T) */
557878d102aSJohn Baldwin 	NVME_TCP_PDU_TYPE_R2T				= 0x09,
558f2e73768SJohn Baldwin };
559f2e73768SJohn Baldwin 
560f2e73768SJohn Baldwin /** Common NVMe/TCP PDU header */
561878d102aSJohn Baldwin struct nvme_tcp_common_pdu_hdr {
562878d102aSJohn Baldwin 	/** PDU type (\ref nvme_tcp_pdu_type) */
563f2e73768SJohn Baldwin 	uint8_t				pdu_type;
564f2e73768SJohn Baldwin 
565f2e73768SJohn Baldwin 	/** pdu_type-specific flags */
566f2e73768SJohn Baldwin 	uint8_t				flags;
567f2e73768SJohn Baldwin 
568f2e73768SJohn Baldwin 	/** Length of PDU header (not including the Header Digest) */
569f2e73768SJohn Baldwin 	uint8_t				hlen;
570f2e73768SJohn Baldwin 
571f2e73768SJohn Baldwin 	/** PDU Data Offset from the start of the PDU */
572f2e73768SJohn Baldwin 	uint8_t				pdo;
573f2e73768SJohn Baldwin 
574f2e73768SJohn Baldwin 	/** Total number of bytes in PDU, including pdu_hdr */
575f2e73768SJohn Baldwin 	uint32_t			plen;
576f2e73768SJohn Baldwin };
577878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_common_pdu_hdr) == 8, "Incorrect size");
578878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, pdu_type) == 0,
579f2e73768SJohn Baldwin 		   "Incorrect offset");
580878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, flags) == 1, "Incorrect offset");
581878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, hlen) == 2, "Incorrect offset");
582878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, pdo) == 3, "Incorrect offset");
583878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, plen) == 4, "Incorrect offset");
584f2e73768SJohn Baldwin 
585878d102aSJohn Baldwin #define NVME_TCP_CH_FLAGS_HDGSTF		(1u << 0)
586878d102aSJohn Baldwin #define NVME_TCP_CH_FLAGS_DDGSTF		(1u << 1)
587f2e73768SJohn Baldwin 
588f2e73768SJohn Baldwin /**
589f2e73768SJohn Baldwin  * ICReq
590f2e73768SJohn Baldwin  *
591878d102aSJohn Baldwin  * common.pdu_type == NVME_TCP_PDU_TYPE_IC_REQ
592f2e73768SJohn Baldwin  */
593878d102aSJohn Baldwin struct nvme_tcp_ic_req {
594878d102aSJohn Baldwin 	struct nvme_tcp_common_pdu_hdr	common;
595f2e73768SJohn Baldwin 	uint16_t				pfv;
596f2e73768SJohn Baldwin 	/** Specifies the data alignment for all PDUs transferred from the controller to the host that contain data */
597f2e73768SJohn Baldwin 	uint8_t					hpda;
598f2e73768SJohn Baldwin 	union {
599f2e73768SJohn Baldwin 		uint8_t				raw;
600f2e73768SJohn Baldwin 		struct {
601f2e73768SJohn Baldwin 			uint8_t			hdgst_enable : 1;
602f2e73768SJohn Baldwin 			uint8_t			ddgst_enable : 1;
603f2e73768SJohn Baldwin 			uint8_t			reserved : 6;
604f2e73768SJohn Baldwin 		} bits;
605f2e73768SJohn Baldwin 	} dgst;
606f2e73768SJohn Baldwin 	uint32_t				maxr2t;
607f2e73768SJohn Baldwin 	uint8_t					reserved16[112];
608f2e73768SJohn Baldwin };
609878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_ic_req) == 128, "Incorrect size");
610878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_ic_req, pfv) == 8, "Incorrect offset");
611878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_ic_req, hpda) == 10, "Incorrect offset");
612878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_ic_req, maxr2t) == 12, "Incorrect offset");
613f2e73768SJohn Baldwin 
614878d102aSJohn Baldwin #define NVME_TCP_HPDA_MAX 31
615878d102aSJohn Baldwin #define NVME_TCP_CPDA_MAX 31
616878d102aSJohn Baldwin #define NVME_TCP_PDU_PDO_MAX_OFFSET     ((NVME_TCP_CPDA_MAX + 1) << 2)
617f2e73768SJohn Baldwin 
618f2e73768SJohn Baldwin /**
619f2e73768SJohn Baldwin  * ICResp
620f2e73768SJohn Baldwin  *
621878d102aSJohn Baldwin  * common.pdu_type == NVME_TCP_PDU_TYPE_IC_RESP
622f2e73768SJohn Baldwin  */
623878d102aSJohn Baldwin struct nvme_tcp_ic_resp {
624878d102aSJohn Baldwin 	struct nvme_tcp_common_pdu_hdr	common;
625f2e73768SJohn Baldwin 	uint16_t				pfv;
626f2e73768SJohn Baldwin 	/** Specifies the data alignment for all PDUs transferred from the host to the controller that contain data */
627f2e73768SJohn Baldwin 	uint8_t					cpda;
628f2e73768SJohn Baldwin 	union {
629f2e73768SJohn Baldwin 		uint8_t				raw;
630f2e73768SJohn Baldwin 		struct {
631f2e73768SJohn Baldwin 			uint8_t			hdgst_enable : 1;
632f2e73768SJohn Baldwin 			uint8_t			ddgst_enable : 1;
633f2e73768SJohn Baldwin 			uint8_t			reserved : 6;
634f2e73768SJohn Baldwin 		} bits;
635f2e73768SJohn Baldwin 	} dgst;
636f2e73768SJohn Baldwin 	/** Specifies the maximum number of PDU-Data bytes per H2C Data Transfer PDU */
637f2e73768SJohn Baldwin 	uint32_t				maxh2cdata;
638f2e73768SJohn Baldwin 	uint8_t					reserved16[112];
639f2e73768SJohn Baldwin };
640878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_ic_resp) == 128, "Incorrect size");
641878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_ic_resp, pfv) == 8, "Incorrect offset");
642878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_ic_resp, cpda) == 10, "Incorrect offset");
643878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_ic_resp, maxh2cdata) == 12, "Incorrect offset");
644f2e73768SJohn Baldwin 
645f2e73768SJohn Baldwin /**
646f2e73768SJohn Baldwin  * TermReq
647f2e73768SJohn Baldwin  *
648878d102aSJohn Baldwin  * common.pdu_type == NVME_TCP_PDU_TYPE_TERM_REQ
649f2e73768SJohn Baldwin  */
650878d102aSJohn Baldwin struct nvme_tcp_term_req_hdr {
651878d102aSJohn Baldwin 	struct nvme_tcp_common_pdu_hdr	common;
652f2e73768SJohn Baldwin 	uint16_t				fes;
653f2e73768SJohn Baldwin 	uint8_t					fei[4];
654f2e73768SJohn Baldwin 	uint8_t					reserved14[10];
655f2e73768SJohn Baldwin };
656f2e73768SJohn Baldwin 
657878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_term_req_hdr) == 24, "Incorrect size");
658878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_term_req_hdr, fes) == 8, "Incorrect offset");
659878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_term_req_hdr, fei) == 10, "Incorrect offset");
660f2e73768SJohn Baldwin 
661878d102aSJohn Baldwin enum nvme_tcp_term_req_fes {
662878d102aSJohn Baldwin 	NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD			= 0x01,
663878d102aSJohn Baldwin 	NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR			= 0x02,
664878d102aSJohn Baldwin 	NVME_TCP_TERM_REQ_FES_HDGST_ERROR				= 0x03,
665878d102aSJohn Baldwin 	NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE		= 0x04,
666878d102aSJohn Baldwin 	NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_LIMIT_EXCEEDED		= 0x05,
667878d102aSJohn Baldwin 	NVME_TCP_TERM_REQ_FES_R2T_LIMIT_EXCEEDED			= 0x05,
668878d102aSJohn Baldwin 	NVME_TCP_TERM_REQ_FES_INVALID_DATA_UNSUPPORTED_PARAMETER	= 0x06,
669f2e73768SJohn Baldwin };
670f2e73768SJohn Baldwin 
671f2e73768SJohn Baldwin /* Total length of term req PDU (including PDU header and DATA) in bytes shall not exceed a limit of 152 bytes. */
672878d102aSJohn Baldwin #define NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE	128
673878d102aSJohn Baldwin #define NVME_TCP_TERM_REQ_PDU_MAX_SIZE		(NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE + sizeof(struct nvme_tcp_term_req_hdr))
674f2e73768SJohn Baldwin 
675f2e73768SJohn Baldwin /**
676f2e73768SJohn Baldwin  * CapsuleCmd
677f2e73768SJohn Baldwin  *
678878d102aSJohn Baldwin  * common.pdu_type == NVME_TCP_PDU_TYPE_CAPSULE_CMD
679f2e73768SJohn Baldwin  */
680878d102aSJohn Baldwin struct nvme_tcp_cmd {
681878d102aSJohn Baldwin 	struct nvme_tcp_common_pdu_hdr	common;
682878d102aSJohn Baldwin 	struct nvme_command		ccsqe;
683f2e73768SJohn Baldwin 	/**< icdoff hdgst padding + in-capsule data + ddgst (if enabled) */
684f2e73768SJohn Baldwin };
685878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_cmd) == 72, "Incorrect size");
686878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_cmd, ccsqe) == 8, "Incorrect offset");
687f2e73768SJohn Baldwin 
688f2e73768SJohn Baldwin /**
689f2e73768SJohn Baldwin  * CapsuleResp
690f2e73768SJohn Baldwin  *
691878d102aSJohn Baldwin  * common.pdu_type == NVME_TCP_PDU_TYPE_CAPSULE_RESP
692f2e73768SJohn Baldwin  */
693878d102aSJohn Baldwin struct nvme_tcp_rsp {
694878d102aSJohn Baldwin 	struct nvme_tcp_common_pdu_hdr	common;
695878d102aSJohn Baldwin 	struct nvme_completion		rccqe;
696f2e73768SJohn Baldwin };
697878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_rsp) == 24, "incorrect size");
698878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_rsp, rccqe) == 8, "Incorrect offset");
699f2e73768SJohn Baldwin 
700f2e73768SJohn Baldwin 
701f2e73768SJohn Baldwin /**
702f2e73768SJohn Baldwin  * H2CData
703f2e73768SJohn Baldwin  *
704878d102aSJohn Baldwin  * hdr.pdu_type == NVME_TCP_PDU_TYPE_H2C_DATA
705f2e73768SJohn Baldwin  */
706878d102aSJohn Baldwin struct nvme_tcp_h2c_data_hdr {
707878d102aSJohn Baldwin 	struct nvme_tcp_common_pdu_hdr	common;
708f2e73768SJohn Baldwin 	uint16_t				cccid;
709f2e73768SJohn Baldwin 	uint16_t				ttag;
710f2e73768SJohn Baldwin 	uint32_t				datao;
711f2e73768SJohn Baldwin 	uint32_t				datal;
712f2e73768SJohn Baldwin 	uint8_t					reserved20[4];
713f2e73768SJohn Baldwin };
714878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_h2c_data_hdr) == 24, "Incorrect size");
715878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, cccid) == 8, "Incorrect offset");
716878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, ttag) == 10, "Incorrect offset");
717878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, datao) == 12, "Incorrect offset");
718878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, datal) == 16, "Incorrect offset");
719f2e73768SJohn Baldwin 
720878d102aSJohn Baldwin #define NVME_TCP_H2C_DATA_FLAGS_LAST_PDU	(1u << 2)
721878d102aSJohn Baldwin #define NVME_TCP_H2C_DATA_FLAGS_SUCCESS		(1u << 3)
722878d102aSJohn Baldwin #define NVME_TCP_H2C_DATA_PDO_MULT		8u
723f2e73768SJohn Baldwin 
724f2e73768SJohn Baldwin /**
725f2e73768SJohn Baldwin  * C2HData
726f2e73768SJohn Baldwin  *
727878d102aSJohn Baldwin  * hdr.pdu_type == NVME_TCP_PDU_TYPE_C2H_DATA
728f2e73768SJohn Baldwin  */
729878d102aSJohn Baldwin struct nvme_tcp_c2h_data_hdr {
730878d102aSJohn Baldwin 	struct nvme_tcp_common_pdu_hdr	common;
731f2e73768SJohn Baldwin 	uint16_t				cccid;
732f2e73768SJohn Baldwin 	uint8_t					reserved10[2];
733f2e73768SJohn Baldwin 	uint32_t				datao;
734f2e73768SJohn Baldwin 	uint32_t				datal;
735f2e73768SJohn Baldwin 	uint8_t					reserved20[4];
736f2e73768SJohn Baldwin };
737878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_c2h_data_hdr) == 24, "Incorrect size");
738878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, cccid) == 8, "Incorrect offset");
739878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, datao) == 12, "Incorrect offset");
740878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, datal) == 16, "Incorrect offset");
741f2e73768SJohn Baldwin 
742878d102aSJohn Baldwin #define NVME_TCP_C2H_DATA_FLAGS_SUCCESS		(1u << 3)
743878d102aSJohn Baldwin #define NVME_TCP_C2H_DATA_FLAGS_LAST_PDU	(1u << 2)
744878d102aSJohn Baldwin #define NVME_TCP_C2H_DATA_PDO_MULT		8u
745f2e73768SJohn Baldwin 
746f2e73768SJohn Baldwin /**
747f2e73768SJohn Baldwin  * R2T
748f2e73768SJohn Baldwin  *
749878d102aSJohn Baldwin  * common.pdu_type == NVME_TCP_PDU_TYPE_R2T
750f2e73768SJohn Baldwin  */
751878d102aSJohn Baldwin struct nvme_tcp_r2t_hdr {
752878d102aSJohn Baldwin 	struct nvme_tcp_common_pdu_hdr	common;
753f2e73768SJohn Baldwin 	uint16_t				cccid;
754f2e73768SJohn Baldwin 	uint16_t				ttag;
755f2e73768SJohn Baldwin 	uint32_t				r2to;
756f2e73768SJohn Baldwin 	uint32_t				r2tl;
757f2e73768SJohn Baldwin 	uint8_t					reserved20[4];
758f2e73768SJohn Baldwin };
759878d102aSJohn Baldwin _Static_assert(sizeof(struct nvme_tcp_r2t_hdr) == 24, "Incorrect size");
760878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_r2t_hdr, cccid) == 8, "Incorrect offset");
761878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_r2t_hdr, ttag) == 10, "Incorrect offset");
762878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_r2t_hdr, r2to) == 12, "Incorrect offset");
763878d102aSJohn Baldwin _Static_assert(offsetof(struct nvme_tcp_r2t_hdr, r2tl) == 16, "Incorrect offset");
764f2e73768SJohn Baldwin 
765878d102aSJohn Baldwin #endif /* __NVMF_PROTO_H__ */
766