1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2016 Intel Corporation.
3 * All rights reserved.
4 */
5
6/* Derived from include/spdk/nvmf_spec.h from Intel's SPDK. */
7
8#ifndef __NVMF_PROTO_H__
9#define __NVMF_PROTO_H__
10
11#include <sys/types.h>
12#include <sys/cdefs.h>
13#ifdef _KERNEL
14#include <sys/stddef.h>
15#else
16#include <stddef.h>
17#endif
18#include <dev/nvme/nvme.h>
19
20/**
21 * \file
22 * NVMe over Fabrics specification definitions
23 */
24
25#define NVME_NQN_FIELD_SIZE 256
26
27struct nvmf_capsule_cmd {
28 uint8_t opcode;
29 uint8_t reserved1;
30 uint16_t cid;
31 uint8_t fctype;
32 uint8_t reserved2[35];
33 uint8_t fabric_specific[24];
34};
35_Static_assert(sizeof(struct nvmf_capsule_cmd) == 64, "Incorrect size");
36
37/* Fabric Command Set */
38enum nvmf_fabric_cmd_types {
39 NVMF_FABRIC_COMMAND_PROPERTY_SET = 0x00,
40 NVMF_FABRIC_COMMAND_CONNECT = 0x01,
41 NVMF_FABRIC_COMMAND_PROPERTY_GET = 0x04,
42 NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND = 0x05,
43 NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV = 0x06,
44 NVMF_FABRIC_COMMAND_DISCONNECT = 0x08,
45 NVMF_FABRIC_COMMAND_START_VENDOR_SPECIFIC = 0xC0,
46};
47
48enum nvmf_fabric_cmd_status_code {
49 NVMF_FABRIC_SC_INCOMPATIBLE_FORMAT = 0x80,
50 NVMF_FABRIC_SC_CONTROLLER_BUSY = 0x81,
51 NVMF_FABRIC_SC_INVALID_PARAM = 0x82,
52 NVMF_FABRIC_SC_RESTART_DISCOVERY = 0x83,
53 NVMF_FABRIC_SC_INVALID_HOST = 0x84,
54 NVMF_FABRIC_SC_INVALID_QUEUE_TYPE = 0x85,
55 NVMF_FABRIC_SC_LOG_RESTART_DISCOVERY = 0x90,
56 NVMF_FABRIC_SC_AUTH_REQUIRED = 0x91,
57};
58
59/**
60 * RDMA Queue Pair service types
61 */
62enum nvmf_rdma_qptype {
63 /** Reliable connected */
64 NVMF_RDMA_QPTYPE_RELIABLE_CONNECTED = 0x1,
65
66 /** Reliable datagram */
67 NVMF_RDMA_QPTYPE_RELIABLE_DATAGRAM = 0x2,
68};
69
70/**
71 * RDMA provider types
72 */
73enum nvmf_rdma_prtype {
74 /** No provider specified */
75 NVMF_RDMA_PRTYPE_NONE = 0x1,
76
77 /** InfiniBand */
78 NVMF_RDMA_PRTYPE_IB = 0x2,
79
80 /** RoCE v1 */
81 NVMF_RDMA_PRTYPE_ROCE = 0x3,
82
83 /** RoCE v2 */
84 NVMF_RDMA_PRTYPE_ROCE2 = 0x4,
85
86 /** iWARP */
87 NVMF_RDMA_PRTYPE_IWARP = 0x5,
88};
89
90/**
91 * RDMA connection management service types
92 */
93enum nvmf_rdma_cms {
94 /** Sockets based endpoint addressing */
95 NVMF_RDMA_CMS_RDMA_CM = 0x1,
96};
97
98/**
99 * NVMe over Fabrics transport types
100 */
101enum nvmf_trtype {
102 /** RDMA */
103 NVMF_TRTYPE_RDMA = 0x1,
104
105 /** Fibre Channel */
106 NVMF_TRTYPE_FC = 0x2,
107
108 /** TCP */
109 NVMF_TRTYPE_TCP = 0x3,
110
111 /** Intra-host transport (loopback) */
112 NVMF_TRTYPE_INTRA_HOST = 0xfe,
113};
114
115/**
116 * Address family types
117 */
118enum nvmf_adrfam {
119 /** IPv4 (AF_INET) */
120 NVMF_ADRFAM_IPV4 = 0x1,
121
122 /** IPv6 (AF_INET6) */
123 NVMF_ADRFAM_IPV6 = 0x2,
124
125 /** InfiniBand (AF_IB) */
126 NVMF_ADRFAM_IB = 0x3,
127
128 /** Fibre Channel address family */
129 NVMF_ADRFAM_FC = 0x4,
130
131 /** Intra-host transport (loopback) */
132 NVMF_ADRFAM_INTRA_HOST = 0xfe,
133};
134
135/**
136 * NVM subsystem types
137 */
138enum nvmf_subtype {
139 /** Referral to a discovery service */
140 NVMF_SUBTYPE_DISCOVERY = 0x1,
141
142 /** NVM Subsystem */
143 NVMF_SUBTYPE_NVME = 0x2,
144
145 /** Current Discovery Subsystem */
146 NVMF_SUBTYPE_DISCOVERY_CURRENT = 0x3
147};
148
149/* Discovery Log Entry Flags - Duplicate Returned Information */
150#define NVMF_DISCOVERY_LOG_EFLAGS_DUPRETINFO (1u << 0u)
151
152/* Discovery Log Entry Flags - Explicit Persistent Connection Support for Discovery */
153#define NVMF_DISCOVERY_LOG_EFLAGS_EPCSD (1u << 1u)
154
155/**
156 * Connections shall be made over a fabric secure channel
157 */
158enum nvmf_treq_secure_channel {
159 /** Not specified */
160 NVMF_TREQ_SECURE_CHANNEL_NOT_SPECIFIED = 0x0,
161
162 /** Required */
163 NVMF_TREQ_SECURE_CHANNEL_REQUIRED = 0x1,
164
165 /** Not required */
166 NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED = 0x2,
167};
168
169struct nvmf_fabric_cmd {
170 uint8_t opcode;
171 uint8_t reserved1;
172 uint16_t cid;
173 uint8_t fctype;
174 uint8_t reserved2[59];
175} __aligned(8);
176
177struct nvmf_fabric_auth_recv_cmd {
178 uint8_t opcode;
179 uint8_t reserved1;
180 uint16_t cid;
181 uint8_t fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV (0x06) */
182 uint8_t reserved2[19];
183 struct nvme_sgl_descriptor sgl1;
184 uint8_t reserved3;
185 uint8_t spsp0;
186 uint8_t spsp1;
187 uint8_t secp;
188 uint32_t al;
189 uint8_t reserved4[16];
190};
191_Static_assert(sizeof(struct nvmf_fabric_auth_recv_cmd) == 64, "Incorrect size");
192
193struct nvmf_fabric_auth_send_cmd {
194 uint8_t opcode;
195 uint8_t reserved1;
196 uint16_t cid;
197 uint8_t fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND (0x05) */
198 uint8_t reserved2[19];
199 struct nvme_sgl_descriptor sgl1;
200 uint8_t reserved3;
201 uint8_t spsp0;
202 uint8_t spsp1;
203 uint8_t secp;
204 uint32_t tl;
205 uint8_t reserved4[16];
206};
207_Static_assert(sizeof(struct nvmf_fabric_auth_send_cmd) == 64, "Incorrect size");
208
209struct nvmf_fabric_connect_data {
210 uint8_t hostid[16];
211 uint16_t cntlid;
212 uint8_t reserved5[238];
213 uint8_t subnqn[NVME_NQN_FIELD_SIZE];
214 uint8_t hostnqn[NVME_NQN_FIELD_SIZE];
215 uint8_t reserved6[256];
216};
217_Static_assert(sizeof(struct nvmf_fabric_connect_data) == 1024, "Incorrect size");
218
219struct nvmf_fabric_connect_cmd {
220 uint8_t opcode;
221 uint8_t reserved1;
222 uint16_t cid;
223 uint8_t fctype;
224 uint8_t reserved2[19];
225 struct nvme_sgl_descriptor sgl1;
226 uint16_t recfmt; /* Connect Record Format */
227 uint16_t qid; /* Queue Identifier */
228 uint16_t sqsize; /* Submission Queue Size */
229 uint8_t cattr; /* queue attributes */
230 uint8_t reserved3;
231 uint32_t kato; /* keep alive timeout */
232 uint8_t reserved4[12];
233};
234_Static_assert(sizeof(struct nvmf_fabric_connect_cmd) == 64, "Incorrect size");
235
236#define NVMF_CNTLID_DYNAMIC 0xFFFF
237#define NVMF_CNTLID_STATIC_ANY 0xFFFE
238
239/*
240 * XXX: 5.3 in NVMe-over-Fabrics 1.1 gives this as an upper bound in
241 * the Discovery Log Entry.
242 */
243#define NVMF_CNTLID_STATIC_MAX 0xFFEF
244
245/* 5.21.1.15 in NVMe 1.4b */
246#define NVMF_KATO_DEFAULT (120000)
247
248#define NVMF_CONNECT_ATTR_PRIORITY_CLASS (0x3)
249#define NVMF_CONNECT_ATTR_DISABLE_SQ_FC (1u << 2)
250#define NVMF_CONNECT_ATTR_IO_QUEUE_DELETION (1u << 3)
251
252struct nvmf_fabric_connect_rsp {
253 union {
254 struct {
255 uint16_t cntlid;
256 uint16_t authreq;
257 } success;
258
259 struct {
260 uint16_t ipo;
261 uint8_t iattr;
262 uint8_t reserved;
263 } invalid;
264
265 uint32_t raw;
266 } status_code_specific;
267
268 uint32_t reserved0;
269 uint16_t sqhd;
270 uint16_t reserved1;
271 uint16_t cid;
272 uint16_t status;
273};
274_Static_assert(sizeof(struct nvmf_fabric_connect_rsp) == 16, "Incorrect size");
275
276struct nvmf_fabric_disconnect_cmd {
277 uint8_t opcode;
278 uint8_t reserved1;
279 uint16_t cid;
280 uint8_t fctype;
281 uint8_t reserved2[19];
282 struct nvme_sgl_descriptor sgl1;
283 uint16_t recfmt; /* Disconnect Record Format */
284 uint8_t reserved3[22];
285};
286_Static_assert(sizeof(struct nvmf_fabric_disconnect_cmd) == 64, "Incorrect size");
287
288#define NVMF_PROP_SIZE_4 0
289#define NVMF_PROP_SIZE_8 1
290
291#define NVMF_PROP_CAP 0x00 /* Controller Capabilities */
292#define NVMF_PROP_VS 0x08 /* Version */
293#define NVMF_PROP_CC 0x14 /* Controller Configuration */
294#define NVMF_PROP_CSTS 0x1C /* Controller Status */
295#define NVMF_PROP_NSSR 0x20 /* NVM Subsystem Reset */
296
297struct nvmf_fabric_prop_get_cmd {
298 uint8_t opcode;
299 uint8_t reserved1;
300 uint16_t cid;
301 uint8_t fctype;
302 uint8_t reserved2[35];
303 struct {
304 uint8_t size : 3;
305 uint8_t reserved : 5;
306 } attrib;
307 uint8_t reserved3[3];
308 uint32_t ofst;
309 uint8_t reserved4[16];
310};
311_Static_assert(sizeof(struct nvmf_fabric_prop_get_cmd) == 64, "Incorrect size");
312
313struct nvmf_fabric_prop_get_rsp {
314 union {
315 uint64_t u64;
316 struct {
317 uint32_t low;
318 uint32_t high;
319 } u32;
320 } value;
321
322 uint16_t sqhd;
323 uint16_t reserved0;
324 uint16_t cid;
325 uint16_t status;
326};
327_Static_assert(sizeof(struct nvmf_fabric_prop_get_rsp) == 16, "Incorrect size");
328
329struct nvmf_fabric_prop_set_cmd {
330 uint8_t opcode;
331 uint8_t reserved0;
332 uint16_t cid;
333 uint8_t fctype;
334 uint8_t reserved1[35];
335 struct {
336 uint8_t size : 3;
337 uint8_t reserved : 5;
338 } attrib;
339 uint8_t reserved2[3];
340 uint32_t ofst;
341
342 union {
343 uint64_t u64;
344 struct {
345 uint32_t low;
346 uint32_t high;
347 } u32;
348 } value;
349
350 uint8_t reserved4[8];
351};
352_Static_assert(sizeof(struct nvmf_fabric_prop_set_cmd) == 64, "Incorrect size");
353
354#define NVMF_NQN_MIN_LEN 11 /* The prefix in the spec is 11 characters */
355#define NVMF_NQN_MAX_LEN 223
356#define NVMF_NQN_UUID_PRE_LEN 32
357#define NVMF_UUID_STRING_LEN 36
358#define NVMF_NQN_UUID_PRE "nqn.2014-08.org.nvmexpress:uuid:"
359#define NVMF_DISCOVERY_NQN "nqn.2014-08.org.nvmexpress.discovery"
360
361#define NVMF_TRSTRING_MAX_LEN 32
362#define NVMF_TRADDR_MAX_LEN 256
363#define NVMF_TRSVCID_MAX_LEN 32
364
365/** RDMA transport-specific address subtype */
366struct nvmf_rdma_transport_specific_address_subtype {
367 /** RDMA QP service type (\ref nvmf_rdma_qptype) */
368 uint8_t rdma_qptype;
369
370 /** RDMA provider type (\ref nvmf_rdma_prtype) */
371 uint8_t rdma_prtype;
372
373 /** RDMA connection management service (\ref nvmf_rdma_cms) */
374 uint8_t rdma_cms;
375
376 uint8_t reserved0[5];
377
378 /** RDMA partition key for AF_IB */
379 uint16_t rdma_pkey;
380
381 uint8_t reserved2[246];
382};
383_Static_assert(sizeof(struct nvmf_rdma_transport_specific_address_subtype) == 256,
384 "Incorrect size");
385
386/** TCP Secure Socket Type */
387enum nvme_tcp_secure_socket_type {
388 /** No security */
389 NVME_TCP_SECURITY_NONE = 0,
390
391 /** TLS (Secure Sockets) version 1.2 */
392 NVME_TCP_SECURITY_TLS_1_2 = 1,
393
394 /** TLS (Secure Sockets) version 1.3 */
395 NVME_TCP_SECURITY_TLS_1_3 = 2,
396};
397
398/** TCP transport-specific address subtype */
399struct nvme_tcp_transport_specific_address_subtype {
400 /** Security type (\ref nvme_tcp_secure_socket_type) */
401 uint8_t sectype;
402
403 uint8_t reserved0[255];
404};
405_Static_assert(sizeof(struct nvme_tcp_transport_specific_address_subtype) == 256,
406 "Incorrect size");
407
408/** Transport-specific address subtype */
409union nvmf_transport_specific_address_subtype {
410 uint8_t raw[256];
411
412 /** RDMA */
413 struct nvmf_rdma_transport_specific_address_subtype rdma;
414
415 /** TCP */
416 struct nvme_tcp_transport_specific_address_subtype tcp;
417};
418_Static_assert(sizeof(union nvmf_transport_specific_address_subtype) == 256,
419 "Incorrect size");
420
421#define NVMF_MIN_ADMIN_MAX_SQ_SIZE 32
422
423/**
424 * Discovery Log Page entry
425 */
426struct nvmf_discovery_log_page_entry {
427 /** Transport type (\ref nvmf_trtype) */
428 uint8_t trtype;
429
430 /** Address family (\ref nvmf_adrfam) */
431 uint8_t adrfam;
432
433 /** Subsystem type (\ref nvmf_subtype) */
434 uint8_t subtype;
435
436 /** Transport requirements */
437 struct {
438 /** Secure channel requirements (\ref nvmf_treq_secure_channel) */
439 uint8_t secure_channel : 2;
440
441 uint8_t reserved : 6;
442 } treq;
443
444 /** NVM subsystem port ID */
445 uint16_t portid;
446
447 /** Controller ID */
448 uint16_t cntlid;
449
450 /** Admin max SQ size */
451 uint16_t asqsz;
452
453 /** Entry Flags */
454 uint16_t eflags;
455
456 uint8_t reserved0[20];
457
458 /** Transport service identifier */
459 uint8_t trsvcid[NVMF_TRSVCID_MAX_LEN];
460
461 uint8_t reserved1[192];
462
463 /** NVM subsystem qualified name */
464 uint8_t subnqn[256];
465
466 /** Transport address */
467 uint8_t traddr[NVMF_TRADDR_MAX_LEN];
468
469 /** Transport-specific address subtype */
470 union nvmf_transport_specific_address_subtype tsas;
471};
472_Static_assert(sizeof(struct nvmf_discovery_log_page_entry) == 1024, "Incorrect size");
473
474struct nvmf_discovery_log_page {
475 uint64_t genctr;
476 uint64_t numrec;
477 uint16_t recfmt;
478 uint8_t reserved0[1006];
479 struct nvmf_discovery_log_page_entry entries[0];
480};
481_Static_assert(sizeof(struct nvmf_discovery_log_page) == 1024, "Incorrect size");
482
483/* RDMA Fabric specific definitions below */
484
485#define NVME_SGL_SUBTYPE_INVALIDATE_KEY 0xF
486
487struct nvmf_rdma_request_private_data {
488 uint16_t recfmt; /* record format */
489 uint16_t qid; /* queue id */
490 uint16_t hrqsize; /* host receive queue size */
491 uint16_t hsqsize; /* host send queue size */
492 uint16_t cntlid; /* controller id */
493 uint8_t reserved[22];
494};
495_Static_assert(sizeof(struct nvmf_rdma_request_private_data) == 32, "Incorrect size");
496
497struct nvmf_rdma_accept_private_data {
498 uint16_t recfmt; /* record format */
499 uint16_t crqsize; /* controller receive queue size */
500 uint8_t reserved[28];
501};
502_Static_assert(sizeof(struct nvmf_rdma_accept_private_data) == 32, "Incorrect size");
503
504struct nvmf_rdma_reject_private_data {
505 uint16_t recfmt; /* record format */
506 uint16_t sts; /* status */
507};
508_Static_assert(sizeof(struct nvmf_rdma_reject_private_data) == 4, "Incorrect size");
509
510union nvmf_rdma_private_data {
511 struct nvmf_rdma_request_private_data pd_request;
512 struct nvmf_rdma_accept_private_data pd_accept;
513 struct nvmf_rdma_reject_private_data pd_reject;
514};
515_Static_assert(sizeof(union nvmf_rdma_private_data) == 32, "Incorrect size");
516
517enum nvmf_rdma_transport_error {
518 NVMF_RDMA_ERROR_INVALID_PRIVATE_DATA_LENGTH = 0x1,
519 NVMF_RDMA_ERROR_INVALID_RECFMT = 0x2,
520 NVMF_RDMA_ERROR_INVALID_QID = 0x3,
521 NVMF_RDMA_ERROR_INVALID_HSQSIZE = 0x4,
522 NVMF_RDMA_ERROR_INVALID_HRQSIZE = 0x5,
523 NVMF_RDMA_ERROR_NO_RESOURCES = 0x6,
524 NVMF_RDMA_ERROR_INVALID_IRD = 0x7,
525 NVMF_RDMA_ERROR_INVALID_ORD = 0x8,
526};
527
528/* TCP transport specific definitions below */
529
530/** NVMe/TCP PDU type */
531enum nvme_tcp_pdu_type {
532 /** Initialize Connection Request (ICReq) */
533 NVME_TCP_PDU_TYPE_IC_REQ = 0x00,
534
535 /** Initialize Connection Response (ICResp) */
536 NVME_TCP_PDU_TYPE_IC_RESP = 0x01,
537
538 /** Terminate Connection Request (TermReq) */
539 NVME_TCP_PDU_TYPE_H2C_TERM_REQ = 0x02,
540
541 /** Terminate Connection Response (TermResp) */
542 NVME_TCP_PDU_TYPE_C2H_TERM_REQ = 0x03,
543
544 /** Command Capsule (CapsuleCmd) */
545 NVME_TCP_PDU_TYPE_CAPSULE_CMD = 0x04,
546
547 /** Response Capsule (CapsuleRsp) */
548 NVME_TCP_PDU_TYPE_CAPSULE_RESP = 0x05,
549
550 /** Host To Controller Data (H2CData) */
551 NVME_TCP_PDU_TYPE_H2C_DATA = 0x06,
552
553 /** Controller To Host Data (C2HData) */
554 NVME_TCP_PDU_TYPE_C2H_DATA = 0x07,
555
556 /** Ready to Transfer (R2T) */
557 NVME_TCP_PDU_TYPE_R2T = 0x09,
558};
559
560/** Common NVMe/TCP PDU header */
561struct nvme_tcp_common_pdu_hdr {
562 /** PDU type (\ref nvme_tcp_pdu_type) */
563 uint8_t pdu_type;
564
565 /** pdu_type-specific flags */
566 uint8_t flags;
567
568 /** Length of PDU header (not including the Header Digest) */
569 uint8_t hlen;
570
571 /** PDU Data Offset from the start of the PDU */
572 uint8_t pdo;
573
574 /** Total number of bytes in PDU, including pdu_hdr */
575 uint32_t plen;
576};
577_Static_assert(sizeof(struct nvme_tcp_common_pdu_hdr) == 8, "Incorrect size");
578_Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, pdu_type) == 0,
579 "Incorrect offset");
580_Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, flags) == 1, "Incorrect offset");
581_Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, hlen) == 2, "Incorrect offset");
582_Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, pdo) == 3, "Incorrect offset");
583_Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, plen) == 4, "Incorrect offset");
584
585#define NVME_TCP_CH_FLAGS_HDGSTF (1u << 0)
586#define NVME_TCP_CH_FLAGS_DDGSTF (1u << 1)
587
588/**
589 * ICReq
590 *
591 * common.pdu_type == NVME_TCP_PDU_TYPE_IC_REQ
592 */
593struct nvme_tcp_ic_req {
594 struct nvme_tcp_common_pdu_hdr common;
595 uint16_t pfv;
596 /** Specifies the data alignment for all PDUs transferred from the controller to the host that contain data */
597 uint8_t hpda;
598 union {
599 uint8_t raw;
600 struct {
601 uint8_t hdgst_enable : 1;
602 uint8_t ddgst_enable : 1;
603 uint8_t reserved : 6;
604 } bits;
605 } dgst;
606 uint32_t maxr2t;
607 uint8_t reserved16[112];
608};
609_Static_assert(sizeof(struct nvme_tcp_ic_req) == 128, "Incorrect size");
610_Static_assert(offsetof(struct nvme_tcp_ic_req, pfv) == 8, "Incorrect offset");
611_Static_assert(offsetof(struct nvme_tcp_ic_req, hpda) == 10, "Incorrect offset");
612_Static_assert(offsetof(struct nvme_tcp_ic_req, maxr2t) == 12, "Incorrect offset");
613
614#define NVME_TCP_HPDA_MAX 31
615#define NVME_TCP_CPDA_MAX 31
616#define NVME_TCP_PDU_PDO_MAX_OFFSET ((NVME_TCP_CPDA_MAX + 1) << 2)
617
618/**
619 * ICResp
620 *
621 * common.pdu_type == NVME_TCP_PDU_TYPE_IC_RESP
622 */
623struct nvme_tcp_ic_resp {
624 struct nvme_tcp_common_pdu_hdr common;
625 uint16_t pfv;
626 /** Specifies the data alignment for all PDUs transferred from the host to the controller that contain data */
627 uint8_t cpda;
628 union {
629 uint8_t raw;
630 struct {
631 uint8_t hdgst_enable : 1;
632 uint8_t ddgst_enable : 1;
633 uint8_t reserved : 6;
634 } bits;
635 } dgst;
636 /** Specifies the maximum number of PDU-Data bytes per H2C Data Transfer PDU */
637 uint32_t maxh2cdata;
638 uint8_t reserved16[112];
639};
640_Static_assert(sizeof(struct nvme_tcp_ic_resp) == 128, "Incorrect size");
641_Static_assert(offsetof(struct nvme_tcp_ic_resp, pfv) == 8, "Incorrect offset");
642_Static_assert(offsetof(struct nvme_tcp_ic_resp, cpda) == 10, "Incorrect offset");
643_Static_assert(offsetof(struct nvme_tcp_ic_resp, maxh2cdata) == 12, "Incorrect offset");
644
645/**
646 * TermReq
647 *
648 * common.pdu_type == NVME_TCP_PDU_TYPE_TERM_REQ
649 */
650struct nvme_tcp_term_req_hdr {
651 struct nvme_tcp_common_pdu_hdr common;
652 uint16_t fes;
653 uint8_t fei[4];
654 uint8_t reserved14[10];
655};
656
657_Static_assert(sizeof(struct nvme_tcp_term_req_hdr) == 24, "Incorrect size");
658_Static_assert(offsetof(struct nvme_tcp_term_req_hdr, fes) == 8, "Incorrect offset");
659_Static_assert(offsetof(struct nvme_tcp_term_req_hdr, fei) == 10, "Incorrect offset");
660
661enum nvme_tcp_term_req_fes {
662 NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD = 0x01,
663 NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR = 0x02,
664 NVME_TCP_TERM_REQ_FES_HDGST_ERROR = 0x03,
665 NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE = 0x04,
666 NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_LIMIT_EXCEEDED = 0x05,
667 NVME_TCP_TERM_REQ_FES_R2T_LIMIT_EXCEEDED = 0x05,
668 NVME_TCP_TERM_REQ_FES_INVALID_DATA_UNSUPPORTED_PARAMETER = 0x06,
669};
670
671/* Total length of term req PDU (including PDU header and DATA) in bytes shall not exceed a limit of 152 bytes. */
672#define NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE 128
673#define NVME_TCP_TERM_REQ_PDU_MAX_SIZE (NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE + sizeof(struct nvme_tcp_term_req_hdr))
674
675/**
676 * CapsuleCmd
677 *
678 * common.pdu_type == NVME_TCP_PDU_TYPE_CAPSULE_CMD
679 */
680struct nvme_tcp_cmd {
681 struct nvme_tcp_common_pdu_hdr common;
682 struct nvme_command ccsqe;
683 /**< icdoff hdgst padding + in-capsule data + ddgst (if enabled) */
684};
685_Static_assert(sizeof(struct nvme_tcp_cmd) == 72, "Incorrect size");
686_Static_assert(offsetof(struct nvme_tcp_cmd, ccsqe) == 8, "Incorrect offset");
687
688/**
689 * CapsuleResp
690 *
691 * common.pdu_type == NVME_TCP_PDU_TYPE_CAPSULE_RESP
692 */
693struct nvme_tcp_rsp {
694 struct nvme_tcp_common_pdu_hdr common;
695 struct nvme_completion rccqe;
696};
697_Static_assert(sizeof(struct nvme_tcp_rsp) == 24, "incorrect size");
698_Static_assert(offsetof(struct nvme_tcp_rsp, rccqe) == 8, "Incorrect offset");
699
700
701/**
702 * H2CData
703 *
704 * hdr.pdu_type == NVME_TCP_PDU_TYPE_H2C_DATA
705 */
706struct nvme_tcp_h2c_data_hdr {
707 struct nvme_tcp_common_pdu_hdr common;
708 uint16_t cccid;
709 uint16_t ttag;
710 uint32_t datao;
711 uint32_t datal;
712 uint8_t reserved20[4];
713};
714_Static_assert(sizeof(struct nvme_tcp_h2c_data_hdr) == 24, "Incorrect size");
715_Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, cccid) == 8, "Incorrect offset");
716_Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, ttag) == 10, "Incorrect offset");
717_Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, datao) == 12, "Incorrect offset");
718_Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, datal) == 16, "Incorrect offset");
719
720#define NVME_TCP_H2C_DATA_FLAGS_LAST_PDU (1u << 2)
721#define NVME_TCP_H2C_DATA_FLAGS_SUCCESS (1u << 3)
722#define NVME_TCP_H2C_DATA_PDO_MULT 8u
723
724/**
725 * C2HData
726 *
727 * hdr.pdu_type == NVME_TCP_PDU_TYPE_C2H_DATA
728 */
729struct nvme_tcp_c2h_data_hdr {
730 struct nvme_tcp_common_pdu_hdr common;
731 uint16_t cccid;
732 uint8_t reserved10[2];
733 uint32_t datao;
734 uint32_t datal;
735 uint8_t reserved20[4];
736};
737_Static_assert(sizeof(struct nvme_tcp_c2h_data_hdr) == 24, "Incorrect size");
738_Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, cccid) == 8, "Incorrect offset");
739_Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, datao) == 12, "Incorrect offset");
740_Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, datal) == 16, "Incorrect offset");
741
742#define NVME_TCP_C2H_DATA_FLAGS_SUCCESS (1u << 3)
743#define NVME_TCP_C2H_DATA_FLAGS_LAST_PDU (1u << 2)
744#define NVME_TCP_C2H_DATA_PDO_MULT 8u
745
746/**
747 * R2T
748 *
749 * common.pdu_type == NVME_TCP_PDU_TYPE_R2T
750 */
751struct nvme_tcp_r2t_hdr {
752 struct nvme_tcp_common_pdu_hdr common;
753 uint16_t cccid;
754 uint16_t ttag;
755 uint32_t r2to;
756 uint32_t r2tl;
757 uint8_t reserved20[4];
758};
759_Static_assert(sizeof(struct nvme_tcp_r2t_hdr) == 24, "Incorrect size");
760_Static_assert(offsetof(struct nvme_tcp_r2t_hdr, cccid) == 8, "Incorrect offset");
761_Static_assert(offsetof(struct nvme_tcp_r2t_hdr, ttag) == 10, "Incorrect offset");
762_Static_assert(offsetof(struct nvme_tcp_r2t_hdr, r2to) == 12, "Incorrect offset");
763_Static_assert(offsetof(struct nvme_tcp_r2t_hdr, r2tl) == 16, "Incorrect offset");
764
765#endif /* __NVMF_PROTO_H__ */