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