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