1 /* 2 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33 #ifndef IB_PACK_H 34 #define IB_PACK_H 35 36 #include <rdma/ib_verbs.h> 37 38 enum { 39 IB_LRH_BYTES = 8, 40 IB_GRH_BYTES = 40, 41 IB_BTH_BYTES = 12, 42 IB_DETH_BYTES = 8 43 }; 44 45 struct ib_field { 46 size_t struct_offset_bytes; 47 size_t struct_size_bytes; 48 int offset_words; 49 int offset_bits; 50 int size_bits; 51 char *field_name; 52 }; 53 54 #define RESERVED \ 55 .field_name = "reserved" 56 57 /* 58 * This macro cleans up the definitions of constants for BTH opcodes. 59 * It is used to define constants such as IB_OPCODE_UD_SEND_ONLY, 60 * which becomes IB_OPCODE_UD + IB_OPCODE_SEND_ONLY, and this gives 61 * the correct value. 62 * 63 * In short, user code should use the constants defined using the 64 * macro rather than worrying about adding together other constants. 65 */ 66 #define IB_OPCODE(transport, op) \ 67 IB_OPCODE_ ## transport ## _ ## op = \ 68 IB_OPCODE_ ## transport + IB_OPCODE_ ## op 69 70 enum { 71 /* transport types -- just used to define real constants */ 72 IB_OPCODE_RC = 0x00, 73 IB_OPCODE_UC = 0x20, 74 IB_OPCODE_RD = 0x40, 75 IB_OPCODE_UD = 0x60, 76 77 /* operations -- just used to define real constants */ 78 IB_OPCODE_SEND_FIRST = 0x00, 79 IB_OPCODE_SEND_MIDDLE = 0x01, 80 IB_OPCODE_SEND_LAST = 0x02, 81 IB_OPCODE_SEND_LAST_WITH_IMMEDIATE = 0x03, 82 IB_OPCODE_SEND_ONLY = 0x04, 83 IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE = 0x05, 84 IB_OPCODE_RDMA_WRITE_FIRST = 0x06, 85 IB_OPCODE_RDMA_WRITE_MIDDLE = 0x07, 86 IB_OPCODE_RDMA_WRITE_LAST = 0x08, 87 IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE = 0x09, 88 IB_OPCODE_RDMA_WRITE_ONLY = 0x0a, 89 IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE = 0x0b, 90 IB_OPCODE_RDMA_READ_REQUEST = 0x0c, 91 IB_OPCODE_RDMA_READ_RESPONSE_FIRST = 0x0d, 92 IB_OPCODE_RDMA_READ_RESPONSE_MIDDLE = 0x0e, 93 IB_OPCODE_RDMA_READ_RESPONSE_LAST = 0x0f, 94 IB_OPCODE_RDMA_READ_RESPONSE_ONLY = 0x10, 95 IB_OPCODE_ACKNOWLEDGE = 0x11, 96 IB_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12, 97 IB_OPCODE_COMPARE_SWAP = 0x13, 98 IB_OPCODE_FETCH_ADD = 0x14, 99 100 /* real constants follow -- see comment about above IB_OPCODE() 101 macro for more details */ 102 103 /* RC */ 104 IB_OPCODE(RC, SEND_FIRST), 105 IB_OPCODE(RC, SEND_MIDDLE), 106 IB_OPCODE(RC, SEND_LAST), 107 IB_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE), 108 IB_OPCODE(RC, SEND_ONLY), 109 IB_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE), 110 IB_OPCODE(RC, RDMA_WRITE_FIRST), 111 IB_OPCODE(RC, RDMA_WRITE_MIDDLE), 112 IB_OPCODE(RC, RDMA_WRITE_LAST), 113 IB_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 114 IB_OPCODE(RC, RDMA_WRITE_ONLY), 115 IB_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 116 IB_OPCODE(RC, RDMA_READ_REQUEST), 117 IB_OPCODE(RC, RDMA_READ_RESPONSE_FIRST), 118 IB_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE), 119 IB_OPCODE(RC, RDMA_READ_RESPONSE_LAST), 120 IB_OPCODE(RC, RDMA_READ_RESPONSE_ONLY), 121 IB_OPCODE(RC, ACKNOWLEDGE), 122 IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE), 123 IB_OPCODE(RC, COMPARE_SWAP), 124 IB_OPCODE(RC, FETCH_ADD), 125 126 /* UC */ 127 IB_OPCODE(UC, SEND_FIRST), 128 IB_OPCODE(UC, SEND_MIDDLE), 129 IB_OPCODE(UC, SEND_LAST), 130 IB_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE), 131 IB_OPCODE(UC, SEND_ONLY), 132 IB_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE), 133 IB_OPCODE(UC, RDMA_WRITE_FIRST), 134 IB_OPCODE(UC, RDMA_WRITE_MIDDLE), 135 IB_OPCODE(UC, RDMA_WRITE_LAST), 136 IB_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 137 IB_OPCODE(UC, RDMA_WRITE_ONLY), 138 IB_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 139 140 /* RD */ 141 IB_OPCODE(RD, SEND_FIRST), 142 IB_OPCODE(RD, SEND_MIDDLE), 143 IB_OPCODE(RD, SEND_LAST), 144 IB_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE), 145 IB_OPCODE(RD, SEND_ONLY), 146 IB_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE), 147 IB_OPCODE(RD, RDMA_WRITE_FIRST), 148 IB_OPCODE(RD, RDMA_WRITE_MIDDLE), 149 IB_OPCODE(RD, RDMA_WRITE_LAST), 150 IB_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE), 151 IB_OPCODE(RD, RDMA_WRITE_ONLY), 152 IB_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 153 IB_OPCODE(RD, RDMA_READ_REQUEST), 154 IB_OPCODE(RD, RDMA_READ_RESPONSE_FIRST), 155 IB_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE), 156 IB_OPCODE(RD, RDMA_READ_RESPONSE_LAST), 157 IB_OPCODE(RD, RDMA_READ_RESPONSE_ONLY), 158 IB_OPCODE(RD, ACKNOWLEDGE), 159 IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE), 160 IB_OPCODE(RD, COMPARE_SWAP), 161 IB_OPCODE(RD, FETCH_ADD), 162 163 /* UD */ 164 IB_OPCODE(UD, SEND_ONLY), 165 IB_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE) 166 }; 167 168 enum { 169 IB_LNH_RAW = 0, 170 IB_LNH_IP = 1, 171 IB_LNH_IBA_LOCAL = 2, 172 IB_LNH_IBA_GLOBAL = 3 173 }; 174 175 struct ib_unpacked_lrh { 176 u8 virtual_lane; 177 u8 link_version; 178 u8 service_level; 179 u8 link_next_header; 180 __be16 destination_lid; 181 __be16 packet_length; 182 __be16 source_lid; 183 }; 184 185 struct ib_unpacked_grh { 186 u8 ip_version; 187 u8 traffic_class; 188 __be32 flow_label; 189 __be16 payload_length; 190 u8 next_header; 191 u8 hop_limit; 192 union ib_gid source_gid; 193 union ib_gid destination_gid; 194 }; 195 196 struct ib_unpacked_bth { 197 u8 opcode; 198 u8 solicited_event; 199 u8 mig_req; 200 u8 pad_count; 201 u8 transport_header_version; 202 __be16 pkey; 203 __be32 destination_qpn; 204 u8 ack_req; 205 __be32 psn; 206 }; 207 208 struct ib_unpacked_deth { 209 __be32 qkey; 210 __be32 source_qpn; 211 }; 212 213 struct ib_ud_header { 214 struct ib_unpacked_lrh lrh; 215 int grh_present; 216 struct ib_unpacked_grh grh; 217 struct ib_unpacked_bth bth; 218 struct ib_unpacked_deth deth; 219 int immediate_present; 220 __be32 immediate_data; 221 }; 222 223 void ib_pack(const struct ib_field *desc, 224 int desc_len, 225 void *structure, 226 void *buf); 227 228 void ib_unpack(const struct ib_field *desc, 229 int desc_len, 230 void *buf, 231 void *structure); 232 233 void ib_ud_header_init(int payload_bytes, 234 int grh_present, 235 struct ib_ud_header *header); 236 237 int ib_ud_header_pack(struct ib_ud_header *header, 238 void *buf); 239 240 int ib_ud_header_unpack(void *buf, 241 struct ib_ud_header *header); 242 243 #endif /* IB_PACK_H */ 244