1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004 Topspin Corporation. All rights reserved. 3219820Sjeff * 4219820Sjeff * This software is available to you under a choice of one of two 5219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 6219820Sjeff * General Public License (GPL) Version 2, available from the file 7219820Sjeff * COPYING in the main directory of this source tree, or the 8219820Sjeff * OpenIB.org BSD license below: 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or 11219820Sjeff * without modification, are permitted provided that the following 12219820Sjeff * conditions are met: 13219820Sjeff * 14219820Sjeff * - Redistributions of source code must retain the above 15219820Sjeff * copyright notice, this list of conditions and the following 16219820Sjeff * disclaimer. 17219820Sjeff * 18219820Sjeff * - Redistributions in binary form must reproduce the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer in the documentation and/or other materials 21219820Sjeff * provided with the distribution. 22219820Sjeff * 23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30219820Sjeff * SOFTWARE. 31219820Sjeff */ 32219820Sjeff 33219820Sjeff#ifndef IB_PACK_H 34219820Sjeff#define IB_PACK_H 35219820Sjeff 36219820Sjeff#include <rdma/ib_verbs.h> 37219820Sjeff 38219820Sjeffenum { 39219820Sjeff IB_LRH_BYTES = 8, 40219820Sjeff IB_ETH_BYTES = 14, 41219820Sjeff IB_VLAN_BYTES = 4, 42219820Sjeff IB_GRH_BYTES = 40, 43219820Sjeff IB_BTH_BYTES = 12, 44219820Sjeff IB_DETH_BYTES = 8 45219820Sjeff}; 46219820Sjeff 47219820Sjeffstruct ib_field { 48219820Sjeff size_t struct_offset_bytes; 49219820Sjeff size_t struct_size_bytes; 50219820Sjeff int offset_words; 51219820Sjeff int offset_bits; 52219820Sjeff int size_bits; 53219820Sjeff char *field_name; 54219820Sjeff}; 55219820Sjeff 56219820Sjeff#define RESERVED \ 57219820Sjeff .field_name = "reserved" 58219820Sjeff 59219820Sjeff/* 60219820Sjeff * This macro cleans up the definitions of constants for BTH opcodes. 61219820Sjeff * It is used to define constants such as IB_OPCODE_UD_SEND_ONLY, 62219820Sjeff * which becomes IB_OPCODE_UD + IB_OPCODE_SEND_ONLY, and this gives 63219820Sjeff * the correct value. 64219820Sjeff * 65219820Sjeff * In short, user code should use the constants defined using the 66219820Sjeff * macro rather than worrying about adding together other constants. 67219820Sjeff*/ 68219820Sjeff#define IB_OPCODE(transport, op) \ 69219820Sjeff IB_OPCODE_ ## transport ## _ ## op = \ 70219820Sjeff IB_OPCODE_ ## transport + IB_OPCODE_ ## op 71219820Sjeff 72219820Sjeffenum { 73219820Sjeff /* transport types -- just used to define real constants */ 74219820Sjeff IB_OPCODE_RC = 0x00, 75219820Sjeff IB_OPCODE_UC = 0x20, 76219820Sjeff IB_OPCODE_RD = 0x40, 77219820Sjeff IB_OPCODE_UD = 0x60, 78219820Sjeff 79219820Sjeff /* operations -- just used to define real constants */ 80219820Sjeff IB_OPCODE_SEND_FIRST = 0x00, 81219820Sjeff IB_OPCODE_SEND_MIDDLE = 0x01, 82219820Sjeff IB_OPCODE_SEND_LAST = 0x02, 83219820Sjeff IB_OPCODE_SEND_LAST_WITH_IMMEDIATE = 0x03, 84219820Sjeff IB_OPCODE_SEND_ONLY = 0x04, 85219820Sjeff IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE = 0x05, 86219820Sjeff IB_OPCODE_RDMA_WRITE_FIRST = 0x06, 87219820Sjeff IB_OPCODE_RDMA_WRITE_MIDDLE = 0x07, 88219820Sjeff IB_OPCODE_RDMA_WRITE_LAST = 0x08, 89219820Sjeff IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE = 0x09, 90219820Sjeff IB_OPCODE_RDMA_WRITE_ONLY = 0x0a, 91219820Sjeff IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE = 0x0b, 92219820Sjeff IB_OPCODE_RDMA_READ_REQUEST = 0x0c, 93219820Sjeff IB_OPCODE_RDMA_READ_RESPONSE_FIRST = 0x0d, 94219820Sjeff IB_OPCODE_RDMA_READ_RESPONSE_MIDDLE = 0x0e, 95219820Sjeff IB_OPCODE_RDMA_READ_RESPONSE_LAST = 0x0f, 96219820Sjeff IB_OPCODE_RDMA_READ_RESPONSE_ONLY = 0x10, 97219820Sjeff IB_OPCODE_ACKNOWLEDGE = 0x11, 98219820Sjeff IB_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12, 99219820Sjeff IB_OPCODE_COMPARE_SWAP = 0x13, 100219820Sjeff IB_OPCODE_FETCH_ADD = 0x14, 101219820Sjeff 102219820Sjeff /* real constants follow -- see comment about above IB_OPCODE() 103219820Sjeff macro for more details */ 104219820Sjeff 105219820Sjeff /* RC */ 106219820Sjeff IB_OPCODE(RC, SEND_FIRST), 107219820Sjeff IB_OPCODE(RC, SEND_MIDDLE), 108219820Sjeff IB_OPCODE(RC, SEND_LAST), 109219820Sjeff IB_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE), 110219820Sjeff IB_OPCODE(RC, SEND_ONLY), 111219820Sjeff IB_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE), 112219820Sjeff IB_OPCODE(RC, RDMA_WRITE_FIRST), 113219820Sjeff IB_OPCODE(RC, RDMA_WRITE_MIDDLE), 114219820Sjeff IB_OPCODE(RC, RDMA_WRITE_LAST), 115219820Sjeff IB_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 116219820Sjeff IB_OPCODE(RC, RDMA_WRITE_ONLY), 117219820Sjeff IB_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 118219820Sjeff IB_OPCODE(RC, RDMA_READ_REQUEST), 119219820Sjeff IB_OPCODE(RC, RDMA_READ_RESPONSE_FIRST), 120219820Sjeff IB_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE), 121219820Sjeff IB_OPCODE(RC, RDMA_READ_RESPONSE_LAST), 122219820Sjeff IB_OPCODE(RC, RDMA_READ_RESPONSE_ONLY), 123219820Sjeff IB_OPCODE(RC, ACKNOWLEDGE), 124219820Sjeff IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE), 125219820Sjeff IB_OPCODE(RC, COMPARE_SWAP), 126219820Sjeff IB_OPCODE(RC, FETCH_ADD), 127219820Sjeff 128219820Sjeff /* UC */ 129219820Sjeff IB_OPCODE(UC, SEND_FIRST), 130219820Sjeff IB_OPCODE(UC, SEND_MIDDLE), 131219820Sjeff IB_OPCODE(UC, SEND_LAST), 132219820Sjeff IB_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE), 133219820Sjeff IB_OPCODE(UC, SEND_ONLY), 134219820Sjeff IB_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE), 135219820Sjeff IB_OPCODE(UC, RDMA_WRITE_FIRST), 136219820Sjeff IB_OPCODE(UC, RDMA_WRITE_MIDDLE), 137219820Sjeff IB_OPCODE(UC, RDMA_WRITE_LAST), 138219820Sjeff IB_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 139219820Sjeff IB_OPCODE(UC, RDMA_WRITE_ONLY), 140219820Sjeff IB_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 141219820Sjeff 142219820Sjeff /* RD */ 143219820Sjeff IB_OPCODE(RD, SEND_FIRST), 144219820Sjeff IB_OPCODE(RD, SEND_MIDDLE), 145219820Sjeff IB_OPCODE(RD, SEND_LAST), 146219820Sjeff IB_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE), 147219820Sjeff IB_OPCODE(RD, SEND_ONLY), 148219820Sjeff IB_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE), 149219820Sjeff IB_OPCODE(RD, RDMA_WRITE_FIRST), 150219820Sjeff IB_OPCODE(RD, RDMA_WRITE_MIDDLE), 151219820Sjeff IB_OPCODE(RD, RDMA_WRITE_LAST), 152219820Sjeff IB_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE), 153219820Sjeff IB_OPCODE(RD, RDMA_WRITE_ONLY), 154219820Sjeff IB_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 155219820Sjeff IB_OPCODE(RD, RDMA_READ_REQUEST), 156219820Sjeff IB_OPCODE(RD, RDMA_READ_RESPONSE_FIRST), 157219820Sjeff IB_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE), 158219820Sjeff IB_OPCODE(RD, RDMA_READ_RESPONSE_LAST), 159219820Sjeff IB_OPCODE(RD, RDMA_READ_RESPONSE_ONLY), 160219820Sjeff IB_OPCODE(RD, ACKNOWLEDGE), 161219820Sjeff IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE), 162219820Sjeff IB_OPCODE(RD, COMPARE_SWAP), 163219820Sjeff IB_OPCODE(RD, FETCH_ADD), 164219820Sjeff 165219820Sjeff /* UD */ 166219820Sjeff IB_OPCODE(UD, SEND_ONLY), 167219820Sjeff IB_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE) 168219820Sjeff}; 169219820Sjeff 170219820Sjeffenum { 171219820Sjeff IB_LNH_RAW = 0, 172219820Sjeff IB_LNH_IP = 1, 173219820Sjeff IB_LNH_IBA_LOCAL = 2, 174219820Sjeff IB_LNH_IBA_GLOBAL = 3 175219820Sjeff}; 176219820Sjeff 177219820Sjeffstruct ib_unpacked_lrh { 178219820Sjeff u8 virtual_lane; 179219820Sjeff u8 link_version; 180219820Sjeff u8 service_level; 181219820Sjeff u8 link_next_header; 182219820Sjeff __be16 destination_lid; 183219820Sjeff __be16 packet_length; 184219820Sjeff __be16 source_lid; 185219820Sjeff}; 186219820Sjeff 187219820Sjeffstruct ib_unpacked_grh { 188219820Sjeff u8 ip_version; 189219820Sjeff u8 traffic_class; 190219820Sjeff __be32 flow_label; 191219820Sjeff __be16 payload_length; 192219820Sjeff u8 next_header; 193219820Sjeff u8 hop_limit; 194219820Sjeff union ib_gid source_gid; 195219820Sjeff union ib_gid destination_gid; 196219820Sjeff}; 197219820Sjeff 198219820Sjeffstruct ib_unpacked_bth { 199219820Sjeff u8 opcode; 200219820Sjeff u8 solicited_event; 201219820Sjeff u8 mig_req; 202219820Sjeff u8 pad_count; 203219820Sjeff u8 transport_header_version; 204219820Sjeff __be16 pkey; 205219820Sjeff __be32 destination_qpn; 206219820Sjeff u8 ack_req; 207219820Sjeff __be32 psn; 208219820Sjeff}; 209219820Sjeff 210219820Sjeffstruct ib_unpacked_deth { 211219820Sjeff __be32 qkey; 212219820Sjeff __be32 source_qpn; 213219820Sjeff}; 214219820Sjeff 215219820Sjeffstruct ib_unpacked_eth { 216219820Sjeff u8 dmac_h[4]; 217219820Sjeff u8 dmac_l[2]; 218219820Sjeff u8 smac_h[2]; 219219820Sjeff u8 smac_l[4]; 220219820Sjeff __be16 type; 221219820Sjeff}; 222219820Sjeff 223219820Sjeffstruct ib_unpacked_vlan { 224219820Sjeff __be16 tag; 225219820Sjeff __be16 type; 226219820Sjeff}; 227219820Sjeff 228219820Sjeffstruct ib_ud_header { 229219820Sjeff int lrh_present; 230219820Sjeff struct ib_unpacked_lrh lrh; 231219820Sjeff int eth_present; 232219820Sjeff struct ib_unpacked_eth eth; 233219820Sjeff int vlan_present; 234219820Sjeff struct ib_unpacked_vlan vlan; 235219820Sjeff int grh_present; 236219820Sjeff struct ib_unpacked_grh grh; 237219820Sjeff struct ib_unpacked_bth bth; 238219820Sjeff struct ib_unpacked_deth deth; 239219820Sjeff int immediate_present; 240219820Sjeff __be32 immediate_data; 241219820Sjeff}; 242219820Sjeff 243219820Sjeffvoid ib_pack(const struct ib_field *desc, 244219820Sjeff int desc_len, 245219820Sjeff void *structure, 246219820Sjeff void *buf); 247219820Sjeff 248219820Sjeffvoid ib_unpack(const struct ib_field *desc, 249219820Sjeff int desc_len, 250219820Sjeff void *buf, 251219820Sjeff void *structure); 252219820Sjeff 253219820Sjeffvoid ib_ud_header_init(int payload_bytes, 254219820Sjeff int lrh_present, 255219820Sjeff int eth_present, 256219820Sjeff int vlan_present, 257219820Sjeff int grh_present, 258219820Sjeff int immediate_present, 259219820Sjeff struct ib_ud_header *header); 260219820Sjeff 261219820Sjeffint ib_ud_header_pack(struct ib_ud_header *header, 262219820Sjeff void *buf); 263219820Sjeff 264219820Sjeffint ib_ud_header_unpack(void *buf, 265219820Sjeff struct ib_ud_header *header); 266219820Sjeffint ib_lrh_header_pack(struct ib_unpacked_lrh *lrh, void *buf); 267219820Sjeffint ib_lrh_header_unpack(void *buf, struct ib_unpacked_lrh *lrh); 268219820Sjeff 269219820Sjeff#endif /* IB_PACK_H */ 270