18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2004 Topspin Corporation. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef IB_PACK_H 78c2ecf20Sopenharmony_ci#define IB_PACK_H 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <rdma/ib_verbs.h> 108c2ecf20Sopenharmony_ci#include <uapi/linux/if_ether.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cienum { 138c2ecf20Sopenharmony_ci IB_LRH_BYTES = 8, 148c2ecf20Sopenharmony_ci IB_ETH_BYTES = 14, 158c2ecf20Sopenharmony_ci IB_VLAN_BYTES = 4, 168c2ecf20Sopenharmony_ci IB_GRH_BYTES = 40, 178c2ecf20Sopenharmony_ci IB_IP4_BYTES = 20, 188c2ecf20Sopenharmony_ci IB_UDP_BYTES = 8, 198c2ecf20Sopenharmony_ci IB_BTH_BYTES = 12, 208c2ecf20Sopenharmony_ci IB_DETH_BYTES = 8, 218c2ecf20Sopenharmony_ci IB_EXT_ATOMICETH_BYTES = 28, 228c2ecf20Sopenharmony_ci IB_EXT_XRC_BYTES = 4, 238c2ecf20Sopenharmony_ci IB_ICRC_BYTES = 4 248c2ecf20Sopenharmony_ci}; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistruct ib_field { 278c2ecf20Sopenharmony_ci size_t struct_offset_bytes; 288c2ecf20Sopenharmony_ci size_t struct_size_bytes; 298c2ecf20Sopenharmony_ci int offset_words; 308c2ecf20Sopenharmony_ci int offset_bits; 318c2ecf20Sopenharmony_ci int size_bits; 328c2ecf20Sopenharmony_ci char *field_name; 338c2ecf20Sopenharmony_ci}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define RESERVED \ 368c2ecf20Sopenharmony_ci .field_name = "reserved" 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci/* 398c2ecf20Sopenharmony_ci * This macro cleans up the definitions of constants for BTH opcodes. 408c2ecf20Sopenharmony_ci * It is used to define constants such as IB_OPCODE_UD_SEND_ONLY, 418c2ecf20Sopenharmony_ci * which becomes IB_OPCODE_UD + IB_OPCODE_SEND_ONLY, and this gives 428c2ecf20Sopenharmony_ci * the correct value. 438c2ecf20Sopenharmony_ci * 448c2ecf20Sopenharmony_ci * In short, user code should use the constants defined using the 458c2ecf20Sopenharmony_ci * macro rather than worrying about adding together other constants. 468c2ecf20Sopenharmony_ci*/ 478c2ecf20Sopenharmony_ci#define IB_OPCODE(transport, op) \ 488c2ecf20Sopenharmony_ci IB_OPCODE_ ## transport ## _ ## op = \ 498c2ecf20Sopenharmony_ci IB_OPCODE_ ## transport + IB_OPCODE_ ## op 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cienum { 528c2ecf20Sopenharmony_ci /* transport types -- just used to define real constants */ 538c2ecf20Sopenharmony_ci IB_OPCODE_RC = 0x00, 548c2ecf20Sopenharmony_ci IB_OPCODE_UC = 0x20, 558c2ecf20Sopenharmony_ci IB_OPCODE_RD = 0x40, 568c2ecf20Sopenharmony_ci IB_OPCODE_UD = 0x60, 578c2ecf20Sopenharmony_ci /* per IBTA 1.3 vol 1 Table 38, A10.3.2 */ 588c2ecf20Sopenharmony_ci IB_OPCODE_CNP = 0x80, 598c2ecf20Sopenharmony_ci /* Manufacturer specific */ 608c2ecf20Sopenharmony_ci IB_OPCODE_MSP = 0xe0, 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci /* operations -- just used to define real constants */ 638c2ecf20Sopenharmony_ci IB_OPCODE_SEND_FIRST = 0x00, 648c2ecf20Sopenharmony_ci IB_OPCODE_SEND_MIDDLE = 0x01, 658c2ecf20Sopenharmony_ci IB_OPCODE_SEND_LAST = 0x02, 668c2ecf20Sopenharmony_ci IB_OPCODE_SEND_LAST_WITH_IMMEDIATE = 0x03, 678c2ecf20Sopenharmony_ci IB_OPCODE_SEND_ONLY = 0x04, 688c2ecf20Sopenharmony_ci IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE = 0x05, 698c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_WRITE_FIRST = 0x06, 708c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_WRITE_MIDDLE = 0x07, 718c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_WRITE_LAST = 0x08, 728c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE = 0x09, 738c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_WRITE_ONLY = 0x0a, 748c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE = 0x0b, 758c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_READ_REQUEST = 0x0c, 768c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_READ_RESPONSE_FIRST = 0x0d, 778c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_READ_RESPONSE_MIDDLE = 0x0e, 788c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_READ_RESPONSE_LAST = 0x0f, 798c2ecf20Sopenharmony_ci IB_OPCODE_RDMA_READ_RESPONSE_ONLY = 0x10, 808c2ecf20Sopenharmony_ci IB_OPCODE_ACKNOWLEDGE = 0x11, 818c2ecf20Sopenharmony_ci IB_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12, 828c2ecf20Sopenharmony_ci IB_OPCODE_COMPARE_SWAP = 0x13, 838c2ecf20Sopenharmony_ci IB_OPCODE_FETCH_ADD = 0x14, 848c2ecf20Sopenharmony_ci /* opcode 0x15 is reserved */ 858c2ecf20Sopenharmony_ci IB_OPCODE_SEND_LAST_WITH_INVALIDATE = 0x16, 868c2ecf20Sopenharmony_ci IB_OPCODE_SEND_ONLY_WITH_INVALIDATE = 0x17, 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci /* real constants follow -- see comment about above IB_OPCODE() 898c2ecf20Sopenharmony_ci macro for more details */ 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci /* RC */ 928c2ecf20Sopenharmony_ci IB_OPCODE(RC, SEND_FIRST), 938c2ecf20Sopenharmony_ci IB_OPCODE(RC, SEND_MIDDLE), 948c2ecf20Sopenharmony_ci IB_OPCODE(RC, SEND_LAST), 958c2ecf20Sopenharmony_ci IB_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE), 968c2ecf20Sopenharmony_ci IB_OPCODE(RC, SEND_ONLY), 978c2ecf20Sopenharmony_ci IB_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE), 988c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_FIRST), 998c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_MIDDLE), 1008c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_LAST), 1018c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 1028c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_ONLY), 1038c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 1048c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_REQUEST), 1058c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_RESPONSE_FIRST), 1068c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE), 1078c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_RESPONSE_LAST), 1088c2ecf20Sopenharmony_ci IB_OPCODE(RC, RDMA_READ_RESPONSE_ONLY), 1098c2ecf20Sopenharmony_ci IB_OPCODE(RC, ACKNOWLEDGE), 1108c2ecf20Sopenharmony_ci IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE), 1118c2ecf20Sopenharmony_ci IB_OPCODE(RC, COMPARE_SWAP), 1128c2ecf20Sopenharmony_ci IB_OPCODE(RC, FETCH_ADD), 1138c2ecf20Sopenharmony_ci IB_OPCODE(RC, SEND_LAST_WITH_INVALIDATE), 1148c2ecf20Sopenharmony_ci IB_OPCODE(RC, SEND_ONLY_WITH_INVALIDATE), 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci /* UC */ 1178c2ecf20Sopenharmony_ci IB_OPCODE(UC, SEND_FIRST), 1188c2ecf20Sopenharmony_ci IB_OPCODE(UC, SEND_MIDDLE), 1198c2ecf20Sopenharmony_ci IB_OPCODE(UC, SEND_LAST), 1208c2ecf20Sopenharmony_ci IB_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE), 1218c2ecf20Sopenharmony_ci IB_OPCODE(UC, SEND_ONLY), 1228c2ecf20Sopenharmony_ci IB_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE), 1238c2ecf20Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_FIRST), 1248c2ecf20Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_MIDDLE), 1258c2ecf20Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_LAST), 1268c2ecf20Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE), 1278c2ecf20Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_ONLY), 1288c2ecf20Sopenharmony_ci IB_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci /* RD */ 1318c2ecf20Sopenharmony_ci IB_OPCODE(RD, SEND_FIRST), 1328c2ecf20Sopenharmony_ci IB_OPCODE(RD, SEND_MIDDLE), 1338c2ecf20Sopenharmony_ci IB_OPCODE(RD, SEND_LAST), 1348c2ecf20Sopenharmony_ci IB_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE), 1358c2ecf20Sopenharmony_ci IB_OPCODE(RD, SEND_ONLY), 1368c2ecf20Sopenharmony_ci IB_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE), 1378c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_FIRST), 1388c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_MIDDLE), 1398c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_LAST), 1408c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE), 1418c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_ONLY), 1428c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE), 1438c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_REQUEST), 1448c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_RESPONSE_FIRST), 1458c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE), 1468c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_RESPONSE_LAST), 1478c2ecf20Sopenharmony_ci IB_OPCODE(RD, RDMA_READ_RESPONSE_ONLY), 1488c2ecf20Sopenharmony_ci IB_OPCODE(RD, ACKNOWLEDGE), 1498c2ecf20Sopenharmony_ci IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE), 1508c2ecf20Sopenharmony_ci IB_OPCODE(RD, COMPARE_SWAP), 1518c2ecf20Sopenharmony_ci IB_OPCODE(RD, FETCH_ADD), 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci /* UD */ 1548c2ecf20Sopenharmony_ci IB_OPCODE(UD, SEND_ONLY), 1558c2ecf20Sopenharmony_ci IB_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE) 1568c2ecf20Sopenharmony_ci}; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cienum { 1598c2ecf20Sopenharmony_ci IB_LNH_RAW = 0, 1608c2ecf20Sopenharmony_ci IB_LNH_IP = 1, 1618c2ecf20Sopenharmony_ci IB_LNH_IBA_LOCAL = 2, 1628c2ecf20Sopenharmony_ci IB_LNH_IBA_GLOBAL = 3 1638c2ecf20Sopenharmony_ci}; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistruct ib_unpacked_lrh { 1668c2ecf20Sopenharmony_ci u8 virtual_lane; 1678c2ecf20Sopenharmony_ci u8 link_version; 1688c2ecf20Sopenharmony_ci u8 service_level; 1698c2ecf20Sopenharmony_ci u8 link_next_header; 1708c2ecf20Sopenharmony_ci __be16 destination_lid; 1718c2ecf20Sopenharmony_ci __be16 packet_length; 1728c2ecf20Sopenharmony_ci __be16 source_lid; 1738c2ecf20Sopenharmony_ci}; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistruct ib_unpacked_grh { 1768c2ecf20Sopenharmony_ci u8 ip_version; 1778c2ecf20Sopenharmony_ci u8 traffic_class; 1788c2ecf20Sopenharmony_ci __be32 flow_label; 1798c2ecf20Sopenharmony_ci __be16 payload_length; 1808c2ecf20Sopenharmony_ci u8 next_header; 1818c2ecf20Sopenharmony_ci u8 hop_limit; 1828c2ecf20Sopenharmony_ci union ib_gid source_gid; 1838c2ecf20Sopenharmony_ci union ib_gid destination_gid; 1848c2ecf20Sopenharmony_ci}; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_cistruct ib_unpacked_bth { 1878c2ecf20Sopenharmony_ci u8 opcode; 1888c2ecf20Sopenharmony_ci u8 solicited_event; 1898c2ecf20Sopenharmony_ci u8 mig_req; 1908c2ecf20Sopenharmony_ci u8 pad_count; 1918c2ecf20Sopenharmony_ci u8 transport_header_version; 1928c2ecf20Sopenharmony_ci __be16 pkey; 1938c2ecf20Sopenharmony_ci __be32 destination_qpn; 1948c2ecf20Sopenharmony_ci u8 ack_req; 1958c2ecf20Sopenharmony_ci __be32 psn; 1968c2ecf20Sopenharmony_ci}; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistruct ib_unpacked_deth { 1998c2ecf20Sopenharmony_ci __be32 qkey; 2008c2ecf20Sopenharmony_ci __be32 source_qpn; 2018c2ecf20Sopenharmony_ci}; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistruct ib_unpacked_eth { 2048c2ecf20Sopenharmony_ci u8 dmac_h[4]; 2058c2ecf20Sopenharmony_ci u8 dmac_l[2]; 2068c2ecf20Sopenharmony_ci u8 smac_h[2]; 2078c2ecf20Sopenharmony_ci u8 smac_l[4]; 2088c2ecf20Sopenharmony_ci __be16 type; 2098c2ecf20Sopenharmony_ci}; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_cistruct ib_unpacked_ip4 { 2128c2ecf20Sopenharmony_ci u8 ver; 2138c2ecf20Sopenharmony_ci u8 hdr_len; 2148c2ecf20Sopenharmony_ci u8 tos; 2158c2ecf20Sopenharmony_ci __be16 tot_len; 2168c2ecf20Sopenharmony_ci __be16 id; 2178c2ecf20Sopenharmony_ci __be16 frag_off; 2188c2ecf20Sopenharmony_ci u8 ttl; 2198c2ecf20Sopenharmony_ci u8 protocol; 2208c2ecf20Sopenharmony_ci __sum16 check; 2218c2ecf20Sopenharmony_ci __be32 saddr; 2228c2ecf20Sopenharmony_ci __be32 daddr; 2238c2ecf20Sopenharmony_ci}; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistruct ib_unpacked_udp { 2268c2ecf20Sopenharmony_ci __be16 sport; 2278c2ecf20Sopenharmony_ci __be16 dport; 2288c2ecf20Sopenharmony_ci __be16 length; 2298c2ecf20Sopenharmony_ci __be16 csum; 2308c2ecf20Sopenharmony_ci}; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistruct ib_unpacked_vlan { 2338c2ecf20Sopenharmony_ci __be16 tag; 2348c2ecf20Sopenharmony_ci __be16 type; 2358c2ecf20Sopenharmony_ci}; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_cistruct ib_ud_header { 2388c2ecf20Sopenharmony_ci int lrh_present; 2398c2ecf20Sopenharmony_ci struct ib_unpacked_lrh lrh; 2408c2ecf20Sopenharmony_ci int eth_present; 2418c2ecf20Sopenharmony_ci struct ib_unpacked_eth eth; 2428c2ecf20Sopenharmony_ci int vlan_present; 2438c2ecf20Sopenharmony_ci struct ib_unpacked_vlan vlan; 2448c2ecf20Sopenharmony_ci int grh_present; 2458c2ecf20Sopenharmony_ci struct ib_unpacked_grh grh; 2468c2ecf20Sopenharmony_ci int ipv4_present; 2478c2ecf20Sopenharmony_ci struct ib_unpacked_ip4 ip4; 2488c2ecf20Sopenharmony_ci int udp_present; 2498c2ecf20Sopenharmony_ci struct ib_unpacked_udp udp; 2508c2ecf20Sopenharmony_ci struct ib_unpacked_bth bth; 2518c2ecf20Sopenharmony_ci struct ib_unpacked_deth deth; 2528c2ecf20Sopenharmony_ci int immediate_present; 2538c2ecf20Sopenharmony_ci __be32 immediate_data; 2548c2ecf20Sopenharmony_ci}; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_civoid ib_pack(const struct ib_field *desc, 2578c2ecf20Sopenharmony_ci int desc_len, 2588c2ecf20Sopenharmony_ci void *structure, 2598c2ecf20Sopenharmony_ci void *buf); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_civoid ib_unpack(const struct ib_field *desc, 2628c2ecf20Sopenharmony_ci int desc_len, 2638c2ecf20Sopenharmony_ci void *buf, 2648c2ecf20Sopenharmony_ci void *structure); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci__sum16 ib_ud_ip4_csum(struct ib_ud_header *header); 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ciint ib_ud_header_init(int payload_bytes, 2698c2ecf20Sopenharmony_ci int lrh_present, 2708c2ecf20Sopenharmony_ci int eth_present, 2718c2ecf20Sopenharmony_ci int vlan_present, 2728c2ecf20Sopenharmony_ci int grh_present, 2738c2ecf20Sopenharmony_ci int ip_version, 2748c2ecf20Sopenharmony_ci int udp_present, 2758c2ecf20Sopenharmony_ci int immediate_present, 2768c2ecf20Sopenharmony_ci struct ib_ud_header *header); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ciint ib_ud_header_pack(struct ib_ud_header *header, 2798c2ecf20Sopenharmony_ci void *buf); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ciint ib_ud_header_unpack(void *buf, 2828c2ecf20Sopenharmony_ci struct ib_ud_header *header); 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci#endif /* IB_PACK_H */ 285