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