1*fe267a55SPedro F. Giffuni /*- 2*fe267a55SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3*fe267a55SPedro F. Giffuni * 4aa0a1e58SJeff Roberson * Copyright (c) 2004 Topspin Corporation. All rights reserved. 5aa0a1e58SJeff Roberson * 6aa0a1e58SJeff Roberson * This software is available to you under a choice of one of two 7aa0a1e58SJeff Roberson * licenses. You may choose to be licensed under the terms of the GNU 8aa0a1e58SJeff Roberson * General Public License (GPL) Version 2, available from the file 9aa0a1e58SJeff Roberson * COPYING in the main directory of this source tree, or the 10aa0a1e58SJeff Roberson * OpenIB.org BSD license below: 11aa0a1e58SJeff Roberson * 12aa0a1e58SJeff Roberson * Redistribution and use in source and binary forms, with or 13aa0a1e58SJeff Roberson * without modification, are permitted provided that the following 14aa0a1e58SJeff Roberson * conditions are met: 15aa0a1e58SJeff Roberson * 16aa0a1e58SJeff Roberson * - Redistributions of source code must retain the above 17aa0a1e58SJeff Roberson * copyright notice, this list of conditions and the following 18aa0a1e58SJeff Roberson * disclaimer. 19aa0a1e58SJeff Roberson * 20aa0a1e58SJeff Roberson * - Redistributions in binary form must reproduce the above 21aa0a1e58SJeff Roberson * copyright notice, this list of conditions and the following 22aa0a1e58SJeff Roberson * disclaimer in the documentation and/or other materials 23aa0a1e58SJeff Roberson * provided with the distribution. 24aa0a1e58SJeff Roberson * 25aa0a1e58SJeff Roberson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26aa0a1e58SJeff Roberson * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27aa0a1e58SJeff Roberson * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28aa0a1e58SJeff Roberson * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29aa0a1e58SJeff Roberson * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30aa0a1e58SJeff Roberson * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31aa0a1e58SJeff Roberson * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32aa0a1e58SJeff Roberson * SOFTWARE. 33aa0a1e58SJeff Roberson */ 34aa0a1e58SJeff Roberson 35aa0a1e58SJeff Roberson #ifndef IB_PACK_H 36aa0a1e58SJeff Roberson #define IB_PACK_H 37aa0a1e58SJeff Roberson 38aa0a1e58SJeff Roberson #include <rdma/ib_verbs.h> 39aa0a1e58SJeff Roberson 40aa0a1e58SJeff Roberson enum { 41aa0a1e58SJeff Roberson IB_LRH_BYTES = 8, 42aa0a1e58SJeff Roberson IB_ETH_BYTES = 14, 43aa0a1e58SJeff Roberson IB_VLAN_BYTES = 4, 44aa0a1e58SJeff Roberson IB_GRH_BYTES = 40, 45478d3005SHans Petter Selasky IB_IP4_BYTES = 20, 46478d3005SHans Petter Selasky IB_UDP_BYTES = 8, 47aa0a1e58SJeff Roberson IB_BTH_BYTES = 12, 48aa0a1e58SJeff Roberson IB_DETH_BYTES = 8 49aa0a1e58SJeff Roberson }; 50aa0a1e58SJeff Roberson 51aa0a1e58SJeff Roberson struct ib_field { 52aa0a1e58SJeff Roberson size_t struct_offset_bytes; 53aa0a1e58SJeff Roberson size_t struct_size_bytes; 54aa0a1e58SJeff Roberson int offset_words; 55aa0a1e58SJeff Roberson int offset_bits; 56aa0a1e58SJeff Roberson int size_bits; 57aa0a1e58SJeff Roberson char *field_name; 58aa0a1e58SJeff Roberson }; 59aa0a1e58SJeff Roberson 60aa0a1e58SJeff Roberson #define RESERVED \ 61aa0a1e58SJeff Roberson .field_name = "reserved" 62aa0a1e58SJeff Roberson 63aa0a1e58SJeff Roberson /* 64aa0a1e58SJeff Roberson * This macro cleans up the definitions of constants for BTH opcodes. 65aa0a1e58SJeff Roberson * It is used to define constants such as IB_OPCODE_UD_SEND_ONLY, 66aa0a1e58SJeff Roberson * which becomes IB_OPCODE_UD + IB_OPCODE_SEND_ONLY, and this gives 67aa0a1e58SJeff Roberson * the correct value. 68aa0a1e58SJeff Roberson * 69aa0a1e58SJeff Roberson * In short, user code should use the constants defined using the 70aa0a1e58SJeff Roberson * macro rather than worrying about adding together other constants. 71aa0a1e58SJeff Roberson */ 72aa0a1e58SJeff Roberson #define IB_OPCODE(transport, op) \ 73aa0a1e58SJeff Roberson IB_OPCODE_ ## transport ## _ ## op = \ 74aa0a1e58SJeff Roberson IB_OPCODE_ ## transport + IB_OPCODE_ ## op 75aa0a1e58SJeff Roberson 76aa0a1e58SJeff Roberson enum { 77aa0a1e58SJeff Roberson /* transport types -- just used to define real constants */ 78aa0a1e58SJeff Roberson IB_OPCODE_RC = 0x00, 79aa0a1e58SJeff Roberson IB_OPCODE_UC = 0x20, 80aa0a1e58SJeff Roberson IB_OPCODE_RD = 0x40, 81aa0a1e58SJeff Roberson IB_OPCODE_UD = 0x60, 82478d3005SHans Petter Selasky /* per IBTA 1.3 vol 1 Table 38, A10.3.2 */ 83478d3005SHans Petter Selasky IB_OPCODE_CNP = 0x80, 84aa0a1e58SJeff Roberson 85aa0a1e58SJeff Roberson /* operations -- just used to define real constants */ 86aa0a1e58SJeff Roberson IB_OPCODE_SEND_FIRST = 0x00, 87aa0a1e58SJeff Roberson IB_OPCODE_SEND_MIDDLE = 0x01, 88aa0a1e58SJeff Roberson IB_OPCODE_SEND_LAST = 0x02, 89aa0a1e58SJeff Roberson IB_OPCODE_SEND_LAST_WITH_IMMEDIATE = 0x03, 90aa0a1e58SJeff Roberson IB_OPCODE_SEND_ONLY = 0x04, 91aa0a1e58SJeff Roberson IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE = 0x05, 92aa0a1e58SJeff Roberson IB_OPCODE_RDMA_WRITE_FIRST = 0x06, 93aa0a1e58SJeff Roberson IB_OPCODE_RDMA_WRITE_MIDDLE = 0x07, 94aa0a1e58SJeff Roberson IB_OPCODE_RDMA_WRITE_LAST = 0x08, 95aa0a1e58SJeff Roberson IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE = 0x09, 96aa0a1e58SJeff Roberson IB_OPCODE_RDMA_WRITE_ONLY = 0x0a, 97aa0a1e58SJeff Roberson IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE = 0x0b, 98aa0a1e58SJeff Roberson IB_OPCODE_RDMA_READ_REQUEST = 0x0c, 99aa0a1e58SJeff Roberson IB_OPCODE_RDMA_READ_RESPONSE_FIRST = 0x0d, 100aa0a1e58SJeff Roberson IB_OPCODE_RDMA_READ_RESPONSE_MIDDLE = 0x0e, 101aa0a1e58SJeff Roberson IB_OPCODE_RDMA_READ_RESPONSE_LAST = 0x0f, 102aa0a1e58SJeff Roberson IB_OPCODE_RDMA_READ_RESPONSE_ONLY = 0x10, 103aa0a1e58SJeff Roberson IB_OPCODE_ACKNOWLEDGE = 0x11, 104aa0a1e58SJeff Roberson IB_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12, 105aa0a1e58SJeff Roberson IB_OPCODE_COMPARE_SWAP = 0x13, 106aa0a1e58SJeff Roberson IB_OPCODE_FETCH_ADD = 0x14, 107478d3005SHans Petter Selasky /* opcode 0x15 is reserved */ 108478d3005SHans Petter Selasky IB_OPCODE_SEND_LAST_WITH_INVALIDATE = 0x16, 109478d3005SHans Petter Selasky IB_OPCODE_SEND_ONLY_WITH_INVALIDATE = 0x17, 110aa0a1e58SJeff Roberson 111aa0a1e58SJeff Roberson /* real constants follow -- see comment about above IB_OPCODE() 112aa0a1e58SJeff Roberson macro for more details */ 113aa0a1e58SJeff Roberson 114aa0a1e58SJeff Roberson /* RC */ 115aa0a1e58SJeff Roberson IB_OPCODE(RC, SEND_FIRST), 116aa0a1e58SJeff Roberson IB_OPCODE(RC, SEND_MIDDLE), 117aa0a1e58SJeff Roberson IB_OPCODE(RC, SEND_LAST), 118aa0a1e58SJeff Roberson IB_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE), 119aa0a1e58SJeff Roberson IB_OPCODE(RC, SEND_ONLY), 120aa0a1e58SJeff Roberson IB_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE), 121aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_WRITE_FIRST), 122aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_WRITE_MIDDLE), 123aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_WRITE_LAST), 124aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 125aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_WRITE_ONLY), 126aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 127aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_READ_REQUEST), 128aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_READ_RESPONSE_FIRST), 129aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE), 130aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_READ_RESPONSE_LAST), 131aa0a1e58SJeff Roberson IB_OPCODE(RC, RDMA_READ_RESPONSE_ONLY), 132aa0a1e58SJeff Roberson IB_OPCODE(RC, ACKNOWLEDGE), 133aa0a1e58SJeff Roberson IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE), 134aa0a1e58SJeff Roberson IB_OPCODE(RC, COMPARE_SWAP), 135aa0a1e58SJeff Roberson IB_OPCODE(RC, FETCH_ADD), 136478d3005SHans Petter Selasky IB_OPCODE(RC, SEND_LAST_WITH_INVALIDATE), 137478d3005SHans Petter Selasky IB_OPCODE(RC, SEND_ONLY_WITH_INVALIDATE), 138aa0a1e58SJeff Roberson 139aa0a1e58SJeff Roberson /* UC */ 140aa0a1e58SJeff Roberson IB_OPCODE(UC, SEND_FIRST), 141aa0a1e58SJeff Roberson IB_OPCODE(UC, SEND_MIDDLE), 142aa0a1e58SJeff Roberson IB_OPCODE(UC, SEND_LAST), 143aa0a1e58SJeff Roberson IB_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE), 144aa0a1e58SJeff Roberson IB_OPCODE(UC, SEND_ONLY), 145aa0a1e58SJeff Roberson IB_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE), 146aa0a1e58SJeff Roberson IB_OPCODE(UC, RDMA_WRITE_FIRST), 147aa0a1e58SJeff Roberson IB_OPCODE(UC, RDMA_WRITE_MIDDLE), 148aa0a1e58SJeff Roberson IB_OPCODE(UC, RDMA_WRITE_LAST), 149aa0a1e58SJeff Roberson IB_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 150aa0a1e58SJeff Roberson IB_OPCODE(UC, RDMA_WRITE_ONLY), 151aa0a1e58SJeff Roberson IB_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 152aa0a1e58SJeff Roberson 153aa0a1e58SJeff Roberson /* RD */ 154aa0a1e58SJeff Roberson IB_OPCODE(RD, SEND_FIRST), 155aa0a1e58SJeff Roberson IB_OPCODE(RD, SEND_MIDDLE), 156aa0a1e58SJeff Roberson IB_OPCODE(RD, SEND_LAST), 157aa0a1e58SJeff Roberson IB_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE), 158aa0a1e58SJeff Roberson IB_OPCODE(RD, SEND_ONLY), 159aa0a1e58SJeff Roberson IB_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE), 160aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_WRITE_FIRST), 161aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_WRITE_MIDDLE), 162aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_WRITE_LAST), 163aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE), 164aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_WRITE_ONLY), 165aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 166aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_READ_REQUEST), 167aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_READ_RESPONSE_FIRST), 168aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE), 169aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_READ_RESPONSE_LAST), 170aa0a1e58SJeff Roberson IB_OPCODE(RD, RDMA_READ_RESPONSE_ONLY), 171aa0a1e58SJeff Roberson IB_OPCODE(RD, ACKNOWLEDGE), 172aa0a1e58SJeff Roberson IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE), 173aa0a1e58SJeff Roberson IB_OPCODE(RD, COMPARE_SWAP), 174aa0a1e58SJeff Roberson IB_OPCODE(RD, FETCH_ADD), 175aa0a1e58SJeff Roberson 176aa0a1e58SJeff Roberson /* UD */ 177aa0a1e58SJeff Roberson IB_OPCODE(UD, SEND_ONLY), 178aa0a1e58SJeff Roberson IB_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE) 179aa0a1e58SJeff Roberson }; 180aa0a1e58SJeff Roberson 181aa0a1e58SJeff Roberson enum { 182aa0a1e58SJeff Roberson IB_LNH_RAW = 0, 183aa0a1e58SJeff Roberson IB_LNH_IP = 1, 184aa0a1e58SJeff Roberson IB_LNH_IBA_LOCAL = 2, 185aa0a1e58SJeff Roberson IB_LNH_IBA_GLOBAL = 3 186aa0a1e58SJeff Roberson }; 187aa0a1e58SJeff Roberson 188aa0a1e58SJeff Roberson struct ib_unpacked_lrh { 189aa0a1e58SJeff Roberson u8 virtual_lane; 190aa0a1e58SJeff Roberson u8 link_version; 191aa0a1e58SJeff Roberson u8 service_level; 192aa0a1e58SJeff Roberson u8 link_next_header; 193aa0a1e58SJeff Roberson __be16 destination_lid; 194aa0a1e58SJeff Roberson __be16 packet_length; 195aa0a1e58SJeff Roberson __be16 source_lid; 196aa0a1e58SJeff Roberson }; 197aa0a1e58SJeff Roberson 198aa0a1e58SJeff Roberson struct ib_unpacked_grh { 199aa0a1e58SJeff Roberson u8 ip_version; 200aa0a1e58SJeff Roberson u8 traffic_class; 201aa0a1e58SJeff Roberson __be32 flow_label; 202aa0a1e58SJeff Roberson __be16 payload_length; 203aa0a1e58SJeff Roberson u8 next_header; 204aa0a1e58SJeff Roberson u8 hop_limit; 205aa0a1e58SJeff Roberson union ib_gid source_gid; 206aa0a1e58SJeff Roberson union ib_gid destination_gid; 207aa0a1e58SJeff Roberson }; 208aa0a1e58SJeff Roberson 209aa0a1e58SJeff Roberson struct ib_unpacked_bth { 210aa0a1e58SJeff Roberson u8 opcode; 211aa0a1e58SJeff Roberson u8 solicited_event; 212aa0a1e58SJeff Roberson u8 mig_req; 213aa0a1e58SJeff Roberson u8 pad_count; 214aa0a1e58SJeff Roberson u8 transport_header_version; 215aa0a1e58SJeff Roberson __be16 pkey; 216aa0a1e58SJeff Roberson __be32 destination_qpn; 217aa0a1e58SJeff Roberson u8 ack_req; 218aa0a1e58SJeff Roberson __be32 psn; 219aa0a1e58SJeff Roberson }; 220aa0a1e58SJeff Roberson 221aa0a1e58SJeff Roberson struct ib_unpacked_deth { 222aa0a1e58SJeff Roberson __be32 qkey; 223aa0a1e58SJeff Roberson __be32 source_qpn; 224aa0a1e58SJeff Roberson }; 225aa0a1e58SJeff Roberson 226aa0a1e58SJeff Roberson struct ib_unpacked_eth { 227aa0a1e58SJeff Roberson u8 dmac_h[4]; 228aa0a1e58SJeff Roberson u8 dmac_l[2]; 229aa0a1e58SJeff Roberson u8 smac_h[2]; 230aa0a1e58SJeff Roberson u8 smac_l[4]; 231aa0a1e58SJeff Roberson __be16 type; 232aa0a1e58SJeff Roberson }; 233aa0a1e58SJeff Roberson 234478d3005SHans Petter Selasky struct ib_unpacked_ip4 { 235478d3005SHans Petter Selasky u8 ver; 236478d3005SHans Petter Selasky u8 hdr_len; 237478d3005SHans Petter Selasky u8 tos; 238478d3005SHans Petter Selasky __be16 tot_len; 239478d3005SHans Petter Selasky __be16 id; 240478d3005SHans Petter Selasky __be16 frag_off; 241478d3005SHans Petter Selasky u8 ttl; 242478d3005SHans Petter Selasky u8 protocol; 243478d3005SHans Petter Selasky __sum16 check; 244478d3005SHans Petter Selasky __be32 saddr; 245478d3005SHans Petter Selasky __be32 daddr; 246478d3005SHans Petter Selasky }; 247478d3005SHans Petter Selasky 248478d3005SHans Petter Selasky struct ib_unpacked_udp { 249478d3005SHans Petter Selasky __be16 sport; 250478d3005SHans Petter Selasky __be16 dport; 251478d3005SHans Petter Selasky __be16 length; 252478d3005SHans Petter Selasky __be16 csum; 253478d3005SHans Petter Selasky }; 254478d3005SHans Petter Selasky 255aa0a1e58SJeff Roberson struct ib_unpacked_vlan { 256aa0a1e58SJeff Roberson __be16 tag; 257aa0a1e58SJeff Roberson __be16 type; 258aa0a1e58SJeff Roberson }; 259aa0a1e58SJeff Roberson 260aa0a1e58SJeff Roberson struct ib_ud_header { 261aa0a1e58SJeff Roberson int lrh_present; 262aa0a1e58SJeff Roberson struct ib_unpacked_lrh lrh; 263aa0a1e58SJeff Roberson int eth_present; 264aa0a1e58SJeff Roberson struct ib_unpacked_eth eth; 265aa0a1e58SJeff Roberson int vlan_present; 266aa0a1e58SJeff Roberson struct ib_unpacked_vlan vlan; 267aa0a1e58SJeff Roberson int grh_present; 268aa0a1e58SJeff Roberson struct ib_unpacked_grh grh; 269478d3005SHans Petter Selasky int ipv4_present; 270478d3005SHans Petter Selasky struct ib_unpacked_ip4 ip4; 271478d3005SHans Petter Selasky int udp_present; 272478d3005SHans Petter Selasky struct ib_unpacked_udp udp; 273aa0a1e58SJeff Roberson struct ib_unpacked_bth bth; 274aa0a1e58SJeff Roberson struct ib_unpacked_deth deth; 275aa0a1e58SJeff Roberson int immediate_present; 276aa0a1e58SJeff Roberson __be32 immediate_data; 277aa0a1e58SJeff Roberson }; 278aa0a1e58SJeff Roberson 279aa0a1e58SJeff Roberson void ib_pack(const struct ib_field *desc, 280aa0a1e58SJeff Roberson int desc_len, 281aa0a1e58SJeff Roberson void *structure, 282aa0a1e58SJeff Roberson void *buf); 283aa0a1e58SJeff Roberson 284aa0a1e58SJeff Roberson void ib_unpack(const struct ib_field *desc, 285aa0a1e58SJeff Roberson int desc_len, 286aa0a1e58SJeff Roberson void *buf, 287aa0a1e58SJeff Roberson void *structure); 288aa0a1e58SJeff Roberson 289478d3005SHans Petter Selasky __sum16 ib_ud_ip4_csum(struct ib_ud_header *header); 290478d3005SHans Petter Selasky 291478d3005SHans Petter Selasky int ib_ud_header_init(int payload_bytes, 292aa0a1e58SJeff Roberson int lrh_present, 293aa0a1e58SJeff Roberson int eth_present, 294aa0a1e58SJeff Roberson int vlan_present, 295aa0a1e58SJeff Roberson int grh_present, 296478d3005SHans Petter Selasky int ip_version, 297478d3005SHans Petter Selasky int udp_present, 298aa0a1e58SJeff Roberson int immediate_present, 299aa0a1e58SJeff Roberson struct ib_ud_header *header); 300aa0a1e58SJeff Roberson 301aa0a1e58SJeff Roberson int ib_ud_header_pack(struct ib_ud_header *header, 302aa0a1e58SJeff Roberson void *buf); 303aa0a1e58SJeff Roberson 304aa0a1e58SJeff Roberson int ib_ud_header_unpack(void *buf, 305aa0a1e58SJeff Roberson struct ib_ud_header *header); 306aa0a1e58SJeff Roberson 307aa0a1e58SJeff Roberson #endif /* IB_PACK_H */ 308