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