162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2004 Topspin Corporation. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef IB_PACK_H 762306a36Sopenharmony_ci#define IB_PACK_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <rdma/ib_verbs.h> 1062306a36Sopenharmony_ci#include <uapi/linux/if_ether.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cienum { 1362306a36Sopenharmony_ci IB_LRH_BYTES = 8, 1462306a36Sopenharmony_ci IB_ETH_BYTES = 14, 1562306a36Sopenharmony_ci IB_VLAN_BYTES = 4, 1662306a36Sopenharmony_ci IB_GRH_BYTES = 40, 1762306a36Sopenharmony_ci IB_IP4_BYTES = 20, 1862306a36Sopenharmony_ci IB_UDP_BYTES = 8, 1962306a36Sopenharmony_ci IB_BTH_BYTES = 12, 2062306a36Sopenharmony_ci IB_DETH_BYTES = 8, 2162306a36Sopenharmony_ci IB_EXT_ATOMICETH_BYTES = 28, 2262306a36Sopenharmony_ci IB_EXT_XRC_BYTES = 4, 2362306a36Sopenharmony_ci IB_ICRC_BYTES = 4 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistruct ib_field { 2762306a36Sopenharmony_ci size_t struct_offset_bytes; 2862306a36Sopenharmony_ci size_t struct_size_bytes; 2962306a36Sopenharmony_ci int offset_words; 3062306a36Sopenharmony_ci int offset_bits; 3162306a36Sopenharmony_ci int size_bits; 3262306a36Sopenharmony_ci char *field_name; 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define RESERVED \ 3662306a36Sopenharmony_ci .field_name = "reserved" 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* 3962306a36Sopenharmony_ci * This macro cleans up the definitions of constants for BTH opcodes. 4062306a36Sopenharmony_ci * It is used to define constants such as IB_OPCODE_UD_SEND_ONLY, 4162306a36Sopenharmony_ci * which becomes IB_OPCODE_UD + IB_OPCODE_SEND_ONLY, and this gives 4262306a36Sopenharmony_ci * the correct value. 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * In short, user code should use the constants defined using the 4562306a36Sopenharmony_ci * macro rather than worrying about adding together other constants. 4662306a36Sopenharmony_ci*/ 4762306a36Sopenharmony_ci#define IB_OPCODE(transport, op) \ 4862306a36Sopenharmony_ci IB_OPCODE_ ## transport ## _ ## op = \ 4962306a36Sopenharmony_ci IB_OPCODE_ ## transport + IB_OPCODE_ ## op 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cienum { 5262306a36Sopenharmony_ci /* transport types -- just used to define real constants */ 5362306a36Sopenharmony_ci IB_OPCODE_RC = 0x00, 5462306a36Sopenharmony_ci IB_OPCODE_UC = 0x20, 5562306a36Sopenharmony_ci IB_OPCODE_RD = 0x40, 5662306a36Sopenharmony_ci IB_OPCODE_UD = 0x60, 5762306a36Sopenharmony_ci /* per IBTA 1.3 vol 1 Table 38, A10.3.2 */ 5862306a36Sopenharmony_ci IB_OPCODE_CNP = 0x80, 5962306a36Sopenharmony_ci /* Manufacturer specific */ 6062306a36Sopenharmony_ci IB_OPCODE_MSP = 0xe0, 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* operations -- just used to define real constants */ 6362306a36Sopenharmony_ci IB_OPCODE_SEND_FIRST = 0x00, 6462306a36Sopenharmony_ci IB_OPCODE_SEND_MIDDLE = 0x01, 6562306a36Sopenharmony_ci IB_OPCODE_SEND_LAST = 0x02, 6662306a36Sopenharmony_ci IB_OPCODE_SEND_LAST_WITH_IMMEDIATE = 0x03, 6762306a36Sopenharmony_ci IB_OPCODE_SEND_ONLY = 0x04, 6862306a36Sopenharmony_ci IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE = 0x05, 6962306a36Sopenharmony_ci IB_OPCODE_RDMA_WRITE_FIRST = 0x06, 7062306a36Sopenharmony_ci IB_OPCODE_RDMA_WRITE_MIDDLE = 0x07, 7162306a36Sopenharmony_ci IB_OPCODE_RDMA_WRITE_LAST = 0x08, 7262306a36Sopenharmony_ci IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE = 0x09, 7362306a36Sopenharmony_ci IB_OPCODE_RDMA_WRITE_ONLY = 0x0a, 7462306a36Sopenharmony_ci IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE = 0x0b, 7562306a36Sopenharmony_ci IB_OPCODE_RDMA_READ_REQUEST = 0x0c, 7662306a36Sopenharmony_ci IB_OPCODE_RDMA_READ_RESPONSE_FIRST = 0x0d, 7762306a36Sopenharmony_ci IB_OPCODE_RDMA_READ_RESPONSE_MIDDLE = 0x0e, 7862306a36Sopenharmony_ci IB_OPCODE_RDMA_READ_RESPONSE_LAST = 0x0f, 7962306a36Sopenharmony_ci IB_OPCODE_RDMA_READ_RESPONSE_ONLY = 0x10, 8062306a36Sopenharmony_ci IB_OPCODE_ACKNOWLEDGE = 0x11, 8162306a36Sopenharmony_ci IB_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12, 8262306a36Sopenharmony_ci IB_OPCODE_COMPARE_SWAP = 0x13, 8362306a36Sopenharmony_ci IB_OPCODE_FETCH_ADD = 0x14, 8462306a36Sopenharmony_ci /* opcode 0x15 is reserved */ 8562306a36Sopenharmony_ci IB_OPCODE_SEND_LAST_WITH_INVALIDATE = 0x16, 8662306a36Sopenharmony_ci IB_OPCODE_SEND_ONLY_WITH_INVALIDATE = 0x17, 8762306a36Sopenharmony_ci IB_OPCODE_FLUSH = 0x1C, 8862306a36Sopenharmony_ci IB_OPCODE_ATOMIC_WRITE = 0x1D, 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /* real constants follow -- see comment about above IB_OPCODE() 9162306a36Sopenharmony_ci macro for more details */ 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci /* RC */ 9462306a36Sopenharmony_ci IB_OPCODE(RC, SEND_FIRST), 9562306a36Sopenharmony_ci IB_OPCODE(RC, SEND_MIDDLE), 9662306a36Sopenharmony_ci IB_OPCODE(RC, SEND_LAST), 9762306a36Sopenharmony_ci IB_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE), 9862306a36Sopenharmony_ci IB_OPCODE(RC, SEND_ONLY), 9962306a36Sopenharmony_ci IB_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE), 10062306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_FIRST), 10162306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_MIDDLE), 10262306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_LAST), 10362306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 10462306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_ONLY), 10562306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 10662306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_REQUEST), 10762306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_RESPONSE_FIRST), 10862306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE), 10962306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_RESPONSE_LAST), 11062306a36Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_RESPONSE_ONLY), 11162306a36Sopenharmony_ci IB_OPCODE(RC, ACKNOWLEDGE), 11262306a36Sopenharmony_ci IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE), 11362306a36Sopenharmony_ci IB_OPCODE(RC, COMPARE_SWAP), 11462306a36Sopenharmony_ci IB_OPCODE(RC, FETCH_ADD), 11562306a36Sopenharmony_ci IB_OPCODE(RC, SEND_LAST_WITH_INVALIDATE), 11662306a36Sopenharmony_ci IB_OPCODE(RC, SEND_ONLY_WITH_INVALIDATE), 11762306a36Sopenharmony_ci IB_OPCODE(RC, FLUSH), 11862306a36Sopenharmony_ci IB_OPCODE(RC, ATOMIC_WRITE), 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci /* UC */ 12162306a36Sopenharmony_ci IB_OPCODE(UC, SEND_FIRST), 12262306a36Sopenharmony_ci IB_OPCODE(UC, SEND_MIDDLE), 12362306a36Sopenharmony_ci IB_OPCODE(UC, SEND_LAST), 12462306a36Sopenharmony_ci IB_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE), 12562306a36Sopenharmony_ci IB_OPCODE(UC, SEND_ONLY), 12662306a36Sopenharmony_ci IB_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE), 12762306a36Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_FIRST), 12862306a36Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_MIDDLE), 12962306a36Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_LAST), 13062306a36Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 13162306a36Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_ONLY), 13262306a36Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* RD */ 13562306a36Sopenharmony_ci IB_OPCODE(RD, SEND_FIRST), 13662306a36Sopenharmony_ci IB_OPCODE(RD, SEND_MIDDLE), 13762306a36Sopenharmony_ci IB_OPCODE(RD, SEND_LAST), 13862306a36Sopenharmony_ci IB_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE), 13962306a36Sopenharmony_ci IB_OPCODE(RD, SEND_ONLY), 14062306a36Sopenharmony_ci IB_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE), 14162306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_FIRST), 14262306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_MIDDLE), 14362306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_LAST), 14462306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE), 14562306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_ONLY), 14662306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 14762306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_REQUEST), 14862306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_RESPONSE_FIRST), 14962306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE), 15062306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_RESPONSE_LAST), 15162306a36Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_RESPONSE_ONLY), 15262306a36Sopenharmony_ci IB_OPCODE(RD, ACKNOWLEDGE), 15362306a36Sopenharmony_ci IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE), 15462306a36Sopenharmony_ci IB_OPCODE(RD, COMPARE_SWAP), 15562306a36Sopenharmony_ci IB_OPCODE(RD, FETCH_ADD), 15662306a36Sopenharmony_ci IB_OPCODE(RD, FLUSH), 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* UD */ 15962306a36Sopenharmony_ci IB_OPCODE(UD, SEND_ONLY), 16062306a36Sopenharmony_ci IB_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE) 16162306a36Sopenharmony_ci}; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cienum { 16462306a36Sopenharmony_ci IB_LNH_RAW = 0, 16562306a36Sopenharmony_ci IB_LNH_IP = 1, 16662306a36Sopenharmony_ci IB_LNH_IBA_LOCAL = 2, 16762306a36Sopenharmony_ci IB_LNH_IBA_GLOBAL = 3 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistruct ib_unpacked_lrh { 17162306a36Sopenharmony_ci u8 virtual_lane; 17262306a36Sopenharmony_ci u8 link_version; 17362306a36Sopenharmony_ci u8 service_level; 17462306a36Sopenharmony_ci u8 link_next_header; 17562306a36Sopenharmony_ci __be16 destination_lid; 17662306a36Sopenharmony_ci __be16 packet_length; 17762306a36Sopenharmony_ci __be16 source_lid; 17862306a36Sopenharmony_ci}; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_cistruct ib_unpacked_grh { 18162306a36Sopenharmony_ci u8 ip_version; 18262306a36Sopenharmony_ci u8 traffic_class; 18362306a36Sopenharmony_ci __be32 flow_label; 18462306a36Sopenharmony_ci __be16 payload_length; 18562306a36Sopenharmony_ci u8 next_header; 18662306a36Sopenharmony_ci u8 hop_limit; 18762306a36Sopenharmony_ci union ib_gid source_gid; 18862306a36Sopenharmony_ci union ib_gid destination_gid; 18962306a36Sopenharmony_ci}; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistruct ib_unpacked_bth { 19262306a36Sopenharmony_ci u8 opcode; 19362306a36Sopenharmony_ci u8 solicited_event; 19462306a36Sopenharmony_ci u8 mig_req; 19562306a36Sopenharmony_ci u8 pad_count; 19662306a36Sopenharmony_ci u8 transport_header_version; 19762306a36Sopenharmony_ci __be16 pkey; 19862306a36Sopenharmony_ci __be32 destination_qpn; 19962306a36Sopenharmony_ci u8 ack_req; 20062306a36Sopenharmony_ci __be32 psn; 20162306a36Sopenharmony_ci}; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistruct ib_unpacked_deth { 20462306a36Sopenharmony_ci __be32 qkey; 20562306a36Sopenharmony_ci __be32 source_qpn; 20662306a36Sopenharmony_ci}; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistruct ib_unpacked_eth { 20962306a36Sopenharmony_ci u8 dmac_h[4]; 21062306a36Sopenharmony_ci u8 dmac_l[2]; 21162306a36Sopenharmony_ci u8 smac_h[2]; 21262306a36Sopenharmony_ci u8 smac_l[4]; 21362306a36Sopenharmony_ci __be16 type; 21462306a36Sopenharmony_ci}; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistruct ib_unpacked_ip4 { 21762306a36Sopenharmony_ci u8 ver; 21862306a36Sopenharmony_ci u8 hdr_len; 21962306a36Sopenharmony_ci u8 tos; 22062306a36Sopenharmony_ci __be16 tot_len; 22162306a36Sopenharmony_ci __be16 id; 22262306a36Sopenharmony_ci __be16 frag_off; 22362306a36Sopenharmony_ci u8 ttl; 22462306a36Sopenharmony_ci u8 protocol; 22562306a36Sopenharmony_ci __sum16 check; 22662306a36Sopenharmony_ci __be32 saddr; 22762306a36Sopenharmony_ci __be32 daddr; 22862306a36Sopenharmony_ci}; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_cistruct ib_unpacked_udp { 23162306a36Sopenharmony_ci __be16 sport; 23262306a36Sopenharmony_ci __be16 dport; 23362306a36Sopenharmony_ci __be16 length; 23462306a36Sopenharmony_ci __be16 csum; 23562306a36Sopenharmony_ci}; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistruct ib_unpacked_vlan { 23862306a36Sopenharmony_ci __be16 tag; 23962306a36Sopenharmony_ci __be16 type; 24062306a36Sopenharmony_ci}; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistruct ib_ud_header { 24362306a36Sopenharmony_ci int lrh_present; 24462306a36Sopenharmony_ci struct ib_unpacked_lrh lrh; 24562306a36Sopenharmony_ci int eth_present; 24662306a36Sopenharmony_ci struct ib_unpacked_eth eth; 24762306a36Sopenharmony_ci int vlan_present; 24862306a36Sopenharmony_ci struct ib_unpacked_vlan vlan; 24962306a36Sopenharmony_ci int grh_present; 25062306a36Sopenharmony_ci struct ib_unpacked_grh grh; 25162306a36Sopenharmony_ci int ipv4_present; 25262306a36Sopenharmony_ci struct ib_unpacked_ip4 ip4; 25362306a36Sopenharmony_ci int udp_present; 25462306a36Sopenharmony_ci struct ib_unpacked_udp udp; 25562306a36Sopenharmony_ci struct ib_unpacked_bth bth; 25662306a36Sopenharmony_ci struct ib_unpacked_deth deth; 25762306a36Sopenharmony_ci int immediate_present; 25862306a36Sopenharmony_ci __be32 immediate_data; 25962306a36Sopenharmony_ci}; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_civoid ib_pack(const struct ib_field *desc, 26262306a36Sopenharmony_ci int desc_len, 26362306a36Sopenharmony_ci void *structure, 26462306a36Sopenharmony_ci void *buf); 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_civoid ib_unpack(const struct ib_field *desc, 26762306a36Sopenharmony_ci int desc_len, 26862306a36Sopenharmony_ci void *buf, 26962306a36Sopenharmony_ci void *structure); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci__sum16 ib_ud_ip4_csum(struct ib_ud_header *header); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ciint ib_ud_header_init(int payload_bytes, 27462306a36Sopenharmony_ci int lrh_present, 27562306a36Sopenharmony_ci int eth_present, 27662306a36Sopenharmony_ci int vlan_present, 27762306a36Sopenharmony_ci int grh_present, 27862306a36Sopenharmony_ci int ip_version, 27962306a36Sopenharmony_ci int udp_present, 28062306a36Sopenharmony_ci int immediate_present, 28162306a36Sopenharmony_ci struct ib_ud_header *header); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ciint ib_ud_header_pack(struct ib_ud_header *header, 28462306a36Sopenharmony_ci void *buf); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ciint ib_ud_header_unpack(void *buf, 28762306a36Sopenharmony_ci struct ib_ud_header *header); 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci#endif /* IB_PACK_H */ 290