16bf9d8f6SLeon Romanovsky /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2a4d61e84SRoland Dreier /* 3a4d61e84SRoland Dreier * Copyright (c) 2004 Topspin Corporation. All rights reserved. 4a4d61e84SRoland Dreier */ 5a4d61e84SRoland Dreier 6a4d61e84SRoland Dreier #ifndef IB_PACK_H 7a4d61e84SRoland Dreier #define IB_PACK_H 8a4d61e84SRoland Dreier 9a4d61e84SRoland Dreier #include <rdma/ib_verbs.h> 10dd5f03beSMatan Barak #include <uapi/linux/if_ether.h> 11a4d61e84SRoland Dreier 12a4d61e84SRoland Dreier enum { 13a4d61e84SRoland Dreier IB_LRH_BYTES = 8, 14ff7f5aabSEli Cohen IB_ETH_BYTES = 14, 15af7bd463SEli Cohen IB_VLAN_BYTES = 4, 16a4d61e84SRoland Dreier IB_GRH_BYTES = 40, 1725f40220SMoni Shoua IB_IP4_BYTES = 20, 1825f40220SMoni Shoua IB_UDP_BYTES = 8, 19a4d61e84SRoland Dreier IB_BTH_BYTES = 12, 2099260132SParav Pandit IB_DETH_BYTES = 8, 2199260132SParav Pandit IB_EXT_ATOMICETH_BYTES = 28, 2299260132SParav Pandit IB_EXT_XRC_BYTES = 4, 2399260132SParav Pandit IB_ICRC_BYTES = 4 24a4d61e84SRoland Dreier }; 25a4d61e84SRoland Dreier 26a4d61e84SRoland Dreier struct ib_field { 27a4d61e84SRoland Dreier size_t struct_offset_bytes; 28a4d61e84SRoland Dreier size_t struct_size_bytes; 29a4d61e84SRoland Dreier int offset_words; 30a4d61e84SRoland Dreier int offset_bits; 31a4d61e84SRoland Dreier int size_bits; 32a4d61e84SRoland Dreier char *field_name; 33a4d61e84SRoland Dreier }; 34a4d61e84SRoland Dreier 35a4d61e84SRoland Dreier #define RESERVED \ 36a4d61e84SRoland Dreier .field_name = "reserved" 37a4d61e84SRoland Dreier 38a4d61e84SRoland Dreier /* 39a4d61e84SRoland Dreier * This macro cleans up the definitions of constants for BTH opcodes. 40a4d61e84SRoland Dreier * It is used to define constants such as IB_OPCODE_UD_SEND_ONLY, 41a4d61e84SRoland Dreier * which becomes IB_OPCODE_UD + IB_OPCODE_SEND_ONLY, and this gives 42a4d61e84SRoland Dreier * the correct value. 43a4d61e84SRoland Dreier * 44a4d61e84SRoland Dreier * In short, user code should use the constants defined using the 45a4d61e84SRoland Dreier * macro rather than worrying about adding together other constants. 46a4d61e84SRoland Dreier */ 47a4d61e84SRoland Dreier #define IB_OPCODE(transport, op) \ 48a4d61e84SRoland Dreier IB_OPCODE_ ## transport ## _ ## op = \ 49a4d61e84SRoland Dreier IB_OPCODE_ ## transport + IB_OPCODE_ ## op 50a4d61e84SRoland Dreier 51a4d61e84SRoland Dreier enum { 52a4d61e84SRoland Dreier /* transport types -- just used to define real constants */ 53a4d61e84SRoland Dreier IB_OPCODE_RC = 0x00, 54a4d61e84SRoland Dreier IB_OPCODE_UC = 0x20, 55a4d61e84SRoland Dreier IB_OPCODE_RD = 0x40, 56a4d61e84SRoland Dreier IB_OPCODE_UD = 0x60, 57931cf9a3SHal Rosenstock /* per IBTA 1.3 vol 1 Table 38, A10.3.2 */ 58d4ab3470SDennis Dalessandro IB_OPCODE_CNP = 0x80, 59243d9f43SDon Hiatt /* Manufacturer specific */ 60243d9f43SDon Hiatt IB_OPCODE_MSP = 0xe0, 61a4d61e84SRoland Dreier 62a4d61e84SRoland Dreier /* operations -- just used to define real constants */ 63a4d61e84SRoland Dreier IB_OPCODE_SEND_FIRST = 0x00, 64a4d61e84SRoland Dreier IB_OPCODE_SEND_MIDDLE = 0x01, 65a4d61e84SRoland Dreier IB_OPCODE_SEND_LAST = 0x02, 66a4d61e84SRoland Dreier IB_OPCODE_SEND_LAST_WITH_IMMEDIATE = 0x03, 67a4d61e84SRoland Dreier IB_OPCODE_SEND_ONLY = 0x04, 68a4d61e84SRoland Dreier IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE = 0x05, 69a4d61e84SRoland Dreier IB_OPCODE_RDMA_WRITE_FIRST = 0x06, 70a4d61e84SRoland Dreier IB_OPCODE_RDMA_WRITE_MIDDLE = 0x07, 71a4d61e84SRoland Dreier IB_OPCODE_RDMA_WRITE_LAST = 0x08, 72a4d61e84SRoland Dreier IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE = 0x09, 73a4d61e84SRoland Dreier IB_OPCODE_RDMA_WRITE_ONLY = 0x0a, 74a4d61e84SRoland Dreier IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE = 0x0b, 75a4d61e84SRoland Dreier IB_OPCODE_RDMA_READ_REQUEST = 0x0c, 76a4d61e84SRoland Dreier IB_OPCODE_RDMA_READ_RESPONSE_FIRST = 0x0d, 77a4d61e84SRoland Dreier IB_OPCODE_RDMA_READ_RESPONSE_MIDDLE = 0x0e, 78a4d61e84SRoland Dreier IB_OPCODE_RDMA_READ_RESPONSE_LAST = 0x0f, 79a4d61e84SRoland Dreier IB_OPCODE_RDMA_READ_RESPONSE_ONLY = 0x10, 80a4d61e84SRoland Dreier IB_OPCODE_ACKNOWLEDGE = 0x11, 81a4d61e84SRoland Dreier IB_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12, 82a4d61e84SRoland Dreier IB_OPCODE_COMPARE_SWAP = 0x13, 83a4d61e84SRoland Dreier IB_OPCODE_FETCH_ADD = 0x14, 84bf77cc34SJianxin Xiong /* opcode 0x15 is reserved */ 85bf77cc34SJianxin Xiong IB_OPCODE_SEND_LAST_WITH_INVALIDATE = 0x16, 86bf77cc34SJianxin Xiong IB_OPCODE_SEND_ONLY_WITH_INVALIDATE = 0x17, 87*208e3a13SLi Zhijian IB_OPCODE_FLUSH = 0x1C, 883ff81e82SXiao Yang IB_OPCODE_ATOMIC_WRITE = 0x1D, 89a4d61e84SRoland Dreier 90a4d61e84SRoland Dreier /* real constants follow -- see comment about above IB_OPCODE() 91a4d61e84SRoland Dreier macro for more details */ 92a4d61e84SRoland Dreier 93a4d61e84SRoland Dreier /* RC */ 94a4d61e84SRoland Dreier IB_OPCODE(RC, SEND_FIRST), 95a4d61e84SRoland Dreier IB_OPCODE(RC, SEND_MIDDLE), 96a4d61e84SRoland Dreier IB_OPCODE(RC, SEND_LAST), 97a4d61e84SRoland Dreier IB_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE), 98a4d61e84SRoland Dreier IB_OPCODE(RC, SEND_ONLY), 99a4d61e84SRoland Dreier IB_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE), 100a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_WRITE_FIRST), 101a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_WRITE_MIDDLE), 102a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_WRITE_LAST), 103a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 104a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_WRITE_ONLY), 105a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 106a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_READ_REQUEST), 107a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_READ_RESPONSE_FIRST), 108a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE), 109a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_READ_RESPONSE_LAST), 110a4d61e84SRoland Dreier IB_OPCODE(RC, RDMA_READ_RESPONSE_ONLY), 111a4d61e84SRoland Dreier IB_OPCODE(RC, ACKNOWLEDGE), 112a4d61e84SRoland Dreier IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE), 113a4d61e84SRoland Dreier IB_OPCODE(RC, COMPARE_SWAP), 114a4d61e84SRoland Dreier IB_OPCODE(RC, FETCH_ADD), 115bf77cc34SJianxin Xiong IB_OPCODE(RC, SEND_LAST_WITH_INVALIDATE), 116bf77cc34SJianxin Xiong IB_OPCODE(RC, SEND_ONLY_WITH_INVALIDATE), 117*208e3a13SLi Zhijian IB_OPCODE(RC, FLUSH), 1183ff81e82SXiao Yang IB_OPCODE(RC, ATOMIC_WRITE), 119a4d61e84SRoland Dreier 120a4d61e84SRoland Dreier /* UC */ 121a4d61e84SRoland Dreier IB_OPCODE(UC, SEND_FIRST), 122a4d61e84SRoland Dreier IB_OPCODE(UC, SEND_MIDDLE), 123a4d61e84SRoland Dreier IB_OPCODE(UC, SEND_LAST), 124a4d61e84SRoland Dreier IB_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE), 125a4d61e84SRoland Dreier IB_OPCODE(UC, SEND_ONLY), 126a4d61e84SRoland Dreier IB_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE), 127a4d61e84SRoland Dreier IB_OPCODE(UC, RDMA_WRITE_FIRST), 128a4d61e84SRoland Dreier IB_OPCODE(UC, RDMA_WRITE_MIDDLE), 129a4d61e84SRoland Dreier IB_OPCODE(UC, RDMA_WRITE_LAST), 130a4d61e84SRoland Dreier IB_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 131a4d61e84SRoland Dreier IB_OPCODE(UC, RDMA_WRITE_ONLY), 132a4d61e84SRoland Dreier IB_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 133a4d61e84SRoland Dreier 134a4d61e84SRoland Dreier /* RD */ 135a4d61e84SRoland Dreier IB_OPCODE(RD, SEND_FIRST), 136a4d61e84SRoland Dreier IB_OPCODE(RD, SEND_MIDDLE), 137a4d61e84SRoland Dreier IB_OPCODE(RD, SEND_LAST), 138a4d61e84SRoland Dreier IB_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE), 139a4d61e84SRoland Dreier IB_OPCODE(RD, SEND_ONLY), 140a4d61e84SRoland Dreier IB_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE), 141a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_WRITE_FIRST), 142a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_WRITE_MIDDLE), 143a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_WRITE_LAST), 144a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE), 145a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_WRITE_ONLY), 146a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 147a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_READ_REQUEST), 148a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_READ_RESPONSE_FIRST), 149a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE), 150a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_READ_RESPONSE_LAST), 151a4d61e84SRoland Dreier IB_OPCODE(RD, RDMA_READ_RESPONSE_ONLY), 152a4d61e84SRoland Dreier IB_OPCODE(RD, ACKNOWLEDGE), 153a4d61e84SRoland Dreier IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE), 154a4d61e84SRoland Dreier IB_OPCODE(RD, COMPARE_SWAP), 155a4d61e84SRoland Dreier IB_OPCODE(RD, FETCH_ADD), 156*208e3a13SLi Zhijian IB_OPCODE(RD, FLUSH), 157a4d61e84SRoland Dreier 158a4d61e84SRoland Dreier /* UD */ 159a4d61e84SRoland Dreier IB_OPCODE(UD, SEND_ONLY), 160a4d61e84SRoland Dreier IB_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE) 161a4d61e84SRoland Dreier }; 162a4d61e84SRoland Dreier 163a4d61e84SRoland Dreier enum { 164a4d61e84SRoland Dreier IB_LNH_RAW = 0, 165a4d61e84SRoland Dreier IB_LNH_IP = 1, 166a4d61e84SRoland Dreier IB_LNH_IBA_LOCAL = 2, 167a4d61e84SRoland Dreier IB_LNH_IBA_GLOBAL = 3 168a4d61e84SRoland Dreier }; 169a4d61e84SRoland Dreier 170a4d61e84SRoland Dreier struct ib_unpacked_lrh { 171a4d61e84SRoland Dreier u8 virtual_lane; 172a4d61e84SRoland Dreier u8 link_version; 173a4d61e84SRoland Dreier u8 service_level; 174a4d61e84SRoland Dreier u8 link_next_header; 175a4d61e84SRoland Dreier __be16 destination_lid; 176a4d61e84SRoland Dreier __be16 packet_length; 177a4d61e84SRoland Dreier __be16 source_lid; 178a4d61e84SRoland Dreier }; 179a4d61e84SRoland Dreier 180a4d61e84SRoland Dreier struct ib_unpacked_grh { 181a4d61e84SRoland Dreier u8 ip_version; 182a4d61e84SRoland Dreier u8 traffic_class; 183a4d61e84SRoland Dreier __be32 flow_label; 184a4d61e84SRoland Dreier __be16 payload_length; 185a4d61e84SRoland Dreier u8 next_header; 186a4d61e84SRoland Dreier u8 hop_limit; 187a4d61e84SRoland Dreier union ib_gid source_gid; 188a4d61e84SRoland Dreier union ib_gid destination_gid; 189a4d61e84SRoland Dreier }; 190a4d61e84SRoland Dreier 191a4d61e84SRoland Dreier struct ib_unpacked_bth { 192a4d61e84SRoland Dreier u8 opcode; 193a4d61e84SRoland Dreier u8 solicited_event; 194a4d61e84SRoland Dreier u8 mig_req; 195a4d61e84SRoland Dreier u8 pad_count; 196a4d61e84SRoland Dreier u8 transport_header_version; 197a4d61e84SRoland Dreier __be16 pkey; 198a4d61e84SRoland Dreier __be32 destination_qpn; 199a4d61e84SRoland Dreier u8 ack_req; 200a4d61e84SRoland Dreier __be32 psn; 201a4d61e84SRoland Dreier }; 202a4d61e84SRoland Dreier 203a4d61e84SRoland Dreier struct ib_unpacked_deth { 204a4d61e84SRoland Dreier __be32 qkey; 205a4d61e84SRoland Dreier __be32 source_qpn; 206a4d61e84SRoland Dreier }; 207a4d61e84SRoland Dreier 208ff7f5aabSEli Cohen struct ib_unpacked_eth { 209ff7f5aabSEli Cohen u8 dmac_h[4]; 210ff7f5aabSEli Cohen u8 dmac_l[2]; 211ff7f5aabSEli Cohen u8 smac_h[2]; 212ff7f5aabSEli Cohen u8 smac_l[4]; 213ff7f5aabSEli Cohen __be16 type; 214ff7f5aabSEli Cohen }; 215ff7f5aabSEli Cohen 21625f40220SMoni Shoua struct ib_unpacked_ip4 { 21725f40220SMoni Shoua u8 ver; 21825f40220SMoni Shoua u8 hdr_len; 21925f40220SMoni Shoua u8 tos; 22025f40220SMoni Shoua __be16 tot_len; 22125f40220SMoni Shoua __be16 id; 22225f40220SMoni Shoua __be16 frag_off; 22325f40220SMoni Shoua u8 ttl; 22425f40220SMoni Shoua u8 protocol; 2253ef967a4SMoni Shoua __sum16 check; 22625f40220SMoni Shoua __be32 saddr; 22725f40220SMoni Shoua __be32 daddr; 22825f40220SMoni Shoua }; 22925f40220SMoni Shoua 23025f40220SMoni Shoua struct ib_unpacked_udp { 23125f40220SMoni Shoua __be16 sport; 23225f40220SMoni Shoua __be16 dport; 23325f40220SMoni Shoua __be16 length; 23425f40220SMoni Shoua __be16 csum; 23525f40220SMoni Shoua }; 23625f40220SMoni Shoua 237af7bd463SEli Cohen struct ib_unpacked_vlan { 238af7bd463SEli Cohen __be16 tag; 239af7bd463SEli Cohen __be16 type; 240af7bd463SEli Cohen }; 241af7bd463SEli Cohen 242a4d61e84SRoland Dreier struct ib_ud_header { 243ff7f5aabSEli Cohen int lrh_present; 244a4d61e84SRoland Dreier struct ib_unpacked_lrh lrh; 245ff7f5aabSEli Cohen int eth_present; 246ff7f5aabSEli Cohen struct ib_unpacked_eth eth; 247af7bd463SEli Cohen int vlan_present; 248af7bd463SEli Cohen struct ib_unpacked_vlan vlan; 249a4d61e84SRoland Dreier int grh_present; 250a4d61e84SRoland Dreier struct ib_unpacked_grh grh; 25125f40220SMoni Shoua int ipv4_present; 25225f40220SMoni Shoua struct ib_unpacked_ip4 ip4; 25325f40220SMoni Shoua int udp_present; 25425f40220SMoni Shoua struct ib_unpacked_udp udp; 255a4d61e84SRoland Dreier struct ib_unpacked_bth bth; 256a4d61e84SRoland Dreier struct ib_unpacked_deth deth; 257a4d61e84SRoland Dreier int immediate_present; 258a4d61e84SRoland Dreier __be32 immediate_data; 259a4d61e84SRoland Dreier }; 260a4d61e84SRoland Dreier 261a4d61e84SRoland Dreier void ib_pack(const struct ib_field *desc, 262a4d61e84SRoland Dreier int desc_len, 263a4d61e84SRoland Dreier void *structure, 264a4d61e84SRoland Dreier void *buf); 265a4d61e84SRoland Dreier 266a4d61e84SRoland Dreier void ib_unpack(const struct ib_field *desc, 267a4d61e84SRoland Dreier int desc_len, 268a4d61e84SRoland Dreier void *buf, 269a4d61e84SRoland Dreier void *structure); 270a4d61e84SRoland Dreier 2713ef967a4SMoni Shoua __sum16 ib_ud_ip4_csum(struct ib_ud_header *header); 27225f40220SMoni Shoua 27325f40220SMoni Shoua int ib_ud_header_init(int payload_bytes, 274ff7f5aabSEli Cohen int lrh_present, 275ff7f5aabSEli Cohen int eth_present, 276af7bd463SEli Cohen int vlan_present, 277a4d61e84SRoland Dreier int grh_present, 27825f40220SMoni Shoua int ip_version, 27925f40220SMoni Shoua int udp_present, 280920d706cSEli Cohen int immediate_present, 281a4d61e84SRoland Dreier struct ib_ud_header *header); 282a4d61e84SRoland Dreier 283a4d61e84SRoland Dreier int ib_ud_header_pack(struct ib_ud_header *header, 284a4d61e84SRoland Dreier void *buf); 285a4d61e84SRoland Dreier 286a4d61e84SRoland Dreier int ib_ud_header_unpack(void *buf, 287a4d61e84SRoland Dreier struct ib_ud_header *header); 288a4d61e84SRoland Dreier 289a4d61e84SRoland Dreier #endif /* IB_PACK_H */ 290