xref: /spdk/include/spdk/nvmf_spec.h (revision da6841e4509a8eec7972dfe154ea9f13d09d9be1)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2016 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #ifndef SPDK_NVMF_SPEC_H
7 #define SPDK_NVMF_SPEC_H
8 
9 #include "spdk/stdinc.h"
10 
11 #include "spdk/assert.h"
12 #include "spdk/nvme_spec.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 /**
19  * \file
20  * NVMe over Fabrics specification definitions
21  */
22 
23 #pragma pack(push, 1)
24 
25 struct spdk_nvmf_capsule_cmd {
26 	uint8_t		opcode;
27 	uint8_t		reserved1;
28 	uint16_t	cid;
29 	uint8_t		fctype;
30 	uint8_t		reserved2[35];
31 	uint8_t		fabric_specific[24];
32 };
33 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_capsule_cmd) == 64, "Incorrect size");
34 
35 /* Fabric Command Set */
36 #define SPDK_NVME_OPC_FABRIC 0x7f
37 
38 enum spdk_nvmf_fabric_cmd_types {
39 	SPDK_NVMF_FABRIC_COMMAND_PROPERTY_SET			= 0x00,
40 	SPDK_NVMF_FABRIC_COMMAND_CONNECT			= 0x01,
41 	SPDK_NVMF_FABRIC_COMMAND_PROPERTY_GET			= 0x04,
42 	SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND		= 0x05,
43 	SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV		= 0x06,
44 	SPDK_NVMF_FABRIC_COMMAND_START_VENDOR_SPECIFIC		= 0xC0,
45 };
46 
47 enum spdk_nvmf_fabric_cmd_status_code {
48 	SPDK_NVMF_FABRIC_SC_INCOMPATIBLE_FORMAT		= 0x80,
49 	SPDK_NVMF_FABRIC_SC_CONTROLLER_BUSY		= 0x81,
50 	SPDK_NVMF_FABRIC_SC_INVALID_PARAM		= 0x82,
51 	SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY		= 0x83,
52 	SPDK_NVMF_FABRIC_SC_INVALID_HOST		= 0x84,
53 	SPDK_NVMF_FABRIC_SC_LOG_RESTART_DISCOVERY	= 0x90,
54 	SPDK_NVMF_FABRIC_SC_AUTH_REQUIRED		= 0x91,
55 };
56 
57 /**
58  * RDMA Queue Pair service types
59  */
60 enum spdk_nvmf_rdma_qptype {
61 	/** Reliable connected */
62 	SPDK_NVMF_RDMA_QPTYPE_RELIABLE_CONNECTED	= 0x1,
63 
64 	/** Reliable datagram */
65 	SPDK_NVMF_RDMA_QPTYPE_RELIABLE_DATAGRAM		= 0x2,
66 };
67 
68 /**
69  * RDMA provider types
70  */
71 enum spdk_nvmf_rdma_prtype {
72 	/** No provider specified */
73 	SPDK_NVMF_RDMA_PRTYPE_NONE	= 0x1,
74 
75 	/** InfiniBand */
76 	SPDK_NVMF_RDMA_PRTYPE_IB	= 0x2,
77 
78 	/** RoCE v1 */
79 	SPDK_NVMF_RDMA_PRTYPE_ROCE	= 0x3,
80 
81 	/** RoCE v2 */
82 	SPDK_NVMF_RDMA_PRTYPE_ROCE2	= 0x4,
83 
84 	/** iWARP */
85 	SPDK_NVMF_RDMA_PRTYPE_IWARP	= 0x5,
86 };
87 
88 /**
89  * RDMA connection management service types
90  */
91 enum spdk_nvmf_rdma_cms {
92 	/** Sockets based endpoint addressing */
93 	SPDK_NVMF_RDMA_CMS_RDMA_CM	= 0x1,
94 };
95 
96 /**
97  * NVMe over Fabrics transport types
98  */
99 enum spdk_nvmf_trtype {
100 	/** RDMA */
101 	SPDK_NVMF_TRTYPE_RDMA		= 0x1,
102 
103 	/** Fibre Channel */
104 	SPDK_NVMF_TRTYPE_FC		= 0x2,
105 
106 	/** TCP */
107 	SPDK_NVMF_TRTYPE_TCP		= 0x3,
108 
109 	/** Intra-host transport (loopback) */
110 	SPDK_NVMF_TRTYPE_INTRA_HOST	= 0xfe,
111 };
112 
113 /**
114  * Address family types
115  */
116 enum spdk_nvmf_adrfam {
117 	/** IPv4 (AF_INET) */
118 	SPDK_NVMF_ADRFAM_IPV4		= 0x1,
119 
120 	/** IPv6 (AF_INET6) */
121 	SPDK_NVMF_ADRFAM_IPV6		= 0x2,
122 
123 	/** InfiniBand (AF_IB) */
124 	SPDK_NVMF_ADRFAM_IB		= 0x3,
125 
126 	/** Fibre Channel address family */
127 	SPDK_NVMF_ADRFAM_FC		= 0x4,
128 
129 	/** Intra-host transport (loopback) */
130 	SPDK_NVMF_ADRFAM_INTRA_HOST	= 0xfe,
131 };
132 
133 /**
134  * NVM subsystem types
135  */
136 enum spdk_nvmf_subtype {
137 	/** Referral to a discovery service */
138 	SPDK_NVMF_SUBTYPE_DISCOVERY		= 0x1,
139 
140 	/** NVM Subsystem */
141 	SPDK_NVMF_SUBTYPE_NVME			= 0x2,
142 
143 	/** Current Discovery Subsystem */
144 	SPDK_NVMF_SUBTYPE_DISCOVERY_CURRENT	= 0x3
145 };
146 
147 /* Discovery Log Entry Flags - Duplicate Returned Information */
148 #define SPDK_NVMF_DISCOVERY_LOG_EFLAGS_DUPRETINFO (1u << 0u)
149 
150 /* Discovery Log Entry Flags - Explicit Persistent Connection Support for Discovery */
151 #define SPDK_NVMF_DISCOVERY_LOG_EFLAGS_EPCSD (1u << 1u)
152 
153 /**
154  * Connections shall be made over a fabric secure channel
155  */
156 enum spdk_nvmf_treq_secure_channel {
157 	/** Not specified */
158 	SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_SPECIFIED	= 0x0,
159 
160 	/** Required */
161 	SPDK_NVMF_TREQ_SECURE_CHANNEL_REQUIRED		= 0x1,
162 
163 	/** Not required */
164 	SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED	= 0x2,
165 };
166 
167 struct spdk_nvmf_fabric_auth_recv_cmd {
168 	uint8_t		opcode;
169 	uint8_t		reserved1;
170 	uint16_t	cid;
171 	uint8_t		fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV (0x06) */
172 	uint8_t		reserved2[19];
173 	struct spdk_nvme_sgl_descriptor sgl1;
174 	uint8_t		reserved3;
175 	uint8_t		spsp0;
176 	uint8_t		spsp1;
177 	uint8_t		secp;
178 	uint32_t	al;
179 	uint8_t		reserved4[16];
180 };
181 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_auth_recv_cmd) == 64, "Incorrect size");
182 
183 struct spdk_nvmf_fabric_auth_send_cmd {
184 	uint8_t		opcode;
185 	uint8_t		reserved1;
186 	uint16_t	cid;
187 	uint8_t		fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND (0x05) */
188 	uint8_t		reserved2[19];
189 	struct spdk_nvme_sgl_descriptor sgl1;
190 	uint8_t		reserved3;
191 	uint8_t		spsp0;
192 	uint8_t		spsp1;
193 	uint8_t		secp;
194 	uint32_t	tl;
195 	uint8_t		reserved4[16];
196 };
197 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_auth_send_cmd) == 64, "Incorrect size");
198 
199 struct spdk_nvmf_fabric_connect_data {
200 	uint8_t		hostid[16];
201 	uint16_t	cntlid;
202 	uint8_t		reserved5[238];
203 	uint8_t		subnqn[SPDK_NVME_NQN_FIELD_SIZE];
204 	uint8_t		hostnqn[SPDK_NVME_NQN_FIELD_SIZE];
205 	uint8_t		reserved6[256];
206 };
207 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_connect_data) == 1024, "Incorrect size");
208 
209 struct spdk_nvmf_fabric_connect_cmd {
210 	uint8_t		opcode;
211 	uint8_t		reserved1;
212 	uint16_t	cid;
213 	uint8_t		fctype;
214 	uint8_t		reserved2[19];
215 	struct spdk_nvme_sgl_descriptor sgl1;
216 	uint16_t	recfmt; /* Connect Record Format */
217 	uint16_t	qid; /* Queue Identifier */
218 	uint16_t	sqsize; /* Submission Queue Size */
219 	uint8_t		cattr; /* queue attributes */
220 	uint8_t		reserved3;
221 	uint32_t	kato; /* keep alive timeout */
222 	uint8_t		reserved4[12];
223 };
224 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_connect_cmd) == 64, "Incorrect size");
225 
226 struct spdk_nvmf_fabric_connect_rsp {
227 	union {
228 		struct {
229 			uint16_t cntlid;
230 			struct {
231 				uint16_t reserved1	: 1;
232 				uint16_t atr		: 1;
233 				uint16_t ascr		: 1;
234 				uint16_t reserved2	: 13;
235 			} authreq;
236 		} success;
237 
238 		struct {
239 			uint16_t	ipo;
240 			uint8_t		iattr;
241 			uint8_t		reserved;
242 		} invalid;
243 
244 		uint32_t raw;
245 	} status_code_specific;
246 
247 	uint32_t	reserved0;
248 	uint16_t	sqhd;
249 	uint16_t	reserved1;
250 	uint16_t	cid;
251 	struct spdk_nvme_status status;
252 };
253 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_connect_rsp) == 16, "Incorrect size");
254 
255 #define SPDK_NVMF_PROP_SIZE_4	0
256 #define SPDK_NVMF_PROP_SIZE_8	1
257 
258 struct spdk_nvmf_fabric_prop_get_cmd {
259 	uint8_t		opcode;
260 	uint8_t		reserved1;
261 	uint16_t	cid;
262 	uint8_t		fctype;
263 	uint8_t		reserved2[35];
264 	struct {
265 		uint8_t size		: 3;
266 		uint8_t reserved	: 5;
267 	} attrib;
268 	uint8_t		reserved3[3];
269 	uint32_t	ofst;
270 	uint8_t		reserved4[16];
271 };
272 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_prop_get_cmd) == 64, "Incorrect size");
273 
274 struct spdk_nvmf_fabric_prop_get_rsp {
275 	union {
276 		uint64_t u64;
277 		struct {
278 			uint32_t low;
279 			uint32_t high;
280 		} u32;
281 	} value;
282 
283 	uint16_t	sqhd;
284 	uint16_t	reserved0;
285 	uint16_t	cid;
286 	struct spdk_nvme_status status;
287 };
288 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_prop_get_rsp) == 16, "Incorrect size");
289 
290 struct spdk_nvmf_fabric_prop_set_cmd {
291 	uint8_t		opcode;
292 	uint8_t		reserved0;
293 	uint16_t	cid;
294 	uint8_t		fctype;
295 	uint8_t		reserved1[35];
296 	struct {
297 		uint8_t size		: 3;
298 		uint8_t reserved	: 5;
299 	} attrib;
300 	uint8_t		reserved2[3];
301 	uint32_t	ofst;
302 
303 	union {
304 		uint64_t u64;
305 		struct {
306 			uint32_t low;
307 			uint32_t high;
308 		} u32;
309 	} value;
310 
311 	uint8_t		reserved4[8];
312 };
313 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_prop_set_cmd) == 64, "Incorrect size");
314 
315 #define SPDK_NVMF_NQN_MIN_LEN 11 /* The prefix in the spec is 11 characters */
316 #define SPDK_NVMF_NQN_MAX_LEN 223
317 #define SPDK_NVMF_NQN_UUID_PRE_LEN 32
318 #define SPDK_NVMF_UUID_STRING_LEN 36
319 #define SPDK_NVMF_NQN_UUID_PRE "nqn.2014-08.org.nvmexpress:uuid:"
320 #define SPDK_NVMF_DISCOVERY_NQN "nqn.2014-08.org.nvmexpress.discovery"
321 
322 #define SPDK_DOMAIN_LABEL_MAX_LEN 63 /* RFC 1034 max domain label length */
323 
324 #define SPDK_NVMF_TRSTRING_MAX_LEN 32
325 #define SPDK_NVMF_TRADDR_MAX_LEN 256
326 #define SPDK_NVMF_TRSVCID_MAX_LEN 32
327 
328 /** RDMA transport-specific address subtype */
329 struct spdk_nvmf_rdma_transport_specific_address_subtype {
330 	/** RDMA QP service type (\ref spdk_nvmf_rdma_qptype) */
331 	uint8_t		rdma_qptype;
332 
333 	/** RDMA provider type (\ref spdk_nvmf_rdma_prtype) */
334 	uint8_t		rdma_prtype;
335 
336 	/** RDMA connection management service (\ref spdk_nvmf_rdma_cms) */
337 	uint8_t		rdma_cms;
338 
339 	uint8_t		reserved0[5];
340 
341 	/** RDMA partition key for AF_IB */
342 	uint16_t	rdma_pkey;
343 
344 	uint8_t		reserved2[246];
345 };
346 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_rdma_transport_specific_address_subtype) == 256,
347 		   "Incorrect size");
348 
349 /** TCP Secure Socket Type */
350 enum spdk_nvme_tcp_secure_socket_type {
351 	/** No security */
352 	SPDK_NVME_TCP_SECURITY_NONE			= 0,
353 
354 	/** TLS (Secure Sockets) version 1.2 */
355 	SPDK_NVME_TCP_SECURITY_TLS_1_2			= 1,
356 
357 	/** TLS (Secure Sockets) version 1.3 */
358 	SPDK_NVME_TCP_SECURITY_TLS_1_3			= 2,
359 };
360 
361 /** TCP transport-specific address subtype */
362 struct spdk_nvme_tcp_transport_specific_address_subtype {
363 	/** Security type (\ref spdk_nvme_tcp_secure_socket_type) */
364 	uint8_t		sectype;
365 
366 	uint8_t		reserved0[255];
367 };
368 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_transport_specific_address_subtype) == 256,
369 		   "Incorrect size");
370 
371 /** Transport-specific address subtype */
372 union spdk_nvmf_transport_specific_address_subtype {
373 	uint8_t raw[256];
374 
375 	/** RDMA */
376 	struct spdk_nvmf_rdma_transport_specific_address_subtype rdma;
377 
378 	/** TCP */
379 	struct spdk_nvme_tcp_transport_specific_address_subtype tcp;
380 };
381 SPDK_STATIC_ASSERT(sizeof(union spdk_nvmf_transport_specific_address_subtype) == 256,
382 		   "Incorrect size");
383 
384 #define SPDK_NVMF_MIN_ADMIN_MAX_SQ_SIZE 32
385 
386 /**
387  * Discovery Log Page entry
388  */
389 struct spdk_nvmf_discovery_log_page_entry {
390 	/** Transport type (\ref spdk_nvmf_trtype) */
391 	uint8_t		trtype;
392 
393 	/** Address family (\ref spdk_nvmf_adrfam) */
394 	uint8_t		adrfam;
395 
396 	/** Subsystem type (\ref spdk_nvmf_subtype) */
397 	uint8_t		subtype;
398 
399 	/** Transport requirements */
400 	struct {
401 		/** Secure channel requirements (\ref spdk_nvmf_treq_secure_channel) */
402 		uint8_t secure_channel : 2;
403 
404 		uint8_t reserved : 6;
405 	} treq;
406 
407 	/** NVM subsystem port ID */
408 	uint16_t	portid;
409 
410 	/** Controller ID */
411 	uint16_t	cntlid;
412 
413 	/** Admin max SQ size */
414 	uint16_t	asqsz;
415 
416 	/** Entry Flags */
417 	uint16_t	eflags;
418 
419 	uint8_t		reserved0[20];
420 
421 	/** Transport service identifier */
422 	uint8_t		trsvcid[SPDK_NVMF_TRSVCID_MAX_LEN];
423 
424 	uint8_t		reserved1[192];
425 
426 	/** NVM subsystem qualified name */
427 	uint8_t		subnqn[256];
428 
429 	/** Transport address */
430 	uint8_t		traddr[SPDK_NVMF_TRADDR_MAX_LEN];
431 
432 	/** Transport-specific address subtype */
433 	union spdk_nvmf_transport_specific_address_subtype tsas;
434 };
435 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_discovery_log_page_entry) == 1024, "Incorrect size");
436 
437 struct spdk_nvmf_discovery_log_page {
438 	uint64_t	genctr;
439 	uint64_t	numrec;
440 	uint16_t	recfmt;
441 	uint8_t		reserved0[1006];
442 	struct spdk_nvmf_discovery_log_page_entry entries[0];
443 };
444 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_discovery_log_page) == 1024, "Incorrect size");
445 
446 /** Security protocol identifier assigned to NVMe */
447 #define SPDK_NVMF_AUTH_SECP_NVME 0xe9
448 
449 /** Authentication types */
450 enum spdk_nvmf_auth_type {
451 	SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE	= 0x0,
452 	SPDK_NVMF_AUTH_TYPE_DHCHAP		= 0x1,
453 };
454 
455 /** AUTH message identifiers */
456 enum spdk_nvmf_auth_id {
457 	SPDK_NVMF_AUTH_ID_NEGOTIATE		= 0x00,
458 	SPDK_NVMF_AUTH_ID_DHCHAP_CHALLENGE	= 0x01,
459 	SPDK_NVMF_AUTH_ID_DHCHAP_REPLY		= 0x02,
460 	SPDK_NVMF_AUTH_ID_DHCHAP_SUCCESS1	= 0x03,
461 	SPDK_NVMF_AUTH_ID_DHCHAP_SUCCESS2	= 0x04,
462 	SPDK_NVMF_AUTH_ID_FAILURE2		= 0xf0,
463 	SPDK_NVMF_AUTH_ID_FAILURE1		= 0xf1,
464 };
465 
466 /** Hash function identifiers */
467 enum spdk_nvmf_dhchap_hash {
468 	SPDK_NVMF_DHCHAP_HASH_NONE	= 0x0,
469 	SPDK_NVMF_DHCHAP_HASH_SHA256	= 0x1,
470 	SPDK_NVMF_DHCHAP_HASH_SHA384	= 0x2,
471 	SPDK_NVMF_DHCHAP_HASH_SHA512	= 0x3,
472 };
473 
474 /** Diffie-Hellman group identifiers */
475 enum spdk_nvmf_dhchap_dhgroup {
476 	SPDK_NVMF_DHCHAP_DHGROUP_NULL = 0x0,
477 	SPDK_NVMF_DHCHAP_DHGROUP_2048 = 0x1,
478 	SPDK_NVMF_DHCHAP_DHGROUP_3072 = 0x2,
479 	SPDK_NVMF_DHCHAP_DHGROUP_4096 = 0x3,
480 	SPDK_NVMF_DHCHAP_DHGROUP_6144 = 0x4,
481 	SPDK_NVMF_DHCHAP_DHGROUP_8192 = 0x5,
482 };
483 
484 struct spdk_nvmf_auth_descriptor {
485 	uint8_t		auth_id;
486 	uint8_t		reserved0;
487 	uint8_t		halen;
488 	uint8_t		dhlen;
489 	uint8_t		hash_id_list[30];
490 	uint8_t		dhg_id_list[30];
491 };
492 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_auth_descriptor) == 64, "Incorrect size");
493 
494 /** Secure channel concatenation */
495 enum spdk_nvmf_auth_scc {
496 	/** No secure channel concatenation */
497 	SPDK_NVMF_AUTH_SCC_DISABLED	= 0,
498 	/** Secure channel concatenation with TLS (TCP) */
499 	SPDK_NVMF_AUTH_SCC_TLS		= 1,
500 };
501 
502 struct spdk_nvmf_auth_negotiate {
503 	uint8_t					auth_type;
504 	uint8_t					auth_id;
505 	uint8_t					reserved0[2];
506 	uint16_t				t_id;
507 	uint8_t					sc_c;
508 	uint8_t					napd;
509 	struct spdk_nvmf_auth_descriptor	descriptors[0];
510 };
511 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_auth_negotiate) == 8, "Incorrect size");
512 
513 struct spdk_nvmf_dhchap_challenge {
514 	uint8_t		auth_type;
515 	uint8_t		auth_id;
516 	uint8_t		reserved0[2];
517 	uint16_t	t_id;
518 	uint8_t		hl;
519 	uint8_t		reserved1;
520 	uint8_t		hash_id;
521 	uint8_t		dhg_id;
522 	uint16_t	dhvlen;
523 	uint32_t	seqnum;
524 	uint8_t		cval[0];
525 	/* Followed by optional dhv if dhvlen > 0 */
526 };
527 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_dhchap_challenge) == 16, "Incorrect size");
528 
529 struct spdk_nvmf_dhchap_reply {
530 	uint8_t		auth_type;
531 	uint8_t		auth_id;
532 	uint8_t		reserved0[2];
533 	uint16_t	t_id;
534 	uint8_t		hl;
535 	uint8_t		reserved1;
536 	uint8_t		cvalid;
537 	uint8_t		reserved2;
538 	uint16_t	dhvlen;
539 	uint32_t	seqnum;
540 	uint8_t		rval[0];
541 	/* Followed by cval[hl] and dhv[dhvlen] */
542 };
543 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_dhchap_reply) == 16, "Incorrect size");
544 
545 struct spdk_nvmf_dhchap_success1 {
546 	uint8_t		auth_type;
547 	uint8_t		auth_id;
548 	uint8_t		reserved0[2];
549 	uint16_t	t_id;
550 	uint8_t		hl;
551 	uint8_t		reserved1;
552 	uint8_t		rvalid;
553 	uint8_t		reserved2[7];
554 	uint8_t		rval[0];
555 };
556 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_dhchap_success1) == 16, "Incorrect size");
557 
558 struct spdk_nvmf_dhchap_success2 {
559 	uint8_t		auth_type;
560 	uint8_t		auth_id;
561 	uint8_t		reserved0[2];
562 	uint16_t	t_id;
563 	uint8_t		reserved1[10];
564 };
565 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_dhchap_success2) == 16, "Incorrect size");
566 
567 /** AUTH_Failure reason codes */
568 #define SPDK_NVMF_AUTH_FAILURE 1
569 
570 /** AUTH_Failure reason code explanations */
571 enum spdk_nvmf_auth_failure_reason {
572 	SPDK_NVMF_AUTH_FAILED				= 0x1,
573 	SPDK_NVMF_AUTH_PROTOCOL_UNUSABLE		= 0x2,
574 	SPDK_NVMF_AUTH_SCC_MISMATCH			= 0x3,
575 	SPDK_NVMF_AUTH_HASH_UNUSABLE			= 0x4,
576 	SPDK_NVMF_AUTH_DHGROUP_UNUSABLE			= 0x5,
577 	SPDK_NVMF_AUTH_INCORRECT_PAYLOAD		= 0x6,
578 	SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE	= 0x7,
579 };
580 
581 struct spdk_nvmf_auth_failure {
582 	uint8_t		auth_type;
583 	uint8_t		auth_id;
584 	uint8_t		reserved0[2];
585 	uint16_t	t_id;
586 	uint8_t		rc;
587 	uint8_t		rce;
588 };
589 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_auth_failure) == 8, "Incorrect size");
590 
591 /* RDMA Fabric specific definitions below */
592 
593 #define SPDK_NVME_SGL_SUBTYPE_INVALIDATE_KEY	0xF
594 
595 struct spdk_nvmf_rdma_request_private_data {
596 	uint16_t	recfmt; /* record format */
597 	uint16_t	qid;	/* queue id */
598 	uint16_t	hrqsize;	/* host receive queue size */
599 	uint16_t	hsqsize;	/* host send queue size */
600 	uint16_t	cntlid;		/* controller id */
601 	uint8_t		reserved[22];
602 };
603 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_rdma_request_private_data) == 32, "Incorrect size");
604 
605 struct spdk_nvmf_rdma_accept_private_data {
606 	uint16_t	recfmt; /* record format */
607 	uint16_t	crqsize;	/* controller receive queue size */
608 	uint8_t		reserved[28];
609 };
610 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_rdma_accept_private_data) == 32, "Incorrect size");
611 
612 struct spdk_nvmf_rdma_reject_private_data {
613 	uint16_t	recfmt; /* record format */
614 	uint16_t	sts; /* status */
615 };
616 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_rdma_reject_private_data) == 4, "Incorrect size");
617 
618 union spdk_nvmf_rdma_private_data {
619 	struct spdk_nvmf_rdma_request_private_data	pd_request;
620 	struct spdk_nvmf_rdma_accept_private_data	pd_accept;
621 	struct spdk_nvmf_rdma_reject_private_data	pd_reject;
622 };
623 SPDK_STATIC_ASSERT(sizeof(union spdk_nvmf_rdma_private_data) == 32, "Incorrect size");
624 
625 enum spdk_nvmf_rdma_transport_error {
626 	SPDK_NVMF_RDMA_ERROR_INVALID_PRIVATE_DATA_LENGTH	= 0x1,
627 	SPDK_NVMF_RDMA_ERROR_INVALID_RECFMT			= 0x2,
628 	SPDK_NVMF_RDMA_ERROR_INVALID_QID			= 0x3,
629 	SPDK_NVMF_RDMA_ERROR_INVALID_HSQSIZE			= 0x4,
630 	SPDK_NVMF_RDMA_ERROR_INVALID_HRQSIZE			= 0x5,
631 	SPDK_NVMF_RDMA_ERROR_NO_RESOURCES			= 0x6,
632 	SPDK_NVMF_RDMA_ERROR_INVALID_IRD			= 0x7,
633 	SPDK_NVMF_RDMA_ERROR_INVALID_ORD			= 0x8,
634 };
635 
636 /* TCP transport specific definitions below */
637 
638 /** NVMe/TCP PDU type */
639 enum spdk_nvme_tcp_pdu_type {
640 	/** Initialize Connection Request (ICReq) */
641 	SPDK_NVME_TCP_PDU_TYPE_IC_REQ			= 0x00,
642 
643 	/** Initialize Connection Response (ICResp) */
644 	SPDK_NVME_TCP_PDU_TYPE_IC_RESP			= 0x01,
645 
646 	/** Terminate Connection Request (TermReq) */
647 	SPDK_NVME_TCP_PDU_TYPE_H2C_TERM_REQ		= 0x02,
648 
649 	/** Terminate Connection Response (TermResp) */
650 	SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ		= 0x03,
651 
652 	/** Command Capsule (CapsuleCmd) */
653 	SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD		= 0x04,
654 
655 	/** Response Capsule (CapsuleRsp) */
656 	SPDK_NVME_TCP_PDU_TYPE_CAPSULE_RESP		= 0x05,
657 
658 	/** Host To Controller Data (H2CData) */
659 	SPDK_NVME_TCP_PDU_TYPE_H2C_DATA			= 0x06,
660 
661 	/** Controller To Host Data (C2HData) */
662 	SPDK_NVME_TCP_PDU_TYPE_C2H_DATA			= 0x07,
663 
664 	/** Ready to Transfer (R2T) */
665 	SPDK_NVME_TCP_PDU_TYPE_R2T			= 0x09,
666 };
667 
668 /** Common NVMe/TCP PDU header */
669 struct spdk_nvme_tcp_common_pdu_hdr {
670 	/** PDU type (\ref spdk_nvme_tcp_pdu_type) */
671 	uint8_t				pdu_type;
672 
673 	/** pdu_type-specific flags */
674 	uint8_t				flags;
675 
676 	/** Length of PDU header (not including the Header Digest) */
677 	uint8_t				hlen;
678 
679 	/** PDU Data Offset from the start of the PDU */
680 	uint8_t				pdo;
681 
682 	/** Total number of bytes in PDU, including pdu_hdr */
683 	uint32_t			plen;
684 };
685 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_common_pdu_hdr) == 8, "Incorrect size");
686 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, pdu_type) == 0,
687 		   "Incorrect offset");
688 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, flags) == 1, "Incorrect offset");
689 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, hlen) == 2, "Incorrect offset");
690 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, pdo) == 3, "Incorrect offset");
691 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, plen) == 4, "Incorrect offset");
692 
693 #define SPDK_NVME_TCP_CH_FLAGS_HDGSTF		(1u << 0)
694 #define SPDK_NVME_TCP_CH_FLAGS_DDGSTF		(1u << 1)
695 
696 /**
697  * ICReq
698  *
699  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_IC_REQ
700  */
701 struct spdk_nvme_tcp_ic_req {
702 	struct spdk_nvme_tcp_common_pdu_hdr	common;
703 	uint16_t				pfv;
704 	/** Specifies the data alignment for all PDUs transferred from the controller to the host that contain data */
705 	uint8_t					hpda;
706 	union {
707 		uint8_t				raw;
708 		struct {
709 			uint8_t			hdgst_enable : 1;
710 			uint8_t			ddgst_enable : 1;
711 			uint8_t			reserved : 6;
712 		} bits;
713 	} dgst;
714 	uint32_t				maxr2t;
715 	uint8_t					reserved16[112];
716 };
717 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_ic_req) == 128, "Incorrect size");
718 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, pfv) == 8, "Incorrect offset");
719 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, hpda) == 10, "Incorrect offset");
720 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, maxr2t) == 12, "Incorrect offset");
721 
722 #define SPDK_NVME_TCP_HPDA_MAX 31
723 #define SPDK_NVME_TCP_CPDA_MAX 31
724 #define SPDK_NVME_TCP_PDU_PDO_MAX_OFFSET     ((SPDK_NVME_TCP_CPDA_MAX + 1) << 2)
725 
726 /**
727  * ICResp
728  *
729  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_IC_RESP
730  */
731 struct spdk_nvme_tcp_ic_resp {
732 	struct spdk_nvme_tcp_common_pdu_hdr	common;
733 	uint16_t				pfv;
734 	/** Specifies the data alignment for all PDUs transferred from the host to the controller that contain data */
735 	uint8_t					cpda;
736 	union {
737 		uint8_t				raw;
738 		struct {
739 			uint8_t			hdgst_enable : 1;
740 			uint8_t			ddgst_enable : 1;
741 			uint8_t			reserved : 6;
742 		} bits;
743 	} dgst;
744 	/** Specifies the maximum number of PDU-Data bytes per H2C Data Transfer PDU */
745 	uint32_t				maxh2cdata;
746 	uint8_t					reserved16[112];
747 };
748 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_ic_resp) == 128, "Incorrect size");
749 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_resp, pfv) == 8, "Incorrect offset");
750 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_resp, cpda) == 10, "Incorrect offset");
751 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_resp, maxh2cdata) == 12, "Incorrect offset");
752 
753 /**
754  * TermReq
755  *
756  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_TERM_REQ
757  */
758 struct spdk_nvme_tcp_term_req_hdr {
759 	struct spdk_nvme_tcp_common_pdu_hdr	common;
760 	uint16_t				fes;
761 	uint8_t					fei[4];
762 	uint8_t					reserved14[10];
763 };
764 
765 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_term_req_hdr) == 24, "Incorrect size");
766 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_term_req_hdr, fes) == 8, "Incorrect offset");
767 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_term_req_hdr, fei) == 10, "Incorrect offset");
768 
769 enum spdk_nvme_tcp_term_req_fes {
770 	SPDK_NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD				= 0x01,
771 	SPDK_NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR				= 0x02,
772 	SPDK_NVME_TCP_TERM_REQ_FES_HDGST_ERROR					= 0x03,
773 	SPDK_NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE			= 0x04,
774 	SPDK_NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_LIMIT_EXCEEDED			= 0x05,
775 	SPDK_NVME_TCP_TERM_REQ_FES_R2T_LIMIT_EXCEEDED				= 0x05,
776 	SPDK_NVME_TCP_TERM_REQ_FES_INVALID_DATA_UNSUPPORTED_PARAMETER		= 0x06,
777 };
778 
779 /* Total length of term req PDU (including PDU header and DATA) in bytes shall not exceed a limit of 152 bytes. */
780 #define SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE	128
781 #define SPDK_NVME_TCP_TERM_REQ_PDU_MAX_SIZE		(SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE + sizeof(struct spdk_nvme_tcp_term_req_hdr))
782 
783 /**
784  * CapsuleCmd
785  *
786  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD
787  */
788 struct spdk_nvme_tcp_cmd {
789 	struct spdk_nvme_tcp_common_pdu_hdr	common;
790 	struct spdk_nvme_cmd			ccsqe;
791 	/**< icdoff hdgst padding + in-capsule data + ddgst (if enabled) */
792 };
793 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_cmd) == 72, "Incorrect size");
794 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_cmd, ccsqe) == 8, "Incorrect offset");
795 
796 /**
797  * CapsuleResp
798  *
799  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_CAPSULE_RESP
800  */
801 struct spdk_nvme_tcp_rsp {
802 	struct spdk_nvme_tcp_common_pdu_hdr	common;
803 	struct spdk_nvme_cpl			rccqe;
804 };
805 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_rsp) == 24, "incorrect size");
806 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_rsp, rccqe) == 8, "Incorrect offset");
807 
808 
809 /**
810  * H2CData
811  *
812  * hdr.pdu_type == SPDK_NVME_TCP_PDU_TYPE_H2C_DATA
813  */
814 struct spdk_nvme_tcp_h2c_data_hdr {
815 	struct spdk_nvme_tcp_common_pdu_hdr	common;
816 	uint16_t				cccid;
817 	uint16_t				ttag;
818 	uint32_t				datao;
819 	uint32_t				datal;
820 	uint8_t					reserved20[4];
821 };
822 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_h2c_data_hdr) == 24, "Incorrect size");
823 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_h2c_data_hdr, cccid) == 8, "Incorrect offset");
824 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_h2c_data_hdr, ttag) == 10, "Incorrect offset");
825 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_h2c_data_hdr, datao) == 12, "Incorrect offset");
826 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_h2c_data_hdr, datal) == 16, "Incorrect offset");
827 
828 #define SPDK_NVME_TCP_H2C_DATA_FLAGS_LAST_PDU	(1u << 2)
829 #define SPDK_NVME_TCP_H2C_DATA_FLAGS_SUCCESS	(1u << 3)
830 #define SPDK_NVME_TCP_H2C_DATA_PDO_MULT		8u
831 
832 /**
833  * C2HData
834  *
835  * hdr.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_DATA
836  */
837 struct spdk_nvme_tcp_c2h_data_hdr {
838 	struct spdk_nvme_tcp_common_pdu_hdr	common;
839 	uint16_t				cccid;
840 	uint8_t					reserved10[2];
841 	uint32_t				datao;
842 	uint32_t				datal;
843 	uint8_t					reserved20[4];
844 };
845 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_c2h_data_hdr) == 24, "Incorrect size");
846 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_c2h_data_hdr, cccid) == 8, "Incorrect offset");
847 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_c2h_data_hdr, datao) == 12, "Incorrect offset");
848 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_c2h_data_hdr, datal) == 16, "Incorrect offset");
849 
850 #define SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS	(1u << 3)
851 #define SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU	(1u << 2)
852 #define SPDK_NVME_TCP_C2H_DATA_PDO_MULT		8u
853 
854 /**
855  * R2T
856  *
857  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_R2T
858  */
859 struct spdk_nvme_tcp_r2t_hdr {
860 	struct spdk_nvme_tcp_common_pdu_hdr	common;
861 	uint16_t				cccid;
862 	uint16_t				ttag;
863 	uint32_t				r2to;
864 	uint32_t				r2tl;
865 	uint8_t					reserved20[4];
866 };
867 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_r2t_hdr) == 24, "Incorrect size");
868 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_r2t_hdr, cccid) == 8, "Incorrect offset");
869 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_r2t_hdr, ttag) == 10, "Incorrect offset");
870 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_r2t_hdr, r2to) == 12, "Incorrect offset");
871 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_r2t_hdr, r2tl) == 16, "Incorrect offset");
872 
873 #pragma pack(pop)
874 
875 #ifdef __cplusplus
876 }
877 #endif
878 
879 #endif /* __NVMF_SPEC_H__ */
880