xref: /OK3568_Linux_fs/kernel/include/rdma/ib_sa.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
4*4882a593Smuzhiyun  * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
5*4882a593Smuzhiyun  * Copyright (c) 2006 Intel Corporation.  All rights reserved.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef IB_SA_H
9*4882a593Smuzhiyun #define IB_SA_H
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/completion.h>
12*4882a593Smuzhiyun #include <linux/compiler.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/atomic.h>
15*4882a593Smuzhiyun #include <linux/netdevice.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <rdma/ib_verbs.h>
18*4882a593Smuzhiyun #include <rdma/ib_mad.h>
19*4882a593Smuzhiyun #include <rdma/ib_addr.h>
20*4882a593Smuzhiyun #include <rdma/opa_addr.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun enum {
23*4882a593Smuzhiyun 	IB_SA_CLASS_VERSION		= 2,	/* IB spec version 1.1/1.2 */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 	IB_SA_METHOD_GET_TABLE		= 0x12,
26*4882a593Smuzhiyun 	IB_SA_METHOD_GET_TABLE_RESP	= 0x92,
27*4882a593Smuzhiyun 	IB_SA_METHOD_DELETE		= 0x15,
28*4882a593Smuzhiyun 	IB_SA_METHOD_DELETE_RESP	= 0x95,
29*4882a593Smuzhiyun 	IB_SA_METHOD_GET_MULTI		= 0x14,
30*4882a593Smuzhiyun 	IB_SA_METHOD_GET_MULTI_RESP	= 0x94,
31*4882a593Smuzhiyun 	IB_SA_METHOD_GET_TRACE_TBL	= 0x13
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #define OPA_SA_CLASS_VERSION	0x80
35*4882a593Smuzhiyun enum {
36*4882a593Smuzhiyun 	IB_SA_ATTR_CLASS_PORTINFO    = 0x01,
37*4882a593Smuzhiyun 	IB_SA_ATTR_NOTICE	     = 0x02,
38*4882a593Smuzhiyun 	IB_SA_ATTR_INFORM_INFO	     = 0x03,
39*4882a593Smuzhiyun 	IB_SA_ATTR_NODE_REC	     = 0x11,
40*4882a593Smuzhiyun 	IB_SA_ATTR_PORT_INFO_REC     = 0x12,
41*4882a593Smuzhiyun 	IB_SA_ATTR_SL2VL_REC	     = 0x13,
42*4882a593Smuzhiyun 	IB_SA_ATTR_SWITCH_REC	     = 0x14,
43*4882a593Smuzhiyun 	IB_SA_ATTR_LINEAR_FDB_REC    = 0x15,
44*4882a593Smuzhiyun 	IB_SA_ATTR_RANDOM_FDB_REC    = 0x16,
45*4882a593Smuzhiyun 	IB_SA_ATTR_MCAST_FDB_REC     = 0x17,
46*4882a593Smuzhiyun 	IB_SA_ATTR_SM_INFO_REC	     = 0x18,
47*4882a593Smuzhiyun 	IB_SA_ATTR_LINK_REC	     = 0x20,
48*4882a593Smuzhiyun 	IB_SA_ATTR_GUID_INFO_REC     = 0x30,
49*4882a593Smuzhiyun 	IB_SA_ATTR_SERVICE_REC	     = 0x31,
50*4882a593Smuzhiyun 	IB_SA_ATTR_PARTITION_REC     = 0x33,
51*4882a593Smuzhiyun 	IB_SA_ATTR_PATH_REC	     = 0x35,
52*4882a593Smuzhiyun 	IB_SA_ATTR_VL_ARB_REC	     = 0x36,
53*4882a593Smuzhiyun 	IB_SA_ATTR_MC_MEMBER_REC     = 0x38,
54*4882a593Smuzhiyun 	IB_SA_ATTR_TRACE_REC	     = 0x39,
55*4882a593Smuzhiyun 	IB_SA_ATTR_MULTI_PATH_REC    = 0x3a,
56*4882a593Smuzhiyun 	IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b,
57*4882a593Smuzhiyun 	IB_SA_ATTR_INFORM_INFO_REC   = 0xf3
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun enum ib_sa_selector {
61*4882a593Smuzhiyun 	IB_SA_GT   = 0,
62*4882a593Smuzhiyun 	IB_SA_LT   = 1,
63*4882a593Smuzhiyun 	IB_SA_EQ   = 2,
64*4882a593Smuzhiyun 	/*
65*4882a593Smuzhiyun 	 * The meaning of "best" depends on the attribute: for
66*4882a593Smuzhiyun 	 * example, for MTU best will return the largest available
67*4882a593Smuzhiyun 	 * MTU, while for packet life time, best will return the
68*4882a593Smuzhiyun 	 * smallest available life time.
69*4882a593Smuzhiyun 	 */
70*4882a593Smuzhiyun 	IB_SA_BEST = 3
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun  * There are 4 types of join states:
75*4882a593Smuzhiyun  * FullMember, NonMember, SendOnlyNonMember, SendOnlyFullMember.
76*4882a593Smuzhiyun  * The order corresponds to JoinState bits in MCMemberRecord.
77*4882a593Smuzhiyun  */
78*4882a593Smuzhiyun enum ib_sa_mc_join_states {
79*4882a593Smuzhiyun 	FULLMEMBER_JOIN,
80*4882a593Smuzhiyun 	NONMEMBER_JOIN,
81*4882a593Smuzhiyun 	SENDONLY_NONMEBER_JOIN,
82*4882a593Smuzhiyun 	SENDONLY_FULLMEMBER_JOIN,
83*4882a593Smuzhiyun 	NUM_JOIN_MEMBERSHIP_TYPES,
84*4882a593Smuzhiyun };
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun #define IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT	BIT(12)
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /*
89*4882a593Smuzhiyun  * Structures for SA records are named "struct ib_sa_xxx_rec."  No
90*4882a593Smuzhiyun  * attempt is made to pack structures to match the physical layout of
91*4882a593Smuzhiyun  * SA records in SA MADs; all packing and unpacking is handled by the
92*4882a593Smuzhiyun  * SA query code.
93*4882a593Smuzhiyun  *
94*4882a593Smuzhiyun  * For a record with structure ib_sa_xxx_rec, the naming convention
95*4882a593Smuzhiyun  * for the component mask value for field yyy is IB_SA_XXX_REC_YYY (we
96*4882a593Smuzhiyun  * never use different abbreviations or otherwise change the spelling
97*4882a593Smuzhiyun  * of xxx/yyy between ib_sa_xxx_rec.yyy and IB_SA_XXX_REC_YYY).
98*4882a593Smuzhiyun  *
99*4882a593Smuzhiyun  * Reserved rows are indicated with comments to help maintainability.
100*4882a593Smuzhiyun  */
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun #define IB_SA_PATH_REC_SERVICE_ID		       (IB_SA_COMP_MASK( 0) |\
103*4882a593Smuzhiyun 							IB_SA_COMP_MASK( 1))
104*4882a593Smuzhiyun #define IB_SA_PATH_REC_DGID				IB_SA_COMP_MASK( 2)
105*4882a593Smuzhiyun #define IB_SA_PATH_REC_SGID				IB_SA_COMP_MASK( 3)
106*4882a593Smuzhiyun #define IB_SA_PATH_REC_DLID				IB_SA_COMP_MASK( 4)
107*4882a593Smuzhiyun #define IB_SA_PATH_REC_SLID				IB_SA_COMP_MASK( 5)
108*4882a593Smuzhiyun #define IB_SA_PATH_REC_RAW_TRAFFIC			IB_SA_COMP_MASK( 6)
109*4882a593Smuzhiyun /* reserved:								 7 */
110*4882a593Smuzhiyun #define IB_SA_PATH_REC_FLOW_LABEL       		IB_SA_COMP_MASK( 8)
111*4882a593Smuzhiyun #define IB_SA_PATH_REC_HOP_LIMIT			IB_SA_COMP_MASK( 9)
112*4882a593Smuzhiyun #define IB_SA_PATH_REC_TRAFFIC_CLASS			IB_SA_COMP_MASK(10)
113*4882a593Smuzhiyun #define IB_SA_PATH_REC_REVERSIBLE			IB_SA_COMP_MASK(11)
114*4882a593Smuzhiyun #define IB_SA_PATH_REC_NUMB_PATH			IB_SA_COMP_MASK(12)
115*4882a593Smuzhiyun #define IB_SA_PATH_REC_PKEY				IB_SA_COMP_MASK(13)
116*4882a593Smuzhiyun #define IB_SA_PATH_REC_QOS_CLASS			IB_SA_COMP_MASK(14)
117*4882a593Smuzhiyun #define IB_SA_PATH_REC_SL				IB_SA_COMP_MASK(15)
118*4882a593Smuzhiyun #define IB_SA_PATH_REC_MTU_SELECTOR			IB_SA_COMP_MASK(16)
119*4882a593Smuzhiyun #define IB_SA_PATH_REC_MTU				IB_SA_COMP_MASK(17)
120*4882a593Smuzhiyun #define IB_SA_PATH_REC_RATE_SELECTOR			IB_SA_COMP_MASK(18)
121*4882a593Smuzhiyun #define IB_SA_PATH_REC_RATE				IB_SA_COMP_MASK(19)
122*4882a593Smuzhiyun #define IB_SA_PATH_REC_PACKET_LIFE_TIME_SELECTOR	IB_SA_COMP_MASK(20)
123*4882a593Smuzhiyun #define IB_SA_PATH_REC_PACKET_LIFE_TIME			IB_SA_COMP_MASK(21)
124*4882a593Smuzhiyun #define IB_SA_PATH_REC_PREFERENCE			IB_SA_COMP_MASK(22)
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun enum sa_path_rec_type {
127*4882a593Smuzhiyun 	SA_PATH_REC_TYPE_IB,
128*4882a593Smuzhiyun 	SA_PATH_REC_TYPE_ROCE_V1,
129*4882a593Smuzhiyun 	SA_PATH_REC_TYPE_ROCE_V2,
130*4882a593Smuzhiyun 	SA_PATH_REC_TYPE_OPA
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun struct sa_path_rec_ib {
134*4882a593Smuzhiyun 	__be16       dlid;
135*4882a593Smuzhiyun 	__be16       slid;
136*4882a593Smuzhiyun 	u8           raw_traffic;
137*4882a593Smuzhiyun };
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /**
140*4882a593Smuzhiyun  * struct sa_path_rec_roce - RoCE specific portion of the path record entry
141*4882a593Smuzhiyun  * @route_resolved:	When set, it indicates that this route is already
142*4882a593Smuzhiyun  *			resolved for this path record entry.
143*4882a593Smuzhiyun  * @dmac:		Destination mac address for the given DGID entry
144*4882a593Smuzhiyun  *			of the path record entry.
145*4882a593Smuzhiyun  */
146*4882a593Smuzhiyun struct sa_path_rec_roce {
147*4882a593Smuzhiyun 	bool	route_resolved;
148*4882a593Smuzhiyun 	u8	dmac[ETH_ALEN];
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun struct sa_path_rec_opa {
152*4882a593Smuzhiyun 	__be32       dlid;
153*4882a593Smuzhiyun 	__be32       slid;
154*4882a593Smuzhiyun 	u8           raw_traffic;
155*4882a593Smuzhiyun 	u8	     l2_8B;
156*4882a593Smuzhiyun 	u8	     l2_10B;
157*4882a593Smuzhiyun 	u8	     l2_9B;
158*4882a593Smuzhiyun 	u8	     l2_16B;
159*4882a593Smuzhiyun 	u8	     qos_type;
160*4882a593Smuzhiyun 	u8	     qos_priority;
161*4882a593Smuzhiyun };
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun struct sa_path_rec {
164*4882a593Smuzhiyun 	union ib_gid dgid;
165*4882a593Smuzhiyun 	union ib_gid sgid;
166*4882a593Smuzhiyun 	__be64       service_id;
167*4882a593Smuzhiyun 	/* reserved */
168*4882a593Smuzhiyun 	__be32       flow_label;
169*4882a593Smuzhiyun 	u8           hop_limit;
170*4882a593Smuzhiyun 	u8           traffic_class;
171*4882a593Smuzhiyun 	u8           reversible;
172*4882a593Smuzhiyun 	u8           numb_path;
173*4882a593Smuzhiyun 	__be16       pkey;
174*4882a593Smuzhiyun 	__be16       qos_class;
175*4882a593Smuzhiyun 	u8           sl;
176*4882a593Smuzhiyun 	u8           mtu_selector;
177*4882a593Smuzhiyun 	u8           mtu;
178*4882a593Smuzhiyun 	u8           rate_selector;
179*4882a593Smuzhiyun 	u8           rate;
180*4882a593Smuzhiyun 	u8           packet_life_time_selector;
181*4882a593Smuzhiyun 	u8           packet_life_time;
182*4882a593Smuzhiyun 	u8           preference;
183*4882a593Smuzhiyun 	union {
184*4882a593Smuzhiyun 		struct sa_path_rec_ib ib;
185*4882a593Smuzhiyun 		struct sa_path_rec_roce roce;
186*4882a593Smuzhiyun 		struct sa_path_rec_opa opa;
187*4882a593Smuzhiyun 	};
188*4882a593Smuzhiyun 	enum sa_path_rec_type rec_type;
189*4882a593Smuzhiyun };
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun static inline enum ib_gid_type
sa_conv_pathrec_to_gid_type(struct sa_path_rec * rec)192*4882a593Smuzhiyun 		sa_conv_pathrec_to_gid_type(struct sa_path_rec *rec)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun 	switch (rec->rec_type) {
195*4882a593Smuzhiyun 	case SA_PATH_REC_TYPE_ROCE_V1:
196*4882a593Smuzhiyun 		return IB_GID_TYPE_ROCE;
197*4882a593Smuzhiyun 	case SA_PATH_REC_TYPE_ROCE_V2:
198*4882a593Smuzhiyun 		return IB_GID_TYPE_ROCE_UDP_ENCAP;
199*4882a593Smuzhiyun 	default:
200*4882a593Smuzhiyun 		return IB_GID_TYPE_IB;
201*4882a593Smuzhiyun 	}
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun static inline enum sa_path_rec_type
sa_conv_gid_to_pathrec_type(enum ib_gid_type type)205*4882a593Smuzhiyun 		sa_conv_gid_to_pathrec_type(enum ib_gid_type type)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	switch (type) {
208*4882a593Smuzhiyun 	case IB_GID_TYPE_ROCE:
209*4882a593Smuzhiyun 		return SA_PATH_REC_TYPE_ROCE_V1;
210*4882a593Smuzhiyun 	case IB_GID_TYPE_ROCE_UDP_ENCAP:
211*4882a593Smuzhiyun 		return SA_PATH_REC_TYPE_ROCE_V2;
212*4882a593Smuzhiyun 	default:
213*4882a593Smuzhiyun 		return SA_PATH_REC_TYPE_IB;
214*4882a593Smuzhiyun 	}
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun 
path_conv_opa_to_ib(struct sa_path_rec * ib,struct sa_path_rec * opa)217*4882a593Smuzhiyun static inline void path_conv_opa_to_ib(struct sa_path_rec *ib,
218*4882a593Smuzhiyun 				       struct sa_path_rec *opa)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun 	if ((be32_to_cpu(opa->opa.dlid) >=
221*4882a593Smuzhiyun 	     be16_to_cpu(IB_MULTICAST_LID_BASE)) ||
222*4882a593Smuzhiyun 	    (be32_to_cpu(opa->opa.slid) >=
223*4882a593Smuzhiyun 	     be16_to_cpu(IB_MULTICAST_LID_BASE))) {
224*4882a593Smuzhiyun 		/* Create OPA GID and zero out the LID */
225*4882a593Smuzhiyun 		ib->dgid.global.interface_id
226*4882a593Smuzhiyun 				= OPA_MAKE_ID(be32_to_cpu(opa->opa.dlid));
227*4882a593Smuzhiyun 		ib->dgid.global.subnet_prefix
228*4882a593Smuzhiyun 				= opa->dgid.global.subnet_prefix;
229*4882a593Smuzhiyun 		ib->sgid.global.interface_id
230*4882a593Smuzhiyun 				= OPA_MAKE_ID(be32_to_cpu(opa->opa.slid));
231*4882a593Smuzhiyun 		ib->dgid.global.subnet_prefix
232*4882a593Smuzhiyun 				= opa->dgid.global.subnet_prefix;
233*4882a593Smuzhiyun 		ib->ib.dlid	= 0;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 		ib->ib.slid	= 0;
236*4882a593Smuzhiyun 	} else {
237*4882a593Smuzhiyun 		ib->ib.dlid	= htons(ntohl(opa->opa.dlid));
238*4882a593Smuzhiyun 		ib->ib.slid	= htons(ntohl(opa->opa.slid));
239*4882a593Smuzhiyun 	}
240*4882a593Smuzhiyun 	ib->service_id		= opa->service_id;
241*4882a593Smuzhiyun 	ib->ib.raw_traffic	= opa->opa.raw_traffic;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
path_conv_ib_to_opa(struct sa_path_rec * opa,struct sa_path_rec * ib)244*4882a593Smuzhiyun static inline void path_conv_ib_to_opa(struct sa_path_rec *opa,
245*4882a593Smuzhiyun 				       struct sa_path_rec *ib)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun 	__be32 slid, dlid;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	if ((ib_is_opa_gid(&ib->sgid)) ||
250*4882a593Smuzhiyun 	    (ib_is_opa_gid(&ib->dgid))) {
251*4882a593Smuzhiyun 		slid = htonl(opa_get_lid_from_gid(&ib->sgid));
252*4882a593Smuzhiyun 		dlid = htonl(opa_get_lid_from_gid(&ib->dgid));
253*4882a593Smuzhiyun 	} else {
254*4882a593Smuzhiyun 		slid = htonl(ntohs(ib->ib.slid));
255*4882a593Smuzhiyun 		dlid = htonl(ntohs(ib->ib.dlid));
256*4882a593Smuzhiyun 	}
257*4882a593Smuzhiyun 	opa->opa.slid		= slid;
258*4882a593Smuzhiyun 	opa->opa.dlid		= dlid;
259*4882a593Smuzhiyun 	opa->service_id		= ib->service_id;
260*4882a593Smuzhiyun 	opa->opa.raw_traffic	= ib->ib.raw_traffic;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun /* Convert from OPA to IB path record */
sa_convert_path_opa_to_ib(struct sa_path_rec * dest,struct sa_path_rec * src)264*4882a593Smuzhiyun static inline void sa_convert_path_opa_to_ib(struct sa_path_rec *dest,
265*4882a593Smuzhiyun 					     struct sa_path_rec *src)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	if (src->rec_type != SA_PATH_REC_TYPE_OPA)
268*4882a593Smuzhiyun 		return;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	*dest = *src;
271*4882a593Smuzhiyun 	dest->rec_type = SA_PATH_REC_TYPE_IB;
272*4882a593Smuzhiyun 	path_conv_opa_to_ib(dest, src);
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun /* Convert from IB to OPA path record */
sa_convert_path_ib_to_opa(struct sa_path_rec * dest,struct sa_path_rec * src)276*4882a593Smuzhiyun static inline void sa_convert_path_ib_to_opa(struct sa_path_rec *dest,
277*4882a593Smuzhiyun 					     struct sa_path_rec *src)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun 	if (src->rec_type != SA_PATH_REC_TYPE_IB)
280*4882a593Smuzhiyun 		return;
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	/* Do a structure copy and overwrite the relevant fields */
283*4882a593Smuzhiyun 	*dest = *src;
284*4882a593Smuzhiyun 	dest->rec_type = SA_PATH_REC_TYPE_OPA;
285*4882a593Smuzhiyun 	path_conv_ib_to_opa(dest, src);
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_MGID				IB_SA_COMP_MASK( 0)
289*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_PORT_GID			IB_SA_COMP_MASK( 1)
290*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_QKEY				IB_SA_COMP_MASK( 2)
291*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_MLID				IB_SA_COMP_MASK( 3)
292*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_MTU_SELECTOR			IB_SA_COMP_MASK( 4)
293*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_MTU				IB_SA_COMP_MASK( 5)
294*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS		IB_SA_COMP_MASK( 6)
295*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_PKEY				IB_SA_COMP_MASK( 7)
296*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_RATE_SELECTOR		IB_SA_COMP_MASK( 8)
297*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_RATE				IB_SA_COMP_MASK( 9)
298*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR	IB_SA_COMP_MASK(10)
299*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME		IB_SA_COMP_MASK(11)
300*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_SL				IB_SA_COMP_MASK(12)
301*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_FLOW_LABEL			IB_SA_COMP_MASK(13)
302*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_HOP_LIMIT			IB_SA_COMP_MASK(14)
303*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_SCOPE			IB_SA_COMP_MASK(15)
304*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_JOIN_STATE			IB_SA_COMP_MASK(16)
305*4882a593Smuzhiyun #define IB_SA_MCMEMBER_REC_PROXY_JOIN			IB_SA_COMP_MASK(17)
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun struct ib_sa_mcmember_rec {
308*4882a593Smuzhiyun 	union ib_gid mgid;
309*4882a593Smuzhiyun 	union ib_gid port_gid;
310*4882a593Smuzhiyun 	__be32       qkey;
311*4882a593Smuzhiyun 	__be16       mlid;
312*4882a593Smuzhiyun 	u8           mtu_selector;
313*4882a593Smuzhiyun 	u8           mtu;
314*4882a593Smuzhiyun 	u8           traffic_class;
315*4882a593Smuzhiyun 	__be16       pkey;
316*4882a593Smuzhiyun 	u8 	     rate_selector;
317*4882a593Smuzhiyun 	u8 	     rate;
318*4882a593Smuzhiyun 	u8 	     packet_life_time_selector;
319*4882a593Smuzhiyun 	u8 	     packet_life_time;
320*4882a593Smuzhiyun 	u8           sl;
321*4882a593Smuzhiyun 	__be32       flow_label;
322*4882a593Smuzhiyun 	u8           hop_limit;
323*4882a593Smuzhiyun 	u8           scope;
324*4882a593Smuzhiyun 	u8           join_state;
325*4882a593Smuzhiyun 	u8           proxy_join;
326*4882a593Smuzhiyun };
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun /* Service Record Component Mask Sec 15.2.5.14 Ver 1.1	*/
329*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_ID			IB_SA_COMP_MASK( 0)
330*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_GID			IB_SA_COMP_MASK( 1)
331*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_PKEY			IB_SA_COMP_MASK( 2)
332*4882a593Smuzhiyun /* reserved:								 3 */
333*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_LEASE			IB_SA_COMP_MASK( 4)
334*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_KEY			IB_SA_COMP_MASK( 5)
335*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_NAME			IB_SA_COMP_MASK( 6)
336*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_0		IB_SA_COMP_MASK( 7)
337*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_1		IB_SA_COMP_MASK( 8)
338*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_2		IB_SA_COMP_MASK( 9)
339*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_3		IB_SA_COMP_MASK(10)
340*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_4		IB_SA_COMP_MASK(11)
341*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_5		IB_SA_COMP_MASK(12)
342*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_6		IB_SA_COMP_MASK(13)
343*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_7		IB_SA_COMP_MASK(14)
344*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_8		IB_SA_COMP_MASK(15)
345*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_9		IB_SA_COMP_MASK(16)
346*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_10		IB_SA_COMP_MASK(17)
347*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_11		IB_SA_COMP_MASK(18)
348*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_12		IB_SA_COMP_MASK(19)
349*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_13		IB_SA_COMP_MASK(20)
350*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_14		IB_SA_COMP_MASK(21)
351*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA8_15		IB_SA_COMP_MASK(22)
352*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA16_0		IB_SA_COMP_MASK(23)
353*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA16_1		IB_SA_COMP_MASK(24)
354*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA16_2		IB_SA_COMP_MASK(25)
355*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA16_3		IB_SA_COMP_MASK(26)
356*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA16_4		IB_SA_COMP_MASK(27)
357*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA16_5		IB_SA_COMP_MASK(28)
358*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA16_6		IB_SA_COMP_MASK(29)
359*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA16_7		IB_SA_COMP_MASK(30)
360*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA32_0		IB_SA_COMP_MASK(31)
361*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA32_1		IB_SA_COMP_MASK(32)
362*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA32_2		IB_SA_COMP_MASK(33)
363*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA32_3		IB_SA_COMP_MASK(34)
364*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA64_0		IB_SA_COMP_MASK(35)
365*4882a593Smuzhiyun #define IB_SA_SERVICE_REC_SERVICE_DATA64_1		IB_SA_COMP_MASK(36)
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun #define IB_DEFAULT_SERVICE_LEASE 	0xFFFFFFFF
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun struct ib_sa_service_rec {
370*4882a593Smuzhiyun 	u64		id;
371*4882a593Smuzhiyun 	union ib_gid	gid;
372*4882a593Smuzhiyun 	__be16 		pkey;
373*4882a593Smuzhiyun 	/* reserved */
374*4882a593Smuzhiyun 	u32		lease;
375*4882a593Smuzhiyun 	u8		key[16];
376*4882a593Smuzhiyun 	u8		name[64];
377*4882a593Smuzhiyun 	u8		data8[16];
378*4882a593Smuzhiyun 	u16		data16[8];
379*4882a593Smuzhiyun 	u32		data32[4];
380*4882a593Smuzhiyun 	u64		data64[2];
381*4882a593Smuzhiyun };
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_LID		IB_SA_COMP_MASK(0)
384*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_BLOCK_NUM	IB_SA_COMP_MASK(1)
385*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_RES1		IB_SA_COMP_MASK(2)
386*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_RES2		IB_SA_COMP_MASK(3)
387*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_GID0		IB_SA_COMP_MASK(4)
388*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_GID1		IB_SA_COMP_MASK(5)
389*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_GID2		IB_SA_COMP_MASK(6)
390*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_GID3		IB_SA_COMP_MASK(7)
391*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_GID4		IB_SA_COMP_MASK(8)
392*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_GID5		IB_SA_COMP_MASK(9)
393*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_GID6		IB_SA_COMP_MASK(10)
394*4882a593Smuzhiyun #define IB_SA_GUIDINFO_REC_GID7		IB_SA_COMP_MASK(11)
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun struct ib_sa_guidinfo_rec {
397*4882a593Smuzhiyun 	__be16	lid;
398*4882a593Smuzhiyun 	u8	block_num;
399*4882a593Smuzhiyun 	/* reserved */
400*4882a593Smuzhiyun 	u8	res1;
401*4882a593Smuzhiyun 	__be32	res2;
402*4882a593Smuzhiyun 	u8	guid_info_list[64];
403*4882a593Smuzhiyun };
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun struct ib_sa_client {
406*4882a593Smuzhiyun 	atomic_t users;
407*4882a593Smuzhiyun 	struct completion comp;
408*4882a593Smuzhiyun };
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun /**
411*4882a593Smuzhiyun  * ib_sa_register_client - Register an SA client.
412*4882a593Smuzhiyun  */
413*4882a593Smuzhiyun void ib_sa_register_client(struct ib_sa_client *client);
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun /**
416*4882a593Smuzhiyun  * ib_sa_unregister_client - Deregister an SA client.
417*4882a593Smuzhiyun  * @client: Client object to deregister.
418*4882a593Smuzhiyun  */
419*4882a593Smuzhiyun void ib_sa_unregister_client(struct ib_sa_client *client);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun struct ib_sa_query;
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun void ib_sa_cancel_query(int id, struct ib_sa_query *query);
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun int ib_sa_path_rec_get(struct ib_sa_client *client, struct ib_device *device,
426*4882a593Smuzhiyun 		       u8 port_num, struct sa_path_rec *rec,
427*4882a593Smuzhiyun 		       ib_sa_comp_mask comp_mask, unsigned long timeout_ms,
428*4882a593Smuzhiyun 		       gfp_t gfp_mask,
429*4882a593Smuzhiyun 		       void (*callback)(int status, struct sa_path_rec *resp,
430*4882a593Smuzhiyun 					void *context),
431*4882a593Smuzhiyun 		       void *context, struct ib_sa_query **query);
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun int ib_sa_service_rec_query(struct ib_sa_client *client,
434*4882a593Smuzhiyun 			    struct ib_device *device, u8 port_num, u8 method,
435*4882a593Smuzhiyun 			    struct ib_sa_service_rec *rec,
436*4882a593Smuzhiyun 			    ib_sa_comp_mask comp_mask, unsigned long timeout_ms,
437*4882a593Smuzhiyun 			    gfp_t gfp_mask,
438*4882a593Smuzhiyun 			    void (*callback)(int status,
439*4882a593Smuzhiyun 					     struct ib_sa_service_rec *resp,
440*4882a593Smuzhiyun 					     void *context),
441*4882a593Smuzhiyun 			    void *context, struct ib_sa_query **sa_query);
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun struct ib_sa_multicast {
444*4882a593Smuzhiyun 	struct ib_sa_mcmember_rec rec;
445*4882a593Smuzhiyun 	ib_sa_comp_mask		comp_mask;
446*4882a593Smuzhiyun 	int			(*callback)(int status,
447*4882a593Smuzhiyun 					    struct ib_sa_multicast *multicast);
448*4882a593Smuzhiyun 	void			*context;
449*4882a593Smuzhiyun };
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun /**
452*4882a593Smuzhiyun  * ib_sa_join_multicast - Initiates a join request to the specified multicast
453*4882a593Smuzhiyun  *   group.
454*4882a593Smuzhiyun  * @client: SA client
455*4882a593Smuzhiyun  * @device: Device associated with the multicast group.
456*4882a593Smuzhiyun  * @port_num: Port on the specified device to associate with the multicast
457*4882a593Smuzhiyun  *   group.
458*4882a593Smuzhiyun  * @rec: SA multicast member record specifying group attributes.
459*4882a593Smuzhiyun  * @comp_mask: Component mask indicating which group attributes of %rec are
460*4882a593Smuzhiyun  *   valid.
461*4882a593Smuzhiyun  * @gfp_mask: GFP mask for memory allocations.
462*4882a593Smuzhiyun  * @callback: User callback invoked once the join operation completes.
463*4882a593Smuzhiyun  * @context: User specified context stored with the ib_sa_multicast structure.
464*4882a593Smuzhiyun  *
465*4882a593Smuzhiyun  * This call initiates a multicast join request with the SA for the specified
466*4882a593Smuzhiyun  * multicast group.  If the join operation is started successfully, it returns
467*4882a593Smuzhiyun  * an ib_sa_multicast structure that is used to track the multicast operation.
468*4882a593Smuzhiyun  * Users must free this structure by calling ib_free_multicast, even if the
469*4882a593Smuzhiyun  * join operation later fails.  (The callback status is non-zero.)
470*4882a593Smuzhiyun  *
471*4882a593Smuzhiyun  * If the join operation fails; status will be non-zero, with the following
472*4882a593Smuzhiyun  * failures possible:
473*4882a593Smuzhiyun  * -ETIMEDOUT: The request timed out.
474*4882a593Smuzhiyun  * -EIO: An error occurred sending the query.
475*4882a593Smuzhiyun  * -EINVAL: The MCMemberRecord values differed from the existing group's.
476*4882a593Smuzhiyun  * -ENETRESET: Indicates that an fatal error has occurred on the multicast
477*4882a593Smuzhiyun  *   group, and the user must rejoin the group to continue using it.
478*4882a593Smuzhiyun  */
479*4882a593Smuzhiyun struct ib_sa_multicast *ib_sa_join_multicast(struct ib_sa_client *client,
480*4882a593Smuzhiyun 					     struct ib_device *device, u8 port_num,
481*4882a593Smuzhiyun 					     struct ib_sa_mcmember_rec *rec,
482*4882a593Smuzhiyun 					     ib_sa_comp_mask comp_mask, gfp_t gfp_mask,
483*4882a593Smuzhiyun 					     int (*callback)(int status,
484*4882a593Smuzhiyun 							     struct ib_sa_multicast
485*4882a593Smuzhiyun 								    *multicast),
486*4882a593Smuzhiyun 					     void *context);
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun /**
489*4882a593Smuzhiyun  * ib_free_multicast - Frees the multicast tracking structure, and releases
490*4882a593Smuzhiyun  *    any reference on the multicast group.
491*4882a593Smuzhiyun  * @multicast: Multicast tracking structure allocated by ib_join_multicast.
492*4882a593Smuzhiyun  *
493*4882a593Smuzhiyun  * This call blocks until the multicast identifier is destroyed.  It may
494*4882a593Smuzhiyun  * not be called from within the multicast callback; however, returning a non-
495*4882a593Smuzhiyun  * zero value from the callback will result in destroying the multicast
496*4882a593Smuzhiyun  * tracking structure.
497*4882a593Smuzhiyun  */
498*4882a593Smuzhiyun void ib_sa_free_multicast(struct ib_sa_multicast *multicast);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun /**
501*4882a593Smuzhiyun  * ib_get_mcmember_rec - Looks up a multicast member record by its MGID and
502*4882a593Smuzhiyun  *   returns it if found.
503*4882a593Smuzhiyun  * @device: Device associated with the multicast group.
504*4882a593Smuzhiyun  * @port_num: Port on the specified device to associate with the multicast
505*4882a593Smuzhiyun  *   group.
506*4882a593Smuzhiyun  * @mgid: MGID of multicast group.
507*4882a593Smuzhiyun  * @rec: Location to copy SA multicast member record.
508*4882a593Smuzhiyun  */
509*4882a593Smuzhiyun int ib_sa_get_mcmember_rec(struct ib_device *device, u8 port_num,
510*4882a593Smuzhiyun 			   union ib_gid *mgid, struct ib_sa_mcmember_rec *rec);
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun /**
513*4882a593Smuzhiyun  * ib_init_ah_from_mcmember - Initialize address handle attributes based on
514*4882a593Smuzhiyun  * an SA multicast member record.
515*4882a593Smuzhiyun  */
516*4882a593Smuzhiyun int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num,
517*4882a593Smuzhiyun 			     struct ib_sa_mcmember_rec *rec,
518*4882a593Smuzhiyun 			     struct net_device *ndev,
519*4882a593Smuzhiyun 			     enum ib_gid_type gid_type,
520*4882a593Smuzhiyun 			     struct rdma_ah_attr *ah_attr);
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num,
523*4882a593Smuzhiyun 			      struct sa_path_rec *rec,
524*4882a593Smuzhiyun 			      struct rdma_ah_attr *ah_attr,
525*4882a593Smuzhiyun 			      const struct ib_gid_attr *sgid_attr);
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun /**
528*4882a593Smuzhiyun  * ib_sa_pack_path - Conert a path record from struct ib_sa_path_rec
529*4882a593Smuzhiyun  * to IB MAD wire format.
530*4882a593Smuzhiyun  */
531*4882a593Smuzhiyun void ib_sa_pack_path(struct sa_path_rec *rec, void *attribute);
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun /**
534*4882a593Smuzhiyun  * ib_sa_unpack_path - Convert a path record from MAD format to struct
535*4882a593Smuzhiyun  * ib_sa_path_rec.
536*4882a593Smuzhiyun  */
537*4882a593Smuzhiyun void ib_sa_unpack_path(void *attribute, struct sa_path_rec *rec);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun /* Support GuidInfoRecord */
540*4882a593Smuzhiyun int ib_sa_guid_info_rec_query(struct ib_sa_client *client,
541*4882a593Smuzhiyun 			      struct ib_device *device, u8 port_num,
542*4882a593Smuzhiyun 			      struct ib_sa_guidinfo_rec *rec,
543*4882a593Smuzhiyun 			      ib_sa_comp_mask comp_mask, u8 method,
544*4882a593Smuzhiyun 			      unsigned long timeout_ms, gfp_t gfp_mask,
545*4882a593Smuzhiyun 			      void (*callback)(int status,
546*4882a593Smuzhiyun 					       struct ib_sa_guidinfo_rec *resp,
547*4882a593Smuzhiyun 					       void *context),
548*4882a593Smuzhiyun 			      void *context, struct ib_sa_query **sa_query);
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun bool ib_sa_sendonly_fullmem_support(struct ib_sa_client *client,
551*4882a593Smuzhiyun 				    struct ib_device *device,
552*4882a593Smuzhiyun 				    u8 port_num);
553*4882a593Smuzhiyun 
sa_path_is_roce(struct sa_path_rec * rec)554*4882a593Smuzhiyun static inline bool sa_path_is_roce(struct sa_path_rec *rec)
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun 	return ((rec->rec_type == SA_PATH_REC_TYPE_ROCE_V1) ||
557*4882a593Smuzhiyun 		(rec->rec_type == SA_PATH_REC_TYPE_ROCE_V2));
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun 
sa_path_is_opa(struct sa_path_rec * rec)560*4882a593Smuzhiyun static inline bool sa_path_is_opa(struct sa_path_rec *rec)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	return (rec->rec_type == SA_PATH_REC_TYPE_OPA);
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun 
sa_path_set_slid(struct sa_path_rec * rec,u32 slid)565*4882a593Smuzhiyun static inline void sa_path_set_slid(struct sa_path_rec *rec, u32 slid)
566*4882a593Smuzhiyun {
567*4882a593Smuzhiyun 	if (rec->rec_type == SA_PATH_REC_TYPE_IB)
568*4882a593Smuzhiyun 		rec->ib.slid = cpu_to_be16(slid);
569*4882a593Smuzhiyun 	else if (rec->rec_type == SA_PATH_REC_TYPE_OPA)
570*4882a593Smuzhiyun 		rec->opa.slid = cpu_to_be32(slid);
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
sa_path_set_dlid(struct sa_path_rec * rec,u32 dlid)573*4882a593Smuzhiyun static inline void sa_path_set_dlid(struct sa_path_rec *rec, u32 dlid)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	if (rec->rec_type == SA_PATH_REC_TYPE_IB)
576*4882a593Smuzhiyun 		rec->ib.dlid = cpu_to_be16(dlid);
577*4882a593Smuzhiyun 	else if (rec->rec_type == SA_PATH_REC_TYPE_OPA)
578*4882a593Smuzhiyun 		rec->opa.dlid = cpu_to_be32(dlid);
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun 
sa_path_set_raw_traffic(struct sa_path_rec * rec,u8 raw_traffic)581*4882a593Smuzhiyun static inline void sa_path_set_raw_traffic(struct sa_path_rec *rec,
582*4882a593Smuzhiyun 					   u8 raw_traffic)
583*4882a593Smuzhiyun {
584*4882a593Smuzhiyun 	if (rec->rec_type == SA_PATH_REC_TYPE_IB)
585*4882a593Smuzhiyun 		rec->ib.raw_traffic = raw_traffic;
586*4882a593Smuzhiyun 	else if (rec->rec_type == SA_PATH_REC_TYPE_OPA)
587*4882a593Smuzhiyun 		rec->opa.raw_traffic = raw_traffic;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun 
sa_path_get_slid(struct sa_path_rec * rec)590*4882a593Smuzhiyun static inline __be32 sa_path_get_slid(struct sa_path_rec *rec)
591*4882a593Smuzhiyun {
592*4882a593Smuzhiyun 	if (rec->rec_type == SA_PATH_REC_TYPE_IB)
593*4882a593Smuzhiyun 		return htonl(ntohs(rec->ib.slid));
594*4882a593Smuzhiyun 	else if (rec->rec_type == SA_PATH_REC_TYPE_OPA)
595*4882a593Smuzhiyun 		return rec->opa.slid;
596*4882a593Smuzhiyun 	return 0;
597*4882a593Smuzhiyun }
598*4882a593Smuzhiyun 
sa_path_get_dlid(struct sa_path_rec * rec)599*4882a593Smuzhiyun static inline __be32 sa_path_get_dlid(struct sa_path_rec *rec)
600*4882a593Smuzhiyun {
601*4882a593Smuzhiyun 	if (rec->rec_type == SA_PATH_REC_TYPE_IB)
602*4882a593Smuzhiyun 		return htonl(ntohs(rec->ib.dlid));
603*4882a593Smuzhiyun 	else if (rec->rec_type == SA_PATH_REC_TYPE_OPA)
604*4882a593Smuzhiyun 		return rec->opa.dlid;
605*4882a593Smuzhiyun 	return 0;
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun 
sa_path_get_raw_traffic(struct sa_path_rec * rec)608*4882a593Smuzhiyun static inline u8 sa_path_get_raw_traffic(struct sa_path_rec *rec)
609*4882a593Smuzhiyun {
610*4882a593Smuzhiyun 	if (rec->rec_type == SA_PATH_REC_TYPE_IB)
611*4882a593Smuzhiyun 		return rec->ib.raw_traffic;
612*4882a593Smuzhiyun 	else if (rec->rec_type == SA_PATH_REC_TYPE_OPA)
613*4882a593Smuzhiyun 		return rec->opa.raw_traffic;
614*4882a593Smuzhiyun 	return 0;
615*4882a593Smuzhiyun }
616*4882a593Smuzhiyun 
sa_path_set_dmac(struct sa_path_rec * rec,u8 * dmac)617*4882a593Smuzhiyun static inline void sa_path_set_dmac(struct sa_path_rec *rec, u8 *dmac)
618*4882a593Smuzhiyun {
619*4882a593Smuzhiyun 	if (sa_path_is_roce(rec))
620*4882a593Smuzhiyun 		memcpy(rec->roce.dmac, dmac, ETH_ALEN);
621*4882a593Smuzhiyun }
622*4882a593Smuzhiyun 
sa_path_set_dmac_zero(struct sa_path_rec * rec)623*4882a593Smuzhiyun static inline void sa_path_set_dmac_zero(struct sa_path_rec *rec)
624*4882a593Smuzhiyun {
625*4882a593Smuzhiyun 	if (sa_path_is_roce(rec))
626*4882a593Smuzhiyun 		eth_zero_addr(rec->roce.dmac);
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun 
sa_path_get_dmac(struct sa_path_rec * rec)629*4882a593Smuzhiyun static inline u8 *sa_path_get_dmac(struct sa_path_rec *rec)
630*4882a593Smuzhiyun {
631*4882a593Smuzhiyun 	if (sa_path_is_roce(rec))
632*4882a593Smuzhiyun 		return rec->roce.dmac;
633*4882a593Smuzhiyun 	return NULL;
634*4882a593Smuzhiyun }
635*4882a593Smuzhiyun #endif /* IB_SA_H */
636