/* SPDX-License-Identifier: BSD-3-Clause * Copyright (C) 2016 Intel Corporation. * All rights reserved. */ /* Derived from include/spdk/nvmf_spec.h from Intel's SPDK. */ #ifndef __NVMF_PROTO_H__ #define __NVMF_PROTO_H__ #include #include #ifdef _KERNEL #include #else #include #endif #include /** * \file * NVMe over Fabrics specification definitions */ #define NVME_NQN_FIELD_SIZE 256 struct nvmf_capsule_cmd { uint8_t opcode; uint8_t reserved1; uint16_t cid; uint8_t fctype; uint8_t reserved2[35]; uint8_t fabric_specific[24]; }; _Static_assert(sizeof(struct nvmf_capsule_cmd) == 64, "Incorrect size"); /* Fabric Command Set */ enum nvmf_fabric_cmd_types { NVMF_FABRIC_COMMAND_PROPERTY_SET = 0x00, NVMF_FABRIC_COMMAND_CONNECT = 0x01, NVMF_FABRIC_COMMAND_PROPERTY_GET = 0x04, NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND = 0x05, NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV = 0x06, NVMF_FABRIC_COMMAND_DISCONNECT = 0x08, NVMF_FABRIC_COMMAND_START_VENDOR_SPECIFIC = 0xC0, }; enum nvmf_fabric_cmd_status_code { NVMF_FABRIC_SC_INCOMPATIBLE_FORMAT = 0x80, NVMF_FABRIC_SC_CONTROLLER_BUSY = 0x81, NVMF_FABRIC_SC_INVALID_PARAM = 0x82, NVMF_FABRIC_SC_RESTART_DISCOVERY = 0x83, NVMF_FABRIC_SC_INVALID_HOST = 0x84, NVMF_FABRIC_SC_INVALID_QUEUE_TYPE = 0x85, NVMF_FABRIC_SC_LOG_RESTART_DISCOVERY = 0x90, NVMF_FABRIC_SC_AUTH_REQUIRED = 0x91, }; /** * RDMA Queue Pair service types */ enum nvmf_rdma_qptype { /** Reliable connected */ NVMF_RDMA_QPTYPE_RELIABLE_CONNECTED = 0x1, /** Reliable datagram */ NVMF_RDMA_QPTYPE_RELIABLE_DATAGRAM = 0x2, }; /** * RDMA provider types */ enum nvmf_rdma_prtype { /** No provider specified */ NVMF_RDMA_PRTYPE_NONE = 0x1, /** InfiniBand */ NVMF_RDMA_PRTYPE_IB = 0x2, /** RoCE v1 */ NVMF_RDMA_PRTYPE_ROCE = 0x3, /** RoCE v2 */ NVMF_RDMA_PRTYPE_ROCE2 = 0x4, /** iWARP */ NVMF_RDMA_PRTYPE_IWARP = 0x5, }; /** * RDMA connection management service types */ enum nvmf_rdma_cms { /** Sockets based endpoint addressing */ NVMF_RDMA_CMS_RDMA_CM = 0x1, }; /** * NVMe over Fabrics transport types */ enum nvmf_trtype { /** RDMA */ NVMF_TRTYPE_RDMA = 0x1, /** Fibre Channel */ NVMF_TRTYPE_FC = 0x2, /** TCP */ NVMF_TRTYPE_TCP = 0x3, /** Intra-host transport (loopback) */ NVMF_TRTYPE_INTRA_HOST = 0xfe, }; /** * Address family types */ enum nvmf_adrfam { /** IPv4 (AF_INET) */ NVMF_ADRFAM_IPV4 = 0x1, /** IPv6 (AF_INET6) */ NVMF_ADRFAM_IPV6 = 0x2, /** InfiniBand (AF_IB) */ NVMF_ADRFAM_IB = 0x3, /** Fibre Channel address family */ NVMF_ADRFAM_FC = 0x4, /** Intra-host transport (loopback) */ NVMF_ADRFAM_INTRA_HOST = 0xfe, }; /** * NVM subsystem types */ enum nvmf_subtype { /** Referral to a discovery service */ NVMF_SUBTYPE_DISCOVERY = 0x1, /** NVM Subsystem */ NVMF_SUBTYPE_NVME = 0x2, /** Current Discovery Subsystem */ NVMF_SUBTYPE_DISCOVERY_CURRENT = 0x3 }; /* Discovery Log Entry Flags - Duplicate Returned Information */ #define NVMF_DISCOVERY_LOG_EFLAGS_DUPRETINFO (1u << 0u) /* Discovery Log Entry Flags - Explicit Persistent Connection Support for Discovery */ #define NVMF_DISCOVERY_LOG_EFLAGS_EPCSD (1u << 1u) /** * Connections shall be made over a fabric secure channel */ enum nvmf_treq_secure_channel { /** Not specified */ NVMF_TREQ_SECURE_CHANNEL_NOT_SPECIFIED = 0x0, /** Required */ NVMF_TREQ_SECURE_CHANNEL_REQUIRED = 0x1, /** Not required */ NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED = 0x2, }; struct nvmf_fabric_cmd { uint8_t opcode; uint8_t reserved1; uint16_t cid; uint8_t fctype; uint8_t reserved2[59]; } __aligned(8); struct nvmf_fabric_auth_recv_cmd { uint8_t opcode; uint8_t reserved1; uint16_t cid; uint8_t fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV (0x06) */ uint8_t reserved2[19]; struct nvme_sgl_descriptor sgl1; uint8_t reserved3; uint8_t spsp0; uint8_t spsp1; uint8_t secp; uint32_t al; uint8_t reserved4[16]; }; _Static_assert(sizeof(struct nvmf_fabric_auth_recv_cmd) == 64, "Incorrect size"); struct nvmf_fabric_auth_send_cmd { uint8_t opcode; uint8_t reserved1; uint16_t cid; uint8_t fctype; /* NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND (0x05) */ uint8_t reserved2[19]; struct nvme_sgl_descriptor sgl1; uint8_t reserved3; uint8_t spsp0; uint8_t spsp1; uint8_t secp; uint32_t tl; uint8_t reserved4[16]; }; _Static_assert(sizeof(struct nvmf_fabric_auth_send_cmd) == 64, "Incorrect size"); struct nvmf_fabric_connect_data { uint8_t hostid[16]; uint16_t cntlid; uint8_t reserved5[238]; uint8_t subnqn[NVME_NQN_FIELD_SIZE]; uint8_t hostnqn[NVME_NQN_FIELD_SIZE]; uint8_t reserved6[256]; }; _Static_assert(sizeof(struct nvmf_fabric_connect_data) == 1024, "Incorrect size"); struct nvmf_fabric_connect_cmd { uint8_t opcode; uint8_t reserved1; uint16_t cid; uint8_t fctype; uint8_t reserved2[19]; struct nvme_sgl_descriptor sgl1; uint16_t recfmt; /* Connect Record Format */ uint16_t qid; /* Queue Identifier */ uint16_t sqsize; /* Submission Queue Size */ uint8_t cattr; /* queue attributes */ uint8_t reserved3; uint32_t kato; /* keep alive timeout */ uint8_t reserved4[12]; }; _Static_assert(sizeof(struct nvmf_fabric_connect_cmd) == 64, "Incorrect size"); #define NVMF_CNTLID_DYNAMIC 0xFFFF #define NVMF_CNTLID_STATIC_ANY 0xFFFE /* * XXX: 5.3 in NVMe-over-Fabrics 1.1 gives this as an upper bound in * the Discovery Log Entry. */ #define NVMF_CNTLID_STATIC_MAX 0xFFEF /* 5.21.1.15 in NVMe 1.4b */ #define NVMF_KATO_DEFAULT (120000) #define NVMF_CONNECT_ATTR_PRIORITY_CLASS (0x3) #define NVMF_CONNECT_ATTR_DISABLE_SQ_FC (1u << 2) #define NVMF_CONNECT_ATTR_IO_QUEUE_DELETION (1u << 3) struct nvmf_fabric_connect_rsp { union { struct { uint16_t cntlid; uint16_t authreq; } success; struct { uint16_t ipo; uint8_t iattr; uint8_t reserved; } invalid; uint32_t raw; } status_code_specific; uint32_t reserved0; uint16_t sqhd; uint16_t reserved1; uint16_t cid; uint16_t status; }; _Static_assert(sizeof(struct nvmf_fabric_connect_rsp) == 16, "Incorrect size"); struct nvmf_fabric_disconnect_cmd { uint8_t opcode; uint8_t reserved1; uint16_t cid; uint8_t fctype; uint8_t reserved2[19]; struct nvme_sgl_descriptor sgl1; uint16_t recfmt; /* Disconnect Record Format */ uint8_t reserved3[22]; }; _Static_assert(sizeof(struct nvmf_fabric_disconnect_cmd) == 64, "Incorrect size"); #define NVMF_PROP_SIZE_4 0 #define NVMF_PROP_SIZE_8 1 #define NVMF_PROP_CAP 0x00 /* Controller Capabilities */ #define NVMF_PROP_VS 0x08 /* Version */ #define NVMF_PROP_CC 0x14 /* Controller Configuration */ #define NVMF_PROP_CSTS 0x1C /* Controller Status */ #define NVMF_PROP_NSSR 0x20 /* NVM Subsystem Reset */ struct nvmf_fabric_prop_get_cmd { uint8_t opcode; uint8_t reserved1; uint16_t cid; uint8_t fctype; uint8_t reserved2[35]; struct { uint8_t size : 3; uint8_t reserved : 5; } attrib; uint8_t reserved3[3]; uint32_t ofst; uint8_t reserved4[16]; }; _Static_assert(sizeof(struct nvmf_fabric_prop_get_cmd) == 64, "Incorrect size"); struct nvmf_fabric_prop_get_rsp { union { uint64_t u64; struct { uint32_t low; uint32_t high; } u32; } value; uint16_t sqhd; uint16_t reserved0; uint16_t cid; uint16_t status; }; _Static_assert(sizeof(struct nvmf_fabric_prop_get_rsp) == 16, "Incorrect size"); struct nvmf_fabric_prop_set_cmd { uint8_t opcode; uint8_t reserved0; uint16_t cid; uint8_t fctype; uint8_t reserved1[35]; struct { uint8_t size : 3; uint8_t reserved : 5; } attrib; uint8_t reserved2[3]; uint32_t ofst; union { uint64_t u64; struct { uint32_t low; uint32_t high; } u32; } value; uint8_t reserved4[8]; }; _Static_assert(sizeof(struct nvmf_fabric_prop_set_cmd) == 64, "Incorrect size"); #define NVMF_NQN_MIN_LEN 11 /* The prefix in the spec is 11 characters */ #define NVMF_NQN_MAX_LEN 223 #define NVMF_NQN_UUID_PRE_LEN 32 #define NVMF_UUID_STRING_LEN 36 #define NVMF_NQN_UUID_PRE "nqn.2014-08.org.nvmexpress:uuid:" #define NVMF_DISCOVERY_NQN "nqn.2014-08.org.nvmexpress.discovery" #define NVMF_TRSTRING_MAX_LEN 32 #define NVMF_TRADDR_MAX_LEN 256 #define NVMF_TRSVCID_MAX_LEN 32 /** RDMA transport-specific address subtype */ struct nvmf_rdma_transport_specific_address_subtype { /** RDMA QP service type (\ref nvmf_rdma_qptype) */ uint8_t rdma_qptype; /** RDMA provider type (\ref nvmf_rdma_prtype) */ uint8_t rdma_prtype; /** RDMA connection management service (\ref nvmf_rdma_cms) */ uint8_t rdma_cms; uint8_t reserved0[5]; /** RDMA partition key for AF_IB */ uint16_t rdma_pkey; uint8_t reserved2[246]; }; _Static_assert(sizeof(struct nvmf_rdma_transport_specific_address_subtype) == 256, "Incorrect size"); /** TCP Secure Socket Type */ enum nvme_tcp_secure_socket_type { /** No security */ NVME_TCP_SECURITY_NONE = 0, /** TLS (Secure Sockets) version 1.2 */ NVME_TCP_SECURITY_TLS_1_2 = 1, /** TLS (Secure Sockets) version 1.3 */ NVME_TCP_SECURITY_TLS_1_3 = 2, }; /** TCP transport-specific address subtype */ struct nvme_tcp_transport_specific_address_subtype { /** Security type (\ref nvme_tcp_secure_socket_type) */ uint8_t sectype; uint8_t reserved0[255]; }; _Static_assert(sizeof(struct nvme_tcp_transport_specific_address_subtype) == 256, "Incorrect size"); /** Transport-specific address subtype */ union nvmf_transport_specific_address_subtype { uint8_t raw[256]; /** RDMA */ struct nvmf_rdma_transport_specific_address_subtype rdma; /** TCP */ struct nvme_tcp_transport_specific_address_subtype tcp; }; _Static_assert(sizeof(union nvmf_transport_specific_address_subtype) == 256, "Incorrect size"); #define NVMF_MIN_ADMIN_MAX_SQ_SIZE 32 /** * Discovery Log Page entry */ struct nvmf_discovery_log_page_entry { /** Transport type (\ref nvmf_trtype) */ uint8_t trtype; /** Address family (\ref nvmf_adrfam) */ uint8_t adrfam; /** Subsystem type (\ref nvmf_subtype) */ uint8_t subtype; /** Transport requirements */ struct { /** Secure channel requirements (\ref nvmf_treq_secure_channel) */ uint8_t secure_channel : 2; uint8_t reserved : 6; } treq; /** NVM subsystem port ID */ uint16_t portid; /** Controller ID */ uint16_t cntlid; /** Admin max SQ size */ uint16_t asqsz; /** Entry Flags */ uint16_t eflags; uint8_t reserved0[20]; /** Transport service identifier */ uint8_t trsvcid[NVMF_TRSVCID_MAX_LEN]; uint8_t reserved1[192]; /** NVM subsystem qualified name */ uint8_t subnqn[256]; /** Transport address */ uint8_t traddr[NVMF_TRADDR_MAX_LEN]; /** Transport-specific address subtype */ union nvmf_transport_specific_address_subtype tsas; }; _Static_assert(sizeof(struct nvmf_discovery_log_page_entry) == 1024, "Incorrect size"); struct nvmf_discovery_log_page { uint64_t genctr; uint64_t numrec; uint16_t recfmt; uint8_t reserved0[1006]; struct nvmf_discovery_log_page_entry entries[0]; }; _Static_assert(sizeof(struct nvmf_discovery_log_page) == 1024, "Incorrect size"); /* RDMA Fabric specific definitions below */ #define NVME_SGL_SUBTYPE_INVALIDATE_KEY 0xF struct nvmf_rdma_request_private_data { uint16_t recfmt; /* record format */ uint16_t qid; /* queue id */ uint16_t hrqsize; /* host receive queue size */ uint16_t hsqsize; /* host send queue size */ uint16_t cntlid; /* controller id */ uint8_t reserved[22]; }; _Static_assert(sizeof(struct nvmf_rdma_request_private_data) == 32, "Incorrect size"); struct nvmf_rdma_accept_private_data { uint16_t recfmt; /* record format */ uint16_t crqsize; /* controller receive queue size */ uint8_t reserved[28]; }; _Static_assert(sizeof(struct nvmf_rdma_accept_private_data) == 32, "Incorrect size"); struct nvmf_rdma_reject_private_data { uint16_t recfmt; /* record format */ uint16_t sts; /* status */ }; _Static_assert(sizeof(struct nvmf_rdma_reject_private_data) == 4, "Incorrect size"); union nvmf_rdma_private_data { struct nvmf_rdma_request_private_data pd_request; struct nvmf_rdma_accept_private_data pd_accept; struct nvmf_rdma_reject_private_data pd_reject; }; _Static_assert(sizeof(union nvmf_rdma_private_data) == 32, "Incorrect size"); enum nvmf_rdma_transport_error { NVMF_RDMA_ERROR_INVALID_PRIVATE_DATA_LENGTH = 0x1, NVMF_RDMA_ERROR_INVALID_RECFMT = 0x2, NVMF_RDMA_ERROR_INVALID_QID = 0x3, NVMF_RDMA_ERROR_INVALID_HSQSIZE = 0x4, NVMF_RDMA_ERROR_INVALID_HRQSIZE = 0x5, NVMF_RDMA_ERROR_NO_RESOURCES = 0x6, NVMF_RDMA_ERROR_INVALID_IRD = 0x7, NVMF_RDMA_ERROR_INVALID_ORD = 0x8, }; /* TCP transport specific definitions below */ /** NVMe/TCP PDU type */ enum nvme_tcp_pdu_type { /** Initialize Connection Request (ICReq) */ NVME_TCP_PDU_TYPE_IC_REQ = 0x00, /** Initialize Connection Response (ICResp) */ NVME_TCP_PDU_TYPE_IC_RESP = 0x01, /** Terminate Connection Request (TermReq) */ NVME_TCP_PDU_TYPE_H2C_TERM_REQ = 0x02, /** Terminate Connection Response (TermResp) */ NVME_TCP_PDU_TYPE_C2H_TERM_REQ = 0x03, /** Command Capsule (CapsuleCmd) */ NVME_TCP_PDU_TYPE_CAPSULE_CMD = 0x04, /** Response Capsule (CapsuleRsp) */ NVME_TCP_PDU_TYPE_CAPSULE_RESP = 0x05, /** Host To Controller Data (H2CData) */ NVME_TCP_PDU_TYPE_H2C_DATA = 0x06, /** Controller To Host Data (C2HData) */ NVME_TCP_PDU_TYPE_C2H_DATA = 0x07, /** Ready to Transfer (R2T) */ NVME_TCP_PDU_TYPE_R2T = 0x09, }; /** Common NVMe/TCP PDU header */ struct nvme_tcp_common_pdu_hdr { /** PDU type (\ref nvme_tcp_pdu_type) */ uint8_t pdu_type; /** pdu_type-specific flags */ uint8_t flags; /** Length of PDU header (not including the Header Digest) */ uint8_t hlen; /** PDU Data Offset from the start of the PDU */ uint8_t pdo; /** Total number of bytes in PDU, including pdu_hdr */ uint32_t plen; }; _Static_assert(sizeof(struct nvme_tcp_common_pdu_hdr) == 8, "Incorrect size"); _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, pdu_type) == 0, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, flags) == 1, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, hlen) == 2, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, pdo) == 3, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_common_pdu_hdr, plen) == 4, "Incorrect offset"); #define NVME_TCP_CH_FLAGS_HDGSTF (1u << 0) #define NVME_TCP_CH_FLAGS_DDGSTF (1u << 1) /** * ICReq * * common.pdu_type == NVME_TCP_PDU_TYPE_IC_REQ */ struct nvme_tcp_ic_req { struct nvme_tcp_common_pdu_hdr common; uint16_t pfv; /** Specifies the data alignment for all PDUs transferred from the controller to the host that contain data */ uint8_t hpda; union { uint8_t raw; struct { uint8_t hdgst_enable : 1; uint8_t ddgst_enable : 1; uint8_t reserved : 6; } bits; } dgst; uint32_t maxr2t; uint8_t reserved16[112]; }; _Static_assert(sizeof(struct nvme_tcp_ic_req) == 128, "Incorrect size"); _Static_assert(offsetof(struct nvme_tcp_ic_req, pfv) == 8, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_ic_req, hpda) == 10, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_ic_req, maxr2t) == 12, "Incorrect offset"); #define NVME_TCP_HPDA_MAX 31 #define NVME_TCP_CPDA_MAX 31 #define NVME_TCP_PDU_PDO_MAX_OFFSET ((NVME_TCP_CPDA_MAX + 1) << 2) /** * ICResp * * common.pdu_type == NVME_TCP_PDU_TYPE_IC_RESP */ struct nvme_tcp_ic_resp { struct nvme_tcp_common_pdu_hdr common; uint16_t pfv; /** Specifies the data alignment for all PDUs transferred from the host to the controller that contain data */ uint8_t cpda; union { uint8_t raw; struct { uint8_t hdgst_enable : 1; uint8_t ddgst_enable : 1; uint8_t reserved : 6; } bits; } dgst; /** Specifies the maximum number of PDU-Data bytes per H2C Data Transfer PDU */ uint32_t maxh2cdata; uint8_t reserved16[112]; }; _Static_assert(sizeof(struct nvme_tcp_ic_resp) == 128, "Incorrect size"); _Static_assert(offsetof(struct nvme_tcp_ic_resp, pfv) == 8, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_ic_resp, cpda) == 10, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_ic_resp, maxh2cdata) == 12, "Incorrect offset"); /** * TermReq * * common.pdu_type == NVME_TCP_PDU_TYPE_TERM_REQ */ struct nvme_tcp_term_req_hdr { struct nvme_tcp_common_pdu_hdr common; uint16_t fes; uint8_t fei[4]; uint8_t reserved14[10]; }; _Static_assert(sizeof(struct nvme_tcp_term_req_hdr) == 24, "Incorrect size"); _Static_assert(offsetof(struct nvme_tcp_term_req_hdr, fes) == 8, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_term_req_hdr, fei) == 10, "Incorrect offset"); enum nvme_tcp_term_req_fes { NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD = 0x01, NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR = 0x02, NVME_TCP_TERM_REQ_FES_HDGST_ERROR = 0x03, NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE = 0x04, NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_LIMIT_EXCEEDED = 0x05, NVME_TCP_TERM_REQ_FES_R2T_LIMIT_EXCEEDED = 0x05, NVME_TCP_TERM_REQ_FES_INVALID_DATA_UNSUPPORTED_PARAMETER = 0x06, }; /* Total length of term req PDU (including PDU header and DATA) in bytes shall not exceed a limit of 152 bytes. */ #define NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE 128 #define NVME_TCP_TERM_REQ_PDU_MAX_SIZE (NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE + sizeof(struct nvme_tcp_term_req_hdr)) /** * CapsuleCmd * * common.pdu_type == NVME_TCP_PDU_TYPE_CAPSULE_CMD */ struct nvme_tcp_cmd { struct nvme_tcp_common_pdu_hdr common; struct nvme_command ccsqe; /**< icdoff hdgst padding + in-capsule data + ddgst (if enabled) */ }; _Static_assert(sizeof(struct nvme_tcp_cmd) == 72, "Incorrect size"); _Static_assert(offsetof(struct nvme_tcp_cmd, ccsqe) == 8, "Incorrect offset"); /** * CapsuleResp * * common.pdu_type == NVME_TCP_PDU_TYPE_CAPSULE_RESP */ struct nvme_tcp_rsp { struct nvme_tcp_common_pdu_hdr common; struct nvme_completion rccqe; }; _Static_assert(sizeof(struct nvme_tcp_rsp) == 24, "incorrect size"); _Static_assert(offsetof(struct nvme_tcp_rsp, rccqe) == 8, "Incorrect offset"); /** * H2CData * * hdr.pdu_type == NVME_TCP_PDU_TYPE_H2C_DATA */ struct nvme_tcp_h2c_data_hdr { struct nvme_tcp_common_pdu_hdr common; uint16_t cccid; uint16_t ttag; uint32_t datao; uint32_t datal; uint8_t reserved20[4]; }; _Static_assert(sizeof(struct nvme_tcp_h2c_data_hdr) == 24, "Incorrect size"); _Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, cccid) == 8, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, ttag) == 10, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, datao) == 12, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_h2c_data_hdr, datal) == 16, "Incorrect offset"); #define NVME_TCP_H2C_DATA_FLAGS_LAST_PDU (1u << 2) #define NVME_TCP_H2C_DATA_FLAGS_SUCCESS (1u << 3) #define NVME_TCP_H2C_DATA_PDO_MULT 8u /** * C2HData * * hdr.pdu_type == NVME_TCP_PDU_TYPE_C2H_DATA */ struct nvme_tcp_c2h_data_hdr { struct nvme_tcp_common_pdu_hdr common; uint16_t cccid; uint8_t reserved10[2]; uint32_t datao; uint32_t datal; uint8_t reserved20[4]; }; _Static_assert(sizeof(struct nvme_tcp_c2h_data_hdr) == 24, "Incorrect size"); _Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, cccid) == 8, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, datao) == 12, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_c2h_data_hdr, datal) == 16, "Incorrect offset"); #define NVME_TCP_C2H_DATA_FLAGS_SUCCESS (1u << 3) #define NVME_TCP_C2H_DATA_FLAGS_LAST_PDU (1u << 2) #define NVME_TCP_C2H_DATA_PDO_MULT 8u /** * R2T * * common.pdu_type == NVME_TCP_PDU_TYPE_R2T */ struct nvme_tcp_r2t_hdr { struct nvme_tcp_common_pdu_hdr common; uint16_t cccid; uint16_t ttag; uint32_t r2to; uint32_t r2tl; uint8_t reserved20[4]; }; _Static_assert(sizeof(struct nvme_tcp_r2t_hdr) == 24, "Incorrect size"); _Static_assert(offsetof(struct nvme_tcp_r2t_hdr, cccid) == 8, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_r2t_hdr, ttag) == 10, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_r2t_hdr, r2to) == 12, "Incorrect offset"); _Static_assert(offsetof(struct nvme_tcp_r2t_hdr, r2tl) == 16, "Incorrect offset"); #endif /* __NVMF_PROTO_H__ */