xref: /spdk/include/spdk/nvmf_spec.h (revision b30d57cdad6d2bc75cc1e4e2ebbcebcb0d98dcfa)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef SPDK_NVMF_SPEC_H
35 #define SPDK_NVMF_SPEC_H
36 
37 #include "spdk/stdinc.h"
38 
39 #include "spdk/assert.h"
40 #include "spdk/nvme_spec.h"
41 
42 /**
43  * \file
44  * NVMe over Fabrics specification definitions
45  */
46 
47 #pragma pack(push, 1)
48 
49 struct spdk_nvmf_capsule_cmd {
50 	uint8_t		opcode;
51 	uint8_t		reserved1;
52 	uint16_t	cid;
53 	uint8_t		fctype;
54 	uint8_t		reserved2[35];
55 	uint8_t		fabric_specific[24];
56 };
57 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_capsule_cmd) == 64, "Incorrect size");
58 
59 /* Fabric Command Set */
60 #define SPDK_NVME_OPC_FABRIC 0x7f
61 
62 enum spdk_nvmf_fabric_cmd_types {
63 	SPDK_NVMF_FABRIC_COMMAND_PROPERTY_SET			= 0x00,
64 	SPDK_NVMF_FABRIC_COMMAND_CONNECT			= 0x01,
65 	SPDK_NVMF_FABRIC_COMMAND_PROPERTY_GET			= 0x04,
66 	SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND		= 0x05,
67 	SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV		= 0x06,
68 	SPDK_NVMF_FABRIC_COMMAND_START_VENDOR_SPECIFIC		= 0xC0,
69 };
70 
71 enum spdk_nvmf_fabric_cmd_status_code {
72 	SPDK_NVMF_FABRIC_SC_INCOMPATIBLE_FORMAT		= 0x80,
73 	SPDK_NVMF_FABRIC_SC_CONTROLLER_BUSY		= 0x81,
74 	SPDK_NVMF_FABRIC_SC_INVALID_PARAM		= 0x82,
75 	SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY		= 0x83,
76 	SPDK_NVMF_FABRIC_SC_INVALID_HOST		= 0x84,
77 	SPDK_NVMF_FABRIC_SC_LOG_RESTART_DISCOVERY	= 0x90,
78 	SPDK_NVMF_FABRIC_SC_AUTH_REQUIRED		= 0x91,
79 };
80 
81 /**
82  * RDMA Queue Pair service types
83  */
84 enum spdk_nvmf_rdma_qptype {
85 	/** Reliable connected */
86 	SPDK_NVMF_RDMA_QPTYPE_RELIABLE_CONNECTED	= 0x1,
87 
88 	/** Reliable datagram */
89 	SPDK_NVMF_RDMA_QPTYPE_RELIABLE_DATAGRAM		= 0x2,
90 };
91 
92 /**
93  * RDMA provider types
94  */
95 enum spdk_nvmf_rdma_prtype {
96 	/** No provider specified */
97 	SPDK_NVMF_RDMA_PRTYPE_NONE	= 0x1,
98 
99 	/** InfiniBand */
100 	SPDK_NVMF_RDMA_PRTYPE_IB	= 0x2,
101 
102 	/** RoCE v1 */
103 	SPDK_NVMF_RDMA_PRTYPE_ROCE	= 0x3,
104 
105 	/** RoCE v2 */
106 	SPDK_NVMF_RDMA_PRTYPE_ROCE2	= 0x4,
107 
108 	/** iWARP */
109 	SPDK_NVMF_RDMA_PRTYPE_IWARP	= 0x5,
110 };
111 
112 /**
113  * RDMA connection management service types
114  */
115 enum spdk_nvmf_rdma_cms {
116 	/** Sockets based endpoint addressing */
117 	SPDK_NVMF_RDMA_CMS_RDMA_CM	= 0x1,
118 };
119 
120 /**
121  * NVMe over Fabrics transport types
122  */
123 enum spdk_nvmf_trtype {
124 	/** RDMA */
125 	SPDK_NVMF_TRTYPE_RDMA		= 0x1,
126 
127 	/** Fibre Channel */
128 	SPDK_NVMF_TRTYPE_FC		= 0x2,
129 
130 	/** TCP */
131 	SPDK_NVMF_TRTYPE_TCP		= 0x3,
132 
133 	/** Intra-host transport (loopback) */
134 	SPDK_NVMF_TRTYPE_INTRA_HOST	= 0xfe,
135 };
136 
137 /**
138  * Address family types
139  */
140 enum spdk_nvmf_adrfam {
141 	/** IPv4 (AF_INET) */
142 	SPDK_NVMF_ADRFAM_IPV4		= 0x1,
143 
144 	/** IPv6 (AF_INET6) */
145 	SPDK_NVMF_ADRFAM_IPV6		= 0x2,
146 
147 	/** InfiniBand (AF_IB) */
148 	SPDK_NVMF_ADRFAM_IB		= 0x3,
149 
150 	/** Fibre Channel address family */
151 	SPDK_NVMF_ADRFAM_FC		= 0x4,
152 
153 	/** Intra-host transport (loopback) */
154 	SPDK_NVMF_ADRFAM_INTRA_HOST	= 0xfe,
155 };
156 
157 /**
158  * NVM subsystem types
159  */
160 enum spdk_nvmf_subtype {
161 	/** Discovery type for NVM subsystem */
162 	SPDK_NVMF_SUBTYPE_DISCOVERY		= 0x1,
163 
164 	/** NVMe type for NVM subsystem */
165 	SPDK_NVMF_SUBTYPE_NVME		= 0x2,
166 };
167 
168 /**
169  * Connections shall be made over a fabric secure channel
170  */
171 enum spdk_nvmf_treq_secure_channel {
172 	/** Not specified */
173 	SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_SPECIFIED	= 0x0,
174 
175 	/** Required */
176 	SPDK_NVMF_TREQ_SECURE_CHANNEL_REQUIRED		= 0x1,
177 
178 	/** Not required */
179 	SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED	= 0x2,
180 };
181 
182 struct spdk_nvmf_fabric_auth_recv_cmd {
183 	uint8_t		opcode;
184 	uint8_t		reserved1;
185 	uint16_t	cid;
186 	uint8_t		fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV (0x06) */
187 	uint8_t		reserved2[19];
188 	struct spdk_nvme_sgl_descriptor sgl1;
189 	uint8_t		reserved3;
190 	uint8_t		spsp0;
191 	uint8_t		spsp1;
192 	uint8_t		secp;
193 	uint32_t	al;
194 	uint8_t		reserved4[16];
195 };
196 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_auth_recv_cmd) == 64, "Incorrect size");
197 
198 struct spdk_nvmf_fabric_auth_send_cmd {
199 	uint8_t		opcode;
200 	uint8_t		reserved1;
201 	uint16_t	cid;
202 	uint8_t		fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND (0x05) */
203 	uint8_t		reserved2[19];
204 	struct spdk_nvme_sgl_descriptor sgl1;
205 	uint8_t		reserved3;
206 	uint8_t		spsp0;
207 	uint8_t		spsp1;
208 	uint8_t		secp;
209 	uint32_t	tl;
210 	uint8_t		reserved4[16];
211 };
212 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_auth_send_cmd) == 64, "Incorrect size");
213 
214 struct spdk_nvmf_fabric_connect_data {
215 	uint8_t		hostid[16];
216 	uint16_t	cntlid;
217 	uint8_t		reserved5[238];
218 	uint8_t		subnqn[SPDK_NVME_NQN_FIELD_SIZE];
219 	uint8_t		hostnqn[SPDK_NVME_NQN_FIELD_SIZE];
220 	uint8_t		reserved6[256];
221 };
222 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_connect_data) == 1024, "Incorrect size");
223 
224 struct spdk_nvmf_fabric_connect_cmd {
225 	uint8_t		opcode;
226 	uint8_t		reserved1;
227 	uint16_t	cid;
228 	uint8_t		fctype;
229 	uint8_t		reserved2[19];
230 	struct spdk_nvme_sgl_descriptor sgl1;
231 	uint16_t	recfmt; /* Connect Record Format */
232 	uint16_t	qid; /* Queue Identifier */
233 	uint16_t	sqsize; /* Submission Queue Size */
234 	uint8_t		cattr; /* queue attributes */
235 	uint8_t		reserved3;
236 	uint32_t	kato; /* keep alive timeout */
237 	uint8_t		reserved4[12];
238 };
239 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_connect_cmd) == 64, "Incorrect size");
240 
241 struct spdk_nvmf_fabric_connect_rsp {
242 	union {
243 		struct {
244 			uint16_t cntlid;
245 			uint16_t authreq;
246 		} success;
247 
248 		struct {
249 			uint16_t	ipo;
250 			uint8_t		iattr;
251 			uint8_t		reserved;
252 		} invalid;
253 
254 		uint32_t raw;
255 	} status_code_specific;
256 
257 	uint32_t	reserved0;
258 	uint16_t	sqhd;
259 	uint16_t	reserved1;
260 	uint16_t	cid;
261 	struct spdk_nvme_status status;
262 };
263 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_connect_rsp) == 16, "Incorrect size");
264 
265 #define SPDK_NVMF_PROP_SIZE_4	0
266 #define SPDK_NVMF_PROP_SIZE_8	1
267 
268 struct spdk_nvmf_fabric_prop_get_cmd {
269 	uint8_t		opcode;
270 	uint8_t		reserved1;
271 	uint16_t	cid;
272 	uint8_t		fctype;
273 	uint8_t		reserved2[35];
274 	struct {
275 		uint8_t size		: 3;
276 		uint8_t reserved	: 5;
277 	} attrib;
278 	uint8_t		reserved3[3];
279 	uint32_t	ofst;
280 	uint8_t		reserved4[16];
281 };
282 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_prop_get_cmd) == 64, "Incorrect size");
283 
284 struct spdk_nvmf_fabric_prop_get_rsp {
285 	union {
286 		uint64_t u64;
287 		struct {
288 			uint32_t low;
289 			uint32_t high;
290 		} u32;
291 	} value;
292 
293 	uint16_t	sqhd;
294 	uint16_t	reserved0;
295 	uint16_t	cid;
296 	struct spdk_nvme_status status;
297 };
298 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_prop_get_rsp) == 16, "Incorrect size");
299 
300 struct spdk_nvmf_fabric_prop_set_cmd {
301 	uint8_t		opcode;
302 	uint8_t		reserved0;
303 	uint16_t	cid;
304 	uint8_t		fctype;
305 	uint8_t		reserved1[35];
306 	struct {
307 		uint8_t size		: 3;
308 		uint8_t reserved	: 5;
309 	} attrib;
310 	uint8_t		reserved2[3];
311 	uint32_t	ofst;
312 
313 	union {
314 		uint64_t u64;
315 		struct {
316 			uint32_t low;
317 			uint32_t high;
318 		} u32;
319 	} value;
320 
321 	uint8_t		reserved4[8];
322 };
323 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_prop_set_cmd) == 64, "Incorrect size");
324 
325 #define SPDK_NVMF_NQN_MIN_LEN 11 /* The prefix in the spec is 11 characters */
326 #define SPDK_NVMF_NQN_MAX_LEN 223
327 #define SPDK_NVMF_NQN_UUID_PRE_LEN 32
328 #define SPDK_NVMF_UUID_STRING_LEN 36
329 #define SPDK_NVMF_NQN_UUID_PRE "nqn.2014-08.org.nvmexpress:uuid:"
330 #define SPDK_NVMF_DISCOVERY_NQN "nqn.2014-08.org.nvmexpress.discovery"
331 
332 #define SPDK_DOMAIN_LABEL_MAX_LEN 63 /* RFC 1034 max domain label length */
333 
334 #define SPDK_NVMF_TRSTRING_MAX_LEN 32
335 #define SPDK_NVMF_TRADDR_MAX_LEN 256
336 #define SPDK_NVMF_TRSVCID_MAX_LEN 32
337 
338 /** RDMA transport-specific address subtype */
339 struct spdk_nvmf_rdma_transport_specific_address_subtype {
340 	/** RDMA QP service type (\ref spdk_nvmf_rdma_qptype) */
341 	uint8_t		rdma_qptype;
342 
343 	/** RDMA provider type (\ref spdk_nvmf_rdma_prtype) */
344 	uint8_t		rdma_prtype;
345 
346 	/** RDMA connection management service (\ref spdk_nvmf_rdma_cms) */
347 	uint8_t		rdma_cms;
348 
349 	uint8_t		reserved0[5];
350 
351 	/** RDMA partition key for AF_IB */
352 	uint16_t	rdma_pkey;
353 
354 	uint8_t		reserved2[246];
355 };
356 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_rdma_transport_specific_address_subtype) == 256,
357 		   "Incorrect size");
358 
359 /** TCP Secure Socket Type */
360 enum spdk_nvme_tcp_secure_socket_type {
361 	/** No security */
362 	SPDK_NVME_TCP_SECURITY_NONE			= 0,
363 
364 	/** TLS (Secure Sockets) */
365 	SPDK_NVME_TCP_SECURITY_TLS			= 1,
366 };
367 
368 /** TCP transport-specific address subtype */
369 struct spdk_nvme_tcp_transport_specific_address_subtype {
370 	/** Security type (\ref spdk_nvme_tcp_secure_socket_type) */
371 	uint8_t		sectype;
372 
373 	uint8_t		reserved0[255];
374 };
375 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_transport_specific_address_subtype) == 256,
376 		   "Incorrect size");
377 
378 /** Transport-specific address subtype */
379 union spdk_nvmf_transport_specific_address_subtype {
380 	uint8_t raw[256];
381 
382 	/** RDMA */
383 	struct spdk_nvmf_rdma_transport_specific_address_subtype rdma;
384 
385 	/** TCP */
386 	struct spdk_nvme_tcp_transport_specific_address_subtype tcp;
387 };
388 SPDK_STATIC_ASSERT(sizeof(union spdk_nvmf_transport_specific_address_subtype) == 256,
389 		   "Incorrect size");
390 
391 #define SPDK_NVMF_MIN_ADMIN_MAX_SQ_SIZE 32
392 
393 /**
394  * Discovery Log Page entry
395  */
396 struct spdk_nvmf_discovery_log_page_entry {
397 	/** Transport type (\ref spdk_nvmf_trtype) */
398 	uint8_t		trtype;
399 
400 	/** Address family (\ref spdk_nvmf_adrfam) */
401 	uint8_t		adrfam;
402 
403 	/** Subsystem type (\ref spdk_nvmf_subtype) */
404 	uint8_t		subtype;
405 
406 	/** Transport requirements */
407 	struct {
408 		/** Secure channel requirements (\ref spdk_nvmf_treq_secure_channel) */
409 		uint8_t secure_channel : 2;
410 
411 		uint8_t reserved : 6;
412 	} treq;
413 
414 	/** NVM subsystem port ID */
415 	uint16_t	portid;
416 
417 	/** Controller ID */
418 	uint16_t	cntlid;
419 
420 	/** Admin max SQ size */
421 	uint16_t	asqsz;
422 
423 	uint8_t		reserved0[22];
424 
425 	/** Transport service identifier */
426 	uint8_t		trsvcid[SPDK_NVMF_TRSVCID_MAX_LEN];
427 
428 	uint8_t		reserved1[192];
429 
430 	/** NVM subsystem qualified name */
431 	uint8_t		subnqn[256];
432 
433 	/** Transport address */
434 	uint8_t		traddr[SPDK_NVMF_TRADDR_MAX_LEN];
435 
436 	/** Transport-specific address subtype */
437 	union spdk_nvmf_transport_specific_address_subtype tsas;
438 };
439 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_discovery_log_page_entry) == 1024, "Incorrect size");
440 
441 struct spdk_nvmf_discovery_log_page {
442 	uint64_t	genctr;
443 	uint64_t	numrec;
444 	uint16_t	recfmt;
445 	uint8_t		reserved0[1006];
446 	struct spdk_nvmf_discovery_log_page_entry entries[0];
447 };
448 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_discovery_log_page) == 1024, "Incorrect size");
449 
450 /* RDMA Fabric specific definitions below */
451 
452 #define SPDK_NVME_SGL_SUBTYPE_INVALIDATE_KEY	0xF
453 
454 struct spdk_nvmf_rdma_request_private_data {
455 	uint16_t	recfmt; /* record format */
456 	uint16_t	qid;	/* queue id */
457 	uint16_t	hrqsize;	/* host receive queue size */
458 	uint16_t	hsqsize;	/* host send queue size */
459 	uint16_t	cntlid;		/* controller id */
460 	uint8_t		reserved[22];
461 };
462 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_rdma_request_private_data) == 32, "Incorrect size");
463 
464 struct spdk_nvmf_rdma_accept_private_data {
465 	uint16_t	recfmt; /* record format */
466 	uint16_t	crqsize;	/* controller receive queue size */
467 	uint8_t		reserved[28];
468 };
469 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_rdma_accept_private_data) == 32, "Incorrect size");
470 
471 struct spdk_nvmf_rdma_reject_private_data {
472 	uint16_t	recfmt; /* record format */
473 	uint16_t	sts; /* status */
474 };
475 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_rdma_reject_private_data) == 4, "Incorrect size");
476 
477 union spdk_nvmf_rdma_private_data {
478 	struct spdk_nvmf_rdma_request_private_data	pd_request;
479 	struct spdk_nvmf_rdma_accept_private_data	pd_accept;
480 	struct spdk_nvmf_rdma_reject_private_data	pd_reject;
481 };
482 SPDK_STATIC_ASSERT(sizeof(union spdk_nvmf_rdma_private_data) == 32, "Incorrect size");
483 
484 enum spdk_nvmf_rdma_transport_error {
485 	SPDK_NVMF_RDMA_ERROR_INVALID_PRIVATE_DATA_LENGTH	= 0x1,
486 	SPDK_NVMF_RDMA_ERROR_INVALID_RECFMT			= 0x2,
487 	SPDK_NVMF_RDMA_ERROR_INVALID_QID			= 0x3,
488 	SPDK_NVMF_RDMA_ERROR_INVALID_HSQSIZE			= 0x4,
489 	SPDK_NVMF_RDMA_ERROR_INVALID_HRQSIZE			= 0x5,
490 	SPDK_NVMF_RDMA_ERROR_NO_RESOURCES			= 0x6,
491 	SPDK_NVMF_RDMA_ERROR_INVALID_IRD			= 0x7,
492 	SPDK_NVMF_RDMA_ERROR_INVALID_ORD			= 0x8,
493 };
494 
495 /* TCP transport specific definitions below */
496 
497 /** NVMe/TCP PDU type */
498 enum spdk_nvme_tcp_pdu_type {
499 	/** Initialize Connection Request (ICReq) */
500 	SPDK_NVME_TCP_PDU_TYPE_IC_REQ			= 0x00,
501 
502 	/** Initialize Connection Response (ICResp) */
503 	SPDK_NVME_TCP_PDU_TYPE_IC_RESP			= 0x01,
504 
505 	/** Terminate Connection Request (TermReq) */
506 	SPDK_NVME_TCP_PDU_TYPE_H2C_TERM_REQ		= 0x02,
507 
508 	/** Terminate Connection Response (TermResp) */
509 	SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ		= 0x03,
510 
511 	/** Command Capsule (CapsuleCmd) */
512 	SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD		= 0x04,
513 
514 	/** Response Capsule (CapsuleRsp) */
515 	SPDK_NVME_TCP_PDU_TYPE_CAPSULE_RESP		= 0x05,
516 
517 	/** Host To Controller Data (H2CData) */
518 	SPDK_NVME_TCP_PDU_TYPE_H2C_DATA			= 0x06,
519 
520 	/** Controller To Host Data (C2HData) */
521 	SPDK_NVME_TCP_PDU_TYPE_C2H_DATA			= 0x07,
522 
523 	/** Ready to Transfer (R2T) */
524 	SPDK_NVME_TCP_PDU_TYPE_R2T			= 0x09,
525 };
526 
527 /** Common NVMe/TCP PDU header */
528 struct spdk_nvme_tcp_common_pdu_hdr {
529 	/** PDU type (\ref spdk_nvme_tcp_pdu_type) */
530 	uint8_t				pdu_type;
531 
532 	/** pdu_type-specific flags */
533 	uint8_t				flags;
534 
535 	/** Length of PDU header (not including the Header Digest) */
536 	uint8_t				hlen;
537 
538 	/** PDU Data Offset from the start of the PDU */
539 	uint8_t				pdo;
540 
541 	/** Total number of bytes in PDU, including pdu_hdr */
542 	uint32_t			plen;
543 };
544 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_common_pdu_hdr) == 8, "Incorrect size");
545 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, pdu_type) == 0,
546 		   "Incorrect offset");
547 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, flags) == 1, "Incorrect offset");
548 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, hlen) == 2, "Incorrect offset");
549 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, pdo) == 3, "Incorrect offset");
550 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_common_pdu_hdr, plen) == 4, "Incorrect offset");
551 
552 #define SPDK_NVME_TCP_CH_FLAGS_HDGSTF		(1u << 0)
553 #define SPDK_NVME_TCP_CH_FLAGS_DDGSTF		(1u << 1)
554 
555 /**
556  * ICReq
557  *
558  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_IC_REQ
559  */
560 struct spdk_nvme_tcp_ic_req {
561 	struct spdk_nvme_tcp_common_pdu_hdr	common;
562 	uint16_t				pfv;
563 	/** Specifies the data alignment for all PDUs transferred from the controller to the host that contain data */
564 	uint8_t					hpda;
565 	union {
566 		uint8_t				raw;
567 		struct {
568 			uint8_t			hdgst_enable : 1;
569 			uint8_t			ddgst_enable : 1;
570 			uint8_t			reserved : 6;
571 		} bits;
572 	} dgst;
573 	uint32_t				maxr2t;
574 	uint8_t					reserved16[112];
575 };
576 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_ic_req) == 128, "Incorrect size");
577 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, pfv) == 8, "Incorrect offset");
578 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, hpda) == 10, "Incorrect offset");
579 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, maxr2t) == 12, "Incorrect offset");
580 
581 #define SPDK_NVME_TCP_CPDA_MAX 31
582 #define SPDK_NVME_TCP_PDU_PDO_MAX_OFFSET     ((SPDK_NVME_TCP_CPDA_MAX + 1) << 2)
583 
584 /**
585  * ICResp
586  *
587  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_IC_RESP
588  */
589 struct spdk_nvme_tcp_ic_resp {
590 	struct spdk_nvme_tcp_common_pdu_hdr	common;
591 	uint16_t				pfv;
592 	/** Specifies the data alignment for all PDUs transferred from the host to the controller that contain data */
593 	uint8_t					cpda;
594 	union {
595 		uint8_t				raw;
596 		struct {
597 			uint8_t			hdgst_enable : 1;
598 			uint8_t			ddgst_enable : 1;
599 			uint8_t			reserved : 6;
600 		} bits;
601 	} dgst;
602 	/** Specifies the maximum number of PDU-Data bytes per H2C Data Transfer PDU */
603 	uint32_t				maxh2cdata;
604 	uint8_t					reserved16[112];
605 };
606 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_ic_resp) == 128, "Incorrect size");
607 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_resp, pfv) == 8, "Incorrect offset");
608 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_resp, cpda) == 10, "Incorrect offset");
609 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_resp, maxh2cdata) == 12, "Incorrect offset");
610 
611 /**
612  * TermReq
613  *
614  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_TERM_REQ
615  */
616 struct spdk_nvme_tcp_term_req_hdr {
617 	struct spdk_nvme_tcp_common_pdu_hdr	common;
618 	uint16_t				fes;
619 	uint8_t					fei[4];
620 	uint8_t					reserved14[10];
621 };
622 
623 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_term_req_hdr) == 24, "Incorrect size");
624 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_term_req_hdr, fes) == 8, "Incorrect offset");
625 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_term_req_hdr, fei) == 10, "Incorrect offset");
626 
627 enum spdk_nvme_tcp_term_req_fes {
628 	SPDK_NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD				= 0x01,
629 	SPDK_NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR				= 0x02,
630 	SPDK_NVME_TCP_TERM_REQ_FES_HDGST_ERROR					= 0x03,
631 	SPDK_NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE			= 0x04,
632 	SPDK_NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_LIMIT_EXCEEDED			= 0x05,
633 	SPDK_NVME_TCP_TERM_REQ_FES_R2T_LIMIT_EXCEEDED				= 0x05,
634 	SPDK_NVME_TCP_TERM_REQ_FES_INVALID_DATA_UNSUPPORTED_PARAMETER		= 0x06,
635 };
636 
637 /* Total length of term req PDU (including PDU header and DATA) in bytes shall not exceed a limit of 152 bytes. */
638 #define SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE	128
639 #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))
640 
641 /**
642  * CapsuleCmd
643  *
644  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD
645  */
646 struct spdk_nvme_tcp_cmd {
647 	struct spdk_nvme_tcp_common_pdu_hdr	common;
648 	struct spdk_nvme_cmd			ccsqe;
649 	/**< icdoff hdgest padding + in-capsule data + ddgst (if enabled) */
650 };
651 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_cmd) == 72, "Incorrect size");
652 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_cmd, ccsqe) == 8, "Incorrect offset");
653 
654 /**
655  * CapsuleResp
656  *
657  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_CAPSULE_RESP
658  */
659 struct spdk_nvme_tcp_rsp {
660 	struct spdk_nvme_tcp_common_pdu_hdr	common;
661 	struct spdk_nvme_cpl			rccqe;
662 };
663 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_rsp) == 24, "incorrect size");
664 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_rsp, rccqe) == 8, "Incorrect offset");
665 
666 
667 /**
668  * H2CData
669  *
670  * hdr.pdu_type == SPDK_NVME_TCP_PDU_TYPE_H2C_DATA
671  */
672 struct spdk_nvme_tcp_h2c_data_hdr {
673 	struct spdk_nvme_tcp_common_pdu_hdr	common;
674 	uint16_t				cccid;
675 	uint16_t				ttag;
676 	uint32_t				datao;
677 	uint32_t				datal;
678 	uint8_t					reserved20[4];
679 };
680 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_h2c_data_hdr) == 24, "Incorrect size");
681 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_h2c_data_hdr, cccid) == 8, "Incorrect offset");
682 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_h2c_data_hdr, ttag) == 10, "Incorrect offset");
683 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_h2c_data_hdr, datao) == 12, "Incorrect offset");
684 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_h2c_data_hdr, datal) == 16, "Incorrect offset");
685 
686 #define SPDK_NVME_TCP_H2C_DATA_FLAGS_LAST_PDU	(1u << 2)
687 #define SPDK_NVME_TCP_H2C_DATA_FLAGS_SUCCESS	(1u << 3)
688 #define SPDK_NVME_TCP_H2C_DATA_PDO_MULT		8u
689 
690 /**
691  * C2HData
692  *
693  * hdr.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_DATA
694  */
695 struct spdk_nvme_tcp_c2h_data_hdr {
696 	struct spdk_nvme_tcp_common_pdu_hdr	common;
697 	uint16_t				cccid;
698 	uint8_t					reserved10[2];
699 	uint32_t				datao;
700 	uint32_t				datal;
701 	uint8_t					reserved20[4];
702 };
703 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_c2h_data_hdr) == 24, "Incorrect size");
704 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_c2h_data_hdr, cccid) == 8, "Incorrect offset");
705 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_c2h_data_hdr, datao) == 12, "Incorrect offset");
706 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_c2h_data_hdr, datal) == 16, "Incorrect offset");
707 
708 #define SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS	(1u << 3)
709 #define SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU	(1u << 2)
710 #define SPDK_NVME_TCP_C2H_DATA_PDO_MULT		8u
711 
712 /**
713  * R2T
714  *
715  * common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_R2T
716  */
717 struct spdk_nvme_tcp_r2t_hdr {
718 	struct spdk_nvme_tcp_common_pdu_hdr	common;
719 	uint16_t				cccid;
720 	uint16_t				ttag;
721 	uint32_t				r2to;
722 	uint32_t				r2tl;
723 	uint8_t					reserved20[4];
724 };
725 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_tcp_r2t_hdr) == 24, "Incorrect size");
726 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_r2t_hdr, cccid) == 8, "Incorrect offset");
727 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_r2t_hdr, ttag) == 10, "Incorrect offset");
728 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_r2t_hdr, r2to) == 12, "Incorrect offset");
729 SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_r2t_hdr, r2tl) == 16, "Incorrect offset");
730 
731 #pragma pack(pop)
732 
733 #endif /* __NVMF_SPEC_H__ */
734