xref: /openbmc/linux/include/rdma/ib_pack.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
16bf9d8f6SLeon Romanovsky /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2a4d61e84SRoland Dreier /*
3a4d61e84SRoland Dreier  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
4a4d61e84SRoland Dreier  */
5a4d61e84SRoland Dreier 
6a4d61e84SRoland Dreier #ifndef IB_PACK_H
7a4d61e84SRoland Dreier #define IB_PACK_H
8a4d61e84SRoland Dreier 
9a4d61e84SRoland Dreier #include <rdma/ib_verbs.h>
10dd5f03beSMatan Barak #include <uapi/linux/if_ether.h>
11a4d61e84SRoland Dreier 
12a4d61e84SRoland Dreier enum {
13a4d61e84SRoland Dreier 	IB_LRH_BYTES		= 8,
14ff7f5aabSEli Cohen 	IB_ETH_BYTES		= 14,
15af7bd463SEli Cohen 	IB_VLAN_BYTES		= 4,
16a4d61e84SRoland Dreier 	IB_GRH_BYTES		= 40,
1725f40220SMoni Shoua 	IB_IP4_BYTES		= 20,
1825f40220SMoni Shoua 	IB_UDP_BYTES		= 8,
19a4d61e84SRoland Dreier 	IB_BTH_BYTES		= 12,
2099260132SParav Pandit 	IB_DETH_BYTES		= 8,
2199260132SParav Pandit 	IB_EXT_ATOMICETH_BYTES	= 28,
2299260132SParav Pandit 	IB_EXT_XRC_BYTES	= 4,
2399260132SParav Pandit 	IB_ICRC_BYTES		= 4
24a4d61e84SRoland Dreier };
25a4d61e84SRoland Dreier 
26a4d61e84SRoland Dreier struct ib_field {
27a4d61e84SRoland Dreier 	size_t struct_offset_bytes;
28a4d61e84SRoland Dreier 	size_t struct_size_bytes;
29a4d61e84SRoland Dreier 	int    offset_words;
30a4d61e84SRoland Dreier 	int    offset_bits;
31a4d61e84SRoland Dreier 	int    size_bits;
32a4d61e84SRoland Dreier 	char  *field_name;
33a4d61e84SRoland Dreier };
34a4d61e84SRoland Dreier 
35a4d61e84SRoland Dreier #define RESERVED \
36a4d61e84SRoland Dreier 	.field_name          = "reserved"
37a4d61e84SRoland Dreier 
38a4d61e84SRoland Dreier /*
39a4d61e84SRoland Dreier  * This macro cleans up the definitions of constants for BTH opcodes.
40a4d61e84SRoland Dreier  * It is used to define constants such as IB_OPCODE_UD_SEND_ONLY,
41a4d61e84SRoland Dreier  * which becomes IB_OPCODE_UD + IB_OPCODE_SEND_ONLY, and this gives
42a4d61e84SRoland Dreier  * the correct value.
43a4d61e84SRoland Dreier  *
44a4d61e84SRoland Dreier  * In short, user code should use the constants defined using the
45a4d61e84SRoland Dreier  * macro rather than worrying about adding together other constants.
46a4d61e84SRoland Dreier */
47a4d61e84SRoland Dreier #define IB_OPCODE(transport, op) \
48a4d61e84SRoland Dreier 	IB_OPCODE_ ## transport ## _ ## op = \
49a4d61e84SRoland Dreier 		IB_OPCODE_ ## transport + IB_OPCODE_ ## op
50a4d61e84SRoland Dreier 
51a4d61e84SRoland Dreier enum {
52a4d61e84SRoland Dreier 	/* transport types -- just used to define real constants */
53a4d61e84SRoland Dreier 	IB_OPCODE_RC                                = 0x00,
54a4d61e84SRoland Dreier 	IB_OPCODE_UC                                = 0x20,
55a4d61e84SRoland Dreier 	IB_OPCODE_RD                                = 0x40,
56a4d61e84SRoland Dreier 	IB_OPCODE_UD                                = 0x60,
57931cf9a3SHal Rosenstock 	/* per IBTA 1.3 vol 1 Table 38, A10.3.2 */
58d4ab3470SDennis Dalessandro 	IB_OPCODE_CNP                               = 0x80,
59243d9f43SDon Hiatt 	/* Manufacturer specific */
60243d9f43SDon Hiatt 	IB_OPCODE_MSP                               = 0xe0,
61a4d61e84SRoland Dreier 
62a4d61e84SRoland Dreier 	/* operations -- just used to define real constants */
63a4d61e84SRoland Dreier 	IB_OPCODE_SEND_FIRST                        = 0x00,
64a4d61e84SRoland Dreier 	IB_OPCODE_SEND_MIDDLE                       = 0x01,
65a4d61e84SRoland Dreier 	IB_OPCODE_SEND_LAST                         = 0x02,
66a4d61e84SRoland Dreier 	IB_OPCODE_SEND_LAST_WITH_IMMEDIATE          = 0x03,
67a4d61e84SRoland Dreier 	IB_OPCODE_SEND_ONLY                         = 0x04,
68a4d61e84SRoland Dreier 	IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE          = 0x05,
69a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_WRITE_FIRST                  = 0x06,
70a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_WRITE_MIDDLE                 = 0x07,
71a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_WRITE_LAST                   = 0x08,
72a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE    = 0x09,
73a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_WRITE_ONLY                   = 0x0a,
74a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE    = 0x0b,
75a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_READ_REQUEST                 = 0x0c,
76a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_READ_RESPONSE_FIRST          = 0x0d,
77a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_READ_RESPONSE_MIDDLE         = 0x0e,
78a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_READ_RESPONSE_LAST           = 0x0f,
79a4d61e84SRoland Dreier 	IB_OPCODE_RDMA_READ_RESPONSE_ONLY           = 0x10,
80a4d61e84SRoland Dreier 	IB_OPCODE_ACKNOWLEDGE                       = 0x11,
81a4d61e84SRoland Dreier 	IB_OPCODE_ATOMIC_ACKNOWLEDGE                = 0x12,
82a4d61e84SRoland Dreier 	IB_OPCODE_COMPARE_SWAP                      = 0x13,
83a4d61e84SRoland Dreier 	IB_OPCODE_FETCH_ADD                         = 0x14,
84bf77cc34SJianxin Xiong 	/* opcode 0x15 is reserved */
85bf77cc34SJianxin Xiong 	IB_OPCODE_SEND_LAST_WITH_INVALIDATE         = 0x16,
86bf77cc34SJianxin Xiong 	IB_OPCODE_SEND_ONLY_WITH_INVALIDATE         = 0x17,
87*208e3a13SLi Zhijian 	IB_OPCODE_FLUSH                             = 0x1C,
883ff81e82SXiao Yang 	IB_OPCODE_ATOMIC_WRITE                      = 0x1D,
89a4d61e84SRoland Dreier 
90a4d61e84SRoland Dreier 	/* real constants follow -- see comment about above IB_OPCODE()
91a4d61e84SRoland Dreier 	   macro for more details */
92a4d61e84SRoland Dreier 
93a4d61e84SRoland Dreier 	/* RC */
94a4d61e84SRoland Dreier 	IB_OPCODE(RC, SEND_FIRST),
95a4d61e84SRoland Dreier 	IB_OPCODE(RC, SEND_MIDDLE),
96a4d61e84SRoland Dreier 	IB_OPCODE(RC, SEND_LAST),
97a4d61e84SRoland Dreier 	IB_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE),
98a4d61e84SRoland Dreier 	IB_OPCODE(RC, SEND_ONLY),
99a4d61e84SRoland Dreier 	IB_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE),
100a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_WRITE_FIRST),
101a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_WRITE_MIDDLE),
102a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_WRITE_LAST),
103a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE),
104a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_WRITE_ONLY),
105a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
106a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_READ_REQUEST),
107a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_READ_RESPONSE_FIRST),
108a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE),
109a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_READ_RESPONSE_LAST),
110a4d61e84SRoland Dreier 	IB_OPCODE(RC, RDMA_READ_RESPONSE_ONLY),
111a4d61e84SRoland Dreier 	IB_OPCODE(RC, ACKNOWLEDGE),
112a4d61e84SRoland Dreier 	IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE),
113a4d61e84SRoland Dreier 	IB_OPCODE(RC, COMPARE_SWAP),
114a4d61e84SRoland Dreier 	IB_OPCODE(RC, FETCH_ADD),
115bf77cc34SJianxin Xiong 	IB_OPCODE(RC, SEND_LAST_WITH_INVALIDATE),
116bf77cc34SJianxin Xiong 	IB_OPCODE(RC, SEND_ONLY_WITH_INVALIDATE),
117*208e3a13SLi Zhijian 	IB_OPCODE(RC, FLUSH),
1183ff81e82SXiao Yang 	IB_OPCODE(RC, ATOMIC_WRITE),
119a4d61e84SRoland Dreier 
120a4d61e84SRoland Dreier 	/* UC */
121a4d61e84SRoland Dreier 	IB_OPCODE(UC, SEND_FIRST),
122a4d61e84SRoland Dreier 	IB_OPCODE(UC, SEND_MIDDLE),
123a4d61e84SRoland Dreier 	IB_OPCODE(UC, SEND_LAST),
124a4d61e84SRoland Dreier 	IB_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE),
125a4d61e84SRoland Dreier 	IB_OPCODE(UC, SEND_ONLY),
126a4d61e84SRoland Dreier 	IB_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE),
127a4d61e84SRoland Dreier 	IB_OPCODE(UC, RDMA_WRITE_FIRST),
128a4d61e84SRoland Dreier 	IB_OPCODE(UC, RDMA_WRITE_MIDDLE),
129a4d61e84SRoland Dreier 	IB_OPCODE(UC, RDMA_WRITE_LAST),
130a4d61e84SRoland Dreier 	IB_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE),
131a4d61e84SRoland Dreier 	IB_OPCODE(UC, RDMA_WRITE_ONLY),
132a4d61e84SRoland Dreier 	IB_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
133a4d61e84SRoland Dreier 
134a4d61e84SRoland Dreier 	/* RD */
135a4d61e84SRoland Dreier 	IB_OPCODE(RD, SEND_FIRST),
136a4d61e84SRoland Dreier 	IB_OPCODE(RD, SEND_MIDDLE),
137a4d61e84SRoland Dreier 	IB_OPCODE(RD, SEND_LAST),
138a4d61e84SRoland Dreier 	IB_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE),
139a4d61e84SRoland Dreier 	IB_OPCODE(RD, SEND_ONLY),
140a4d61e84SRoland Dreier 	IB_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE),
141a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_WRITE_FIRST),
142a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_WRITE_MIDDLE),
143a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_WRITE_LAST),
144a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE),
145a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_WRITE_ONLY),
146a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
147a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_READ_REQUEST),
148a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_READ_RESPONSE_FIRST),
149a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE),
150a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_READ_RESPONSE_LAST),
151a4d61e84SRoland Dreier 	IB_OPCODE(RD, RDMA_READ_RESPONSE_ONLY),
152a4d61e84SRoland Dreier 	IB_OPCODE(RD, ACKNOWLEDGE),
153a4d61e84SRoland Dreier 	IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE),
154a4d61e84SRoland Dreier 	IB_OPCODE(RD, COMPARE_SWAP),
155a4d61e84SRoland Dreier 	IB_OPCODE(RD, FETCH_ADD),
156*208e3a13SLi Zhijian 	IB_OPCODE(RD, FLUSH),
157a4d61e84SRoland Dreier 
158a4d61e84SRoland Dreier 	/* UD */
159a4d61e84SRoland Dreier 	IB_OPCODE(UD, SEND_ONLY),
160a4d61e84SRoland Dreier 	IB_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE)
161a4d61e84SRoland Dreier };
162a4d61e84SRoland Dreier 
163a4d61e84SRoland Dreier enum {
164a4d61e84SRoland Dreier 	IB_LNH_RAW        = 0,
165a4d61e84SRoland Dreier 	IB_LNH_IP         = 1,
166a4d61e84SRoland Dreier 	IB_LNH_IBA_LOCAL  = 2,
167a4d61e84SRoland Dreier 	IB_LNH_IBA_GLOBAL = 3
168a4d61e84SRoland Dreier };
169a4d61e84SRoland Dreier 
170a4d61e84SRoland Dreier struct ib_unpacked_lrh {
171a4d61e84SRoland Dreier 	u8        virtual_lane;
172a4d61e84SRoland Dreier 	u8        link_version;
173a4d61e84SRoland Dreier 	u8        service_level;
174a4d61e84SRoland Dreier 	u8        link_next_header;
175a4d61e84SRoland Dreier 	__be16    destination_lid;
176a4d61e84SRoland Dreier 	__be16    packet_length;
177a4d61e84SRoland Dreier 	__be16    source_lid;
178a4d61e84SRoland Dreier };
179a4d61e84SRoland Dreier 
180a4d61e84SRoland Dreier struct ib_unpacked_grh {
181a4d61e84SRoland Dreier 	u8    	     ip_version;
182a4d61e84SRoland Dreier 	u8    	     traffic_class;
183a4d61e84SRoland Dreier 	__be32 	     flow_label;
184a4d61e84SRoland Dreier 	__be16       payload_length;
185a4d61e84SRoland Dreier 	u8    	     next_header;
186a4d61e84SRoland Dreier 	u8    	     hop_limit;
187a4d61e84SRoland Dreier 	union ib_gid source_gid;
188a4d61e84SRoland Dreier 	union ib_gid destination_gid;
189a4d61e84SRoland Dreier };
190a4d61e84SRoland Dreier 
191a4d61e84SRoland Dreier struct ib_unpacked_bth {
192a4d61e84SRoland Dreier 	u8           opcode;
193a4d61e84SRoland Dreier 	u8           solicited_event;
194a4d61e84SRoland Dreier 	u8           mig_req;
195a4d61e84SRoland Dreier 	u8           pad_count;
196a4d61e84SRoland Dreier 	u8           transport_header_version;
197a4d61e84SRoland Dreier 	__be16       pkey;
198a4d61e84SRoland Dreier 	__be32       destination_qpn;
199a4d61e84SRoland Dreier 	u8           ack_req;
200a4d61e84SRoland Dreier 	__be32       psn;
201a4d61e84SRoland Dreier };
202a4d61e84SRoland Dreier 
203a4d61e84SRoland Dreier struct ib_unpacked_deth {
204a4d61e84SRoland Dreier 	__be32       qkey;
205a4d61e84SRoland Dreier 	__be32       source_qpn;
206a4d61e84SRoland Dreier };
207a4d61e84SRoland Dreier 
208ff7f5aabSEli Cohen struct ib_unpacked_eth {
209ff7f5aabSEli Cohen 	u8	dmac_h[4];
210ff7f5aabSEli Cohen 	u8	dmac_l[2];
211ff7f5aabSEli Cohen 	u8	smac_h[2];
212ff7f5aabSEli Cohen 	u8	smac_l[4];
213ff7f5aabSEli Cohen 	__be16	type;
214ff7f5aabSEli Cohen };
215ff7f5aabSEli Cohen 
21625f40220SMoni Shoua struct ib_unpacked_ip4 {
21725f40220SMoni Shoua 	u8	ver;
21825f40220SMoni Shoua 	u8	hdr_len;
21925f40220SMoni Shoua 	u8	tos;
22025f40220SMoni Shoua 	__be16	tot_len;
22125f40220SMoni Shoua 	__be16	id;
22225f40220SMoni Shoua 	__be16	frag_off;
22325f40220SMoni Shoua 	u8	ttl;
22425f40220SMoni Shoua 	u8	protocol;
2253ef967a4SMoni Shoua 	__sum16	check;
22625f40220SMoni Shoua 	__be32	saddr;
22725f40220SMoni Shoua 	__be32	daddr;
22825f40220SMoni Shoua };
22925f40220SMoni Shoua 
23025f40220SMoni Shoua struct ib_unpacked_udp {
23125f40220SMoni Shoua 	__be16	sport;
23225f40220SMoni Shoua 	__be16	dport;
23325f40220SMoni Shoua 	__be16	length;
23425f40220SMoni Shoua 	__be16	csum;
23525f40220SMoni Shoua };
23625f40220SMoni Shoua 
237af7bd463SEli Cohen struct ib_unpacked_vlan {
238af7bd463SEli Cohen 	__be16  tag;
239af7bd463SEli Cohen 	__be16  type;
240af7bd463SEli Cohen };
241af7bd463SEli Cohen 
242a4d61e84SRoland Dreier struct ib_ud_header {
243ff7f5aabSEli Cohen 	int                     lrh_present;
244a4d61e84SRoland Dreier 	struct ib_unpacked_lrh  lrh;
245ff7f5aabSEli Cohen 	int			eth_present;
246ff7f5aabSEli Cohen 	struct ib_unpacked_eth	eth;
247af7bd463SEli Cohen 	int                     vlan_present;
248af7bd463SEli Cohen 	struct ib_unpacked_vlan vlan;
249a4d61e84SRoland Dreier 	int			grh_present;
250a4d61e84SRoland Dreier 	struct ib_unpacked_grh	grh;
25125f40220SMoni Shoua 	int			ipv4_present;
25225f40220SMoni Shoua 	struct ib_unpacked_ip4	ip4;
25325f40220SMoni Shoua 	int			udp_present;
25425f40220SMoni Shoua 	struct ib_unpacked_udp	udp;
255a4d61e84SRoland Dreier 	struct ib_unpacked_bth	bth;
256a4d61e84SRoland Dreier 	struct ib_unpacked_deth deth;
257a4d61e84SRoland Dreier 	int			immediate_present;
258a4d61e84SRoland Dreier 	__be32			immediate_data;
259a4d61e84SRoland Dreier };
260a4d61e84SRoland Dreier 
261a4d61e84SRoland Dreier void ib_pack(const struct ib_field        *desc,
262a4d61e84SRoland Dreier 	     int                           desc_len,
263a4d61e84SRoland Dreier 	     void                         *structure,
264a4d61e84SRoland Dreier 	     void                         *buf);
265a4d61e84SRoland Dreier 
266a4d61e84SRoland Dreier void ib_unpack(const struct ib_field        *desc,
267a4d61e84SRoland Dreier 	       int                           desc_len,
268a4d61e84SRoland Dreier 	       void                         *buf,
269a4d61e84SRoland Dreier 	       void                         *structure);
270a4d61e84SRoland Dreier 
2713ef967a4SMoni Shoua __sum16 ib_ud_ip4_csum(struct ib_ud_header *header);
27225f40220SMoni Shoua 
27325f40220SMoni Shoua int ib_ud_header_init(int		    payload_bytes,
274ff7f5aabSEli Cohen 		      int		    lrh_present,
275ff7f5aabSEli Cohen 		      int		    eth_present,
276af7bd463SEli Cohen 		      int		    vlan_present,
277a4d61e84SRoland Dreier 		      int		    grh_present,
27825f40220SMoni Shoua 		      int		    ip_version,
27925f40220SMoni Shoua 		      int		    udp_present,
280920d706cSEli Cohen 		      int		    immediate_present,
281a4d61e84SRoland Dreier 		      struct ib_ud_header *header);
282a4d61e84SRoland Dreier 
283a4d61e84SRoland Dreier int ib_ud_header_pack(struct ib_ud_header *header,
284a4d61e84SRoland Dreier 		      void                *buf);
285a4d61e84SRoland Dreier 
286a4d61e84SRoland Dreier int ib_ud_header_unpack(void                *buf,
287a4d61e84SRoland Dreier 			struct ib_ud_header *header);
288a4d61e84SRoland Dreier 
289a4d61e84SRoland Dreier #endif /* IB_PACK_H */
290