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