xref: /freebsd/contrib/ofed/opensm/libvendor/osm_vendor_mtl.c (revision 87181516ef48be852d5e5fee53c6e0dbfc62f21e)
1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky  * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3*d6b92ffaSHans Petter Selasky  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4*d6b92ffaSHans Petter Selasky  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5*d6b92ffaSHans Petter Selasky  *
6*d6b92ffaSHans Petter Selasky  * This software is available to you under a choice of one of two
7*d6b92ffaSHans Petter Selasky  * licenses.  You may choose to be licensed under the terms of the GNU
8*d6b92ffaSHans Petter Selasky  * General Public License (GPL) Version 2, available from the file
9*d6b92ffaSHans Petter Selasky  * COPYING in the main directory of this source tree, or the
10*d6b92ffaSHans Petter Selasky  * OpenIB.org BSD license below:
11*d6b92ffaSHans Petter Selasky  *
12*d6b92ffaSHans Petter Selasky  *     Redistribution and use in source and binary forms, with or
13*d6b92ffaSHans Petter Selasky  *     without modification, are permitted provided that the following
14*d6b92ffaSHans Petter Selasky  *     conditions are met:
15*d6b92ffaSHans Petter Selasky  *
16*d6b92ffaSHans Petter Selasky  *      - Redistributions of source code must retain the above
17*d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
18*d6b92ffaSHans Petter Selasky  *        disclaimer.
19*d6b92ffaSHans Petter Selasky  *
20*d6b92ffaSHans Petter Selasky  *      - Redistributions in binary form must reproduce the above
21*d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
22*d6b92ffaSHans Petter Selasky  *        disclaimer in the documentation and/or other materials
23*d6b92ffaSHans Petter Selasky  *        provided with the distribution.
24*d6b92ffaSHans Petter Selasky  *
25*d6b92ffaSHans Petter Selasky  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26*d6b92ffaSHans Petter Selasky  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27*d6b92ffaSHans Petter Selasky  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28*d6b92ffaSHans Petter Selasky  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29*d6b92ffaSHans Petter Selasky  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30*d6b92ffaSHans Petter Selasky  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31*d6b92ffaSHans Petter Selasky  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32*d6b92ffaSHans Petter Selasky  * SOFTWARE.
33*d6b92ffaSHans Petter Selasky  *
34*d6b92ffaSHans Petter Selasky  */
35*d6b92ffaSHans Petter Selasky 
36*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
37*d6b92ffaSHans Petter Selasky #  include <config.h>
38*d6b92ffaSHans Petter Selasky #endif				/* HAVE_CONFIG_H */
39*d6b92ffaSHans Petter Selasky 
40*d6b92ffaSHans Petter Selasky #ifdef OSM_VENDOR_INTF_MTL
41*d6b92ffaSHans Petter Selasky 
42*d6b92ffaSHans Petter Selasky #include <stdlib.h>
43*d6b92ffaSHans Petter Selasky #include <string.h>
44*d6b92ffaSHans Petter Selasky #include <opensm/osm_helper.h>
45*d6b92ffaSHans Petter Selasky #include <opensm/osm_log.h>
46*d6b92ffaSHans Petter Selasky /* HACK - I do not know how to prevent complib from loading kernel H files */
47*d6b92ffaSHans Petter Selasky #undef __init
48*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mtl.h>
49*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_api.h>
50*d6b92ffaSHans Petter Selasky #include <opensm/osm_subnet.h>
51*d6b92ffaSHans Petter Selasky #include <opensm/osm_opensm.h>
52*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mtl_transaction_mgr.h>
53*d6b92ffaSHans Petter Selasky #include <vendor/osm_mtl_bind.h>
54*d6b92ffaSHans Petter Selasky 
55*d6b92ffaSHans Petter Selasky /*
56*d6b92ffaSHans Petter Selasky   Since a race can accure on requests. Meaning - a response is received before
57*d6b92ffaSHans Petter Selasky   the send_callback is called - we will save both the madw_p and the fact
58*d6b92ffaSHans Petter Selasky   whether or not it is a response. A race can occure only on requests that did
59*d6b92ffaSHans Petter Selasky   not fail, and then the madw_p will be put back in the pool before the callback.
60*d6b92ffaSHans Petter Selasky */
__osm_set_wrid_by_p_madw(IN osm_madw_t * p_madw)61*d6b92ffaSHans Petter Selasky uint64_t __osm_set_wrid_by_p_madw(IN osm_madw_t * p_madw)
62*d6b92ffaSHans Petter Selasky {
63*d6b92ffaSHans Petter Selasky 	uint64_t wrid = 0;
64*d6b92ffaSHans Petter Selasky 
65*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw->p_mad);
66*d6b92ffaSHans Petter Selasky 
67*d6b92ffaSHans Petter Selasky 	memcpy(&wrid, &p_madw, sizeof(osm_madw_t *));
68*d6b92ffaSHans Petter Selasky 	wrid = (wrid << 1) |
69*d6b92ffaSHans Petter Selasky 	    ib_mad_is_response(p_madw->p_mad);
70*d6b92ffaSHans Petter Selasky 	return wrid;
71*d6b92ffaSHans Petter Selasky }
72*d6b92ffaSHans Petter Selasky 
73*d6b92ffaSHans Petter Selasky void
__osm_set_p_madw_and_resp_by_wrid(IN uint64_t wrid,OUT uint8_t * is_resp,OUT osm_madw_t ** pp_madw)74*d6b92ffaSHans Petter Selasky __osm_set_p_madw_and_resp_by_wrid(IN uint64_t wrid,
75*d6b92ffaSHans Petter Selasky 				  OUT uint8_t * is_resp,
76*d6b92ffaSHans Petter Selasky 				  OUT osm_madw_t ** pp_madw)
77*d6b92ffaSHans Petter Selasky {
78*d6b92ffaSHans Petter Selasky 	*is_resp = wrid & 0x0000000000000001;
79*d6b92ffaSHans Petter Selasky 	wrid = wrid >> 1;
80*d6b92ffaSHans Petter Selasky 	memcpy(pp_madw, &wrid, sizeof(osm_madw_t *));
81*d6b92ffaSHans Petter Selasky }
82*d6b92ffaSHans Petter Selasky 
83*d6b92ffaSHans Petter Selasky /**********************************************************************
84*d6b92ffaSHans Petter Selasky  * IB_MGT to OSM ADDRESS VECTOR
85*d6b92ffaSHans Petter Selasky  **********************************************************************/
86*d6b92ffaSHans Petter Selasky void
__osm_mtl_conv_ibmgt_rcv_desc_to_osm_addr(IN osm_vendor_t * const p_vend,IN IB_MGT_mad_rcv_desc_t * p_rcv_desc,IN uint8_t is_smi,OUT osm_mad_addr_t * p_mad_addr)87*d6b92ffaSHans Petter Selasky __osm_mtl_conv_ibmgt_rcv_desc_to_osm_addr(IN osm_vendor_t * const p_vend,
88*d6b92ffaSHans Petter Selasky 					  IN IB_MGT_mad_rcv_desc_t * p_rcv_desc,
89*d6b92ffaSHans Petter Selasky 					  IN uint8_t is_smi,
90*d6b92ffaSHans Petter Selasky 					  OUT osm_mad_addr_t * p_mad_addr)
91*d6b92ffaSHans Petter Selasky {
92*d6b92ffaSHans Petter Selasky 	/*  p_mad_addr->dest_lid = p_osm->subn.sm_base_lid; - for resp we use the dest lid ... */
93*d6b92ffaSHans Petter Selasky 	p_mad_addr->dest_lid = cl_hton16(p_rcv_desc->remote_lid);
94*d6b92ffaSHans Petter Selasky 	p_mad_addr->static_rate = 0;	/*  HACK - we do not  know the rate ! */
95*d6b92ffaSHans Petter Selasky 	p_mad_addr->path_bits = p_rcv_desc->local_path_bits;
96*d6b92ffaSHans Petter Selasky 	if (is_smi) {
97*d6b92ffaSHans Petter Selasky 		/* SMI */
98*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.smi.source_lid =
99*d6b92ffaSHans Petter Selasky 		    cl_hton16(p_rcv_desc->remote_lid);
100*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.smi.port_num = 99;	/*  HACK - if used - should fail */
101*d6b92ffaSHans Petter Selasky 	} else {
102*d6b92ffaSHans Petter Selasky 		/* GSI */
103*d6b92ffaSHans Petter Selasky 		/* seems to me there is a IBMGT bug reversing the QPN ... */
104*d6b92ffaSHans Petter Selasky 		/* Does IBMGT supposed to provide the QPN is network or HOST ? */
105*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.remote_qp = cl_hton32(p_rcv_desc->qp);
106*d6b92ffaSHans Petter Selasky 
107*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
108*d6b92ffaSHans Petter Selasky 		/*  we do have the p_mad_addr->pkey_ix but how to get the PKey by index ? */
109*d6b92ffaSHans Petter Selasky 		/*  the only way seems to be to use VAPI_query_hca_pkey_tbl and obtain */
110*d6b92ffaSHans Petter Selasky 		/*  the full PKey table - than go by the index. */
111*d6b92ffaSHans Petter Selasky 		/*  since this does not seem reasonable to me I simply use the default */
112*d6b92ffaSHans Petter Selasky 		/*  There is a TAVOR limitation that only one P_KEY is supported per  */
113*d6b92ffaSHans Petter Selasky 		/*  QP - so QP1 must use IB_DEFAULT_PKEY */
114*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.pkey_ix = 0;
115*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.service_level = p_rcv_desc->sl;
116*d6b92ffaSHans Petter Selasky 
117*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.global_route = p_rcv_desc->grh_flag;
118*d6b92ffaSHans Petter Selasky 		/* copy the GRH data if relevant */
119*d6b92ffaSHans Petter Selasky 		if (p_mad_addr->addr_type.gsi.global_route) {
120*d6b92ffaSHans Petter Selasky 			p_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
121*d6b92ffaSHans Petter Selasky 			    ib_grh_set_ver_class_flow(p_rcv_desc->grh.
122*d6b92ffaSHans Petter Selasky 						      IP_version,
123*d6b92ffaSHans Petter Selasky 						      p_rcv_desc->grh.
124*d6b92ffaSHans Petter Selasky 						      traffic_class,
125*d6b92ffaSHans Petter Selasky 						      p_rcv_desc->grh.
126*d6b92ffaSHans Petter Selasky 						      flow_label);
127*d6b92ffaSHans Petter Selasky 			p_mad_addr->addr_type.gsi.grh_info.hop_limit =
128*d6b92ffaSHans Petter Selasky 			    p_rcv_desc->grh.hop_limit;
129*d6b92ffaSHans Petter Selasky 			memcpy(&p_mad_addr->addr_type.gsi.grh_info.src_gid.raw,
130*d6b92ffaSHans Petter Selasky 			       &p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
131*d6b92ffaSHans Petter Selasky 			memcpy(&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
132*d6b92ffaSHans Petter Selasky 			       p_rcv_desc->grh.dgid, sizeof(ib_net64_t));
133*d6b92ffaSHans Petter Selasky 		}
134*d6b92ffaSHans Petter Selasky 	}
135*d6b92ffaSHans Petter Selasky }
136*d6b92ffaSHans Petter Selasky 
137*d6b92ffaSHans Petter Selasky /**********************************************************************
138*d6b92ffaSHans Petter Selasky  * OSM ADDR VECTOR TO IB_MGT
139*d6b92ffaSHans Petter Selasky  **********************************************************************/
140*d6b92ffaSHans Petter Selasky void
__osm_mtl_conv_osm_addr_to_ibmgt_addr(IN osm_mad_addr_t * p_mad_addr,IN uint8_t is_smi,OUT IB_ud_av_t * p_av)141*d6b92ffaSHans Petter Selasky __osm_mtl_conv_osm_addr_to_ibmgt_addr(IN osm_mad_addr_t * p_mad_addr,
142*d6b92ffaSHans Petter Selasky 				      IN uint8_t is_smi, OUT IB_ud_av_t * p_av)
143*d6b92ffaSHans Petter Selasky {
144*d6b92ffaSHans Petter Selasky 
145*d6b92ffaSHans Petter Selasky 	/* For global destination or Multicast address: */
146*d6b92ffaSHans Petter Selasky 	u_int8_t ver;
147*d6b92ffaSHans Petter Selasky 
148*d6b92ffaSHans Petter Selasky 	memset(p_av, 0, sizeof(IB_ud_av_t));
149*d6b92ffaSHans Petter Selasky 
150*d6b92ffaSHans Petter Selasky 	p_av->src_path_bits = p_mad_addr->path_bits;
151*d6b92ffaSHans Petter Selasky 	p_av->static_rate = p_mad_addr->static_rate;
152*d6b92ffaSHans Petter Selasky 	p_av->dlid = cl_ntoh16(p_mad_addr->dest_lid);
153*d6b92ffaSHans Petter Selasky 
154*d6b92ffaSHans Petter Selasky 	if (is_smi) {
155*d6b92ffaSHans Petter Selasky 		p_av->sl = 0;	/*  Just to note we use 0 here. */
156*d6b92ffaSHans Petter Selasky 	} else {
157*d6b92ffaSHans Petter Selasky 		p_av->sl = p_mad_addr->addr_type.gsi.service_level;
158*d6b92ffaSHans Petter Selasky 		p_av->grh_flag = p_mad_addr->addr_type.gsi.global_route;
159*d6b92ffaSHans Petter Selasky 
160*d6b92ffaSHans Petter Selasky 		if (p_mad_addr->addr_type.gsi.global_route) {
161*d6b92ffaSHans Petter Selasky 			ib_grh_get_ver_class_flow(p_mad_addr->addr_type.gsi.
162*d6b92ffaSHans Petter Selasky 						  grh_info.ver_class_flow, &ver,
163*d6b92ffaSHans Petter Selasky 						  &p_av->traffic_class,
164*d6b92ffaSHans Petter Selasky 						  &p_av->flow_label);
165*d6b92ffaSHans Petter Selasky 			p_av->hop_limit =
166*d6b92ffaSHans Petter Selasky 			    p_mad_addr->addr_type.gsi.grh_info.hop_limit;
167*d6b92ffaSHans Petter Selasky 			p_av->sgid_index = 0;	/*  we always use source GID 0 */
168*d6b92ffaSHans Petter Selasky 			memcpy(&p_av->dgid,
169*d6b92ffaSHans Petter Selasky 			       &p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
170*d6b92ffaSHans Petter Selasky 			       sizeof(ib_net64_t));
171*d6b92ffaSHans Petter Selasky 
172*d6b92ffaSHans Petter Selasky 		}
173*d6b92ffaSHans Petter Selasky 	}
174*d6b92ffaSHans Petter Selasky }
175*d6b92ffaSHans Petter Selasky 
__osm_vendor_clear_sm(IN osm_bind_handle_t h_bind)176*d6b92ffaSHans Petter Selasky void __osm_vendor_clear_sm(IN osm_bind_handle_t h_bind)
177*d6b92ffaSHans Petter Selasky {
178*d6b92ffaSHans Petter Selasky 	osm_mtl_bind_info_t *p_bind = (osm_mtl_bind_info_t *) h_bind;
179*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
180*d6b92ffaSHans Petter Selasky 	VAPI_ret_t status;
181*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_t attr_mod;
182*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_mask_t attr_mask;
183*d6b92ffaSHans Petter Selasky 
184*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
185*d6b92ffaSHans Petter Selasky 
186*d6b92ffaSHans Petter Selasky 	memset(&attr_mod, 0, sizeof(attr_mod));
187*d6b92ffaSHans Petter Selasky 	memset(&attr_mask, 0, sizeof(attr_mask));
188*d6b92ffaSHans Petter Selasky 
189*d6b92ffaSHans Petter Selasky 	attr_mod.is_sm = FALSE;
190*d6b92ffaSHans Petter Selasky 	attr_mask = HCA_ATTR_IS_SM;
191*d6b92ffaSHans Petter Selasky 
192*d6b92ffaSHans Petter Selasky 	status =
193*d6b92ffaSHans Petter Selasky 	    VAPI_modify_hca_attr(p_bind->hca_hndl, p_bind->port_num, &attr_mod,
194*d6b92ffaSHans Petter Selasky 				 &attr_mask);
195*d6b92ffaSHans Petter Selasky 	if (status != VAPI_OK) {
196*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
197*d6b92ffaSHans Petter Selasky 			"__osm_vendor_clear_sm: ERR 3C21: "
198*d6b92ffaSHans Petter Selasky 			"Unable set 'IS_SM' bit in port attributes (%d).\n",
199*d6b92ffaSHans Petter Selasky 			status);
200*d6b92ffaSHans Petter Selasky 	}
201*d6b92ffaSHans Petter Selasky 
202*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
203*d6b92ffaSHans Petter Selasky }
204*d6b92ffaSHans Petter Selasky 
205*d6b92ffaSHans Petter Selasky /**********************************************************************
206*d6b92ffaSHans Petter Selasky  * ANY CONSTRUCTION OF THE osm_vendor_t OBJECT
207*d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_construct(IN osm_vendor_t * const p_vend)208*d6b92ffaSHans Petter Selasky void osm_vendor_construct(IN osm_vendor_t * const p_vend)
209*d6b92ffaSHans Petter Selasky {
210*d6b92ffaSHans Petter Selasky 	memset(p_vend, 0, sizeof(*p_vend));
211*d6b92ffaSHans Petter Selasky }
212*d6b92ffaSHans Petter Selasky 
213*d6b92ffaSHans Petter Selasky /**********************************************************************
214*d6b92ffaSHans Petter Selasky  * DEALOCATE osm_vendor_t
215*d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_destroy(IN osm_vendor_t * const p_vend)216*d6b92ffaSHans Petter Selasky void osm_vendor_destroy(IN osm_vendor_t * const p_vend)
217*d6b92ffaSHans Petter Selasky {
218*d6b92ffaSHans Petter Selasky 	osm_vendor_mgt_bind_t *vendor_mgt_bind_p;
219*d6b92ffaSHans Petter Selasky 	IB_MGT_ret_t mgt_ret;
220*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
221*d6b92ffaSHans Petter Selasky 
222*d6b92ffaSHans Petter Selasky 	if (p_vend->h_al != NULL) {
223*d6b92ffaSHans Petter Selasky 		vendor_mgt_bind_p = (osm_vendor_mgt_bind_t *) p_vend->h_al;
224*d6b92ffaSHans Petter Selasky 		if (vendor_mgt_bind_p->gsi_init) {
225*d6b92ffaSHans Petter Selasky 
226*d6b92ffaSHans Petter Selasky 			/* un register the class */
227*d6b92ffaSHans Petter Selasky 			/* HACK WE ASSUME WE ONLY GOT SA CLASS REGISTERD ON GSI !!! */
228*d6b92ffaSHans Petter Selasky 			mgt_ret =
229*d6b92ffaSHans Petter Selasky 			    IB_MGT_unbind_gsi_class(vendor_mgt_bind_p->
230*d6b92ffaSHans Petter Selasky 						    gsi_mads_hdl,
231*d6b92ffaSHans Petter Selasky 						    IB_MCLASS_SUBN_ADM);
232*d6b92ffaSHans Petter Selasky 			if (mgt_ret != IB_MGT_OK) {
233*d6b92ffaSHans Petter Selasky 				osm_log(p_vend->p_log, OSM_LOG_ERROR,
234*d6b92ffaSHans Petter Selasky 					"osm_vendor_destroy: ERR 3C03: "
235*d6b92ffaSHans Petter Selasky 					"Fail to unbind the SA class.\n");
236*d6b92ffaSHans Petter Selasky 			}
237*d6b92ffaSHans Petter Selasky 
238*d6b92ffaSHans Petter Selasky 			/* un bind the handle */
239*d6b92ffaSHans Petter Selasky 			if (IB_MGT_release_handle
240*d6b92ffaSHans Petter Selasky 			    (vendor_mgt_bind_p->gsi_mads_hdl) != IB_MGT_OK) {
241*d6b92ffaSHans Petter Selasky 				osm_log(p_vend->p_log, OSM_LOG_ERROR,
242*d6b92ffaSHans Petter Selasky 					"osm_vendor_destroy: ERR 3C02: "
243*d6b92ffaSHans Petter Selasky 					"Fail to unbind the SA GSI handle.\n");
244*d6b92ffaSHans Petter Selasky 			}
245*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
246*d6b92ffaSHans Petter Selasky 				"osm_vendor_destroy: DBG 1002: "
247*d6b92ffaSHans Petter Selasky 				"Unbind the GSI handles.\n");
248*d6b92ffaSHans Petter Selasky 		}
249*d6b92ffaSHans Petter Selasky 		if (vendor_mgt_bind_p->smi_init) {
250*d6b92ffaSHans Petter Selasky 			/* first - clear the IS_SM in the capability mask */
251*d6b92ffaSHans Petter Selasky 			__osm_vendor_clear_sm((osm_bind_handle_t)
252*d6b92ffaSHans Petter Selasky 					      (vendor_mgt_bind_p->smi_p_bind));
253*d6b92ffaSHans Petter Selasky 
254*d6b92ffaSHans Petter Selasky 			/* un register the class */
255*d6b92ffaSHans Petter Selasky 			mgt_ret =
256*d6b92ffaSHans Petter Selasky 			    IB_MGT_unbind_sm(vendor_mgt_bind_p->smi_mads_hdl);
257*d6b92ffaSHans Petter Selasky 			if (mgt_ret != IB_MGT_OK) {
258*d6b92ffaSHans Petter Selasky 				osm_log(p_vend->p_log, OSM_LOG_ERROR,
259*d6b92ffaSHans Petter Selasky 					"osm_vendor_destroy: ERR 3C04: "
260*d6b92ffaSHans Petter Selasky 					"Fail to unbind the SM class.\n");
261*d6b92ffaSHans Petter Selasky 			}
262*d6b92ffaSHans Petter Selasky 
263*d6b92ffaSHans Petter Selasky 			/* un bind the handle */
264*d6b92ffaSHans Petter Selasky 			if (IB_MGT_release_handle
265*d6b92ffaSHans Petter Selasky 			    (vendor_mgt_bind_p->smi_mads_hdl) != IB_MGT_OK) {
266*d6b92ffaSHans Petter Selasky 				osm_log(p_vend->p_log, OSM_LOG_ERROR,
267*d6b92ffaSHans Petter Selasky 					"osm_vendor_destroy: ERR 3C05: "
268*d6b92ffaSHans Petter Selasky 					"Fail to unbind the SMI handle.\n");
269*d6b92ffaSHans Petter Selasky 			}
270*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
271*d6b92ffaSHans Petter Selasky 				"osm_vendor_destroy: DBG 1003: "
272*d6b92ffaSHans Petter Selasky 				"Unbind the SMI handles.\n");
273*d6b92ffaSHans Petter Selasky 
274*d6b92ffaSHans Petter Selasky 		}
275*d6b92ffaSHans Petter Selasky 	}
276*d6b92ffaSHans Petter Selasky 	osm_transaction_mgr_destroy(p_vend);
277*d6b92ffaSHans Petter Selasky 	/*  __osm_mtl_destroy_tid_mad_map( p_vend ); */
278*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
279*d6b92ffaSHans Petter Selasky }
280*d6b92ffaSHans Petter Selasky 
281*d6b92ffaSHans Petter Selasky /**********************************************************************
282*d6b92ffaSHans Petter Selasky DEALLOCATE A POINTER TO osm_vendor_t
283*d6b92ffaSHans Petter Selasky **********************************************************************/
osm_vendor_delete(IN osm_vendor_t ** const pp_vend)284*d6b92ffaSHans Petter Selasky void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
285*d6b92ffaSHans Petter Selasky {
286*d6b92ffaSHans Petter Selasky 	CL_ASSERT(pp_vend);
287*d6b92ffaSHans Petter Selasky 
288*d6b92ffaSHans Petter Selasky 	osm_vendor_destroy(*pp_vend);
289*d6b92ffaSHans Petter Selasky 	free(*pp_vend);
290*d6b92ffaSHans Petter Selasky 	*pp_vend = NULL;
291*d6b92ffaSHans Petter Selasky }
292*d6b92ffaSHans Petter Selasky 
293*d6b92ffaSHans Petter Selasky /**********************************************************************
294*d6b92ffaSHans Petter Selasky  * This proc actuall binds the handle to the lower level.
295*d6b92ffaSHans Petter Selasky  *
296*d6b92ffaSHans Petter Selasky  * We might have here as a result a casting of our struct to the ib_al_handle_t
297*d6b92ffaSHans Petter Selasky  *
298*d6b92ffaSHans Petter Selasky  * Q: Do we need 2 of those - one for MSI and one for GSI ?
299*d6b92ffaSHans Petter Selasky  * A: Yes! We should be able to do the SA too. So we need a struct!
300*d6b92ffaSHans Petter Selasky  *
301*d6b92ffaSHans Petter Selasky  **********************************************************************/
302*d6b92ffaSHans Petter Selasky 
303*d6b92ffaSHans Petter Selasky ib_api_status_t
osm_vendor_init(IN osm_vendor_t * const p_vend,IN osm_log_t * const p_log,IN const uint32_t timeout)304*d6b92ffaSHans Petter Selasky osm_vendor_init(IN osm_vendor_t * const p_vend,
305*d6b92ffaSHans Petter Selasky 		IN osm_log_t * const p_log, IN const uint32_t timeout)
306*d6b92ffaSHans Petter Selasky {
307*d6b92ffaSHans Petter Selasky 	osm_vendor_mgt_bind_t *ib_mgt_hdl_p;
308*d6b92ffaSHans Petter Selasky 	ib_api_status_t status = IB_SUCCESS;
309*d6b92ffaSHans Petter Selasky 
310*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
311*d6b92ffaSHans Petter Selasky 
312*d6b92ffaSHans Petter Selasky 	p_vend->p_log = p_log;
313*d6b92ffaSHans Petter Selasky 
314*d6b92ffaSHans Petter Selasky 	/*
315*d6b92ffaSHans Petter Selasky 	 * HACK: We need no handle. Assuming the driver is up.
316*d6b92ffaSHans Petter Selasky 	 */
317*d6b92ffaSHans Petter Selasky 	ib_mgt_hdl_p = (osm_vendor_mgt_bind_t *)
318*d6b92ffaSHans Petter Selasky 	    malloc(sizeof(osm_vendor_mgt_bind_t));
319*d6b92ffaSHans Petter Selasky 	if (ib_mgt_hdl_p == NULL) {
320*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
321*d6b92ffaSHans Petter Selasky 			"osm_vendor_init: ERR 3C06: "
322*d6b92ffaSHans Petter Selasky 			"Fail to allocate vendor mgt handle.\n");
323*d6b92ffaSHans Petter Selasky 		goto Exit;
324*d6b92ffaSHans Petter Selasky 	}
325*d6b92ffaSHans Petter Selasky 
326*d6b92ffaSHans Petter Selasky 	ib_mgt_hdl_p->smi_init = FALSE;
327*d6b92ffaSHans Petter Selasky 	ib_mgt_hdl_p->gsi_init = FALSE;
328*d6b92ffaSHans Petter Selasky 	/* cast it into the ib_al_handle_t h_al */
329*d6b92ffaSHans Petter Selasky 	p_vend->h_al = (ib_al_handle_t) ib_mgt_hdl_p;
330*d6b92ffaSHans Petter Selasky 	p_vend->p_transaction_mgr = NULL;
331*d6b92ffaSHans Petter Selasky 	osm_transaction_mgr_init(p_vend);
332*d6b92ffaSHans Petter Selasky 	/*  p_vend->madw_by_tid_map_p = NULL; */
333*d6b92ffaSHans Petter Selasky 	/*  __osm_mtl_init_tid_mad_map( p_vend ); */
334*d6b92ffaSHans Petter Selasky 	p_vend->timeout = timeout;
335*d6b92ffaSHans Petter Selasky 
336*d6b92ffaSHans Petter Selasky Exit:
337*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
338*d6b92ffaSHans Petter Selasky 	return (status);
339*d6b92ffaSHans Petter Selasky }
340*d6b92ffaSHans Petter Selasky 
341*d6b92ffaSHans Petter Selasky /**********************************************************************
342*d6b92ffaSHans Petter Selasky  *  Create and Initialize osm_vendor_t Object
343*d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_new(IN osm_log_t * const p_log,IN const uint32_t timeout)344*d6b92ffaSHans Petter Selasky osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
345*d6b92ffaSHans Petter Selasky 			     IN const uint32_t timeout)
346*d6b92ffaSHans Petter Selasky {
347*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
348*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend;
349*d6b92ffaSHans Petter Selasky 
350*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
351*d6b92ffaSHans Petter Selasky 
352*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_log);
353*d6b92ffaSHans Petter Selasky 
354*d6b92ffaSHans Petter Selasky 	p_vend = malloc(sizeof(*p_vend));
355*d6b92ffaSHans Petter Selasky 	if (p_vend != NULL) {
356*d6b92ffaSHans Petter Selasky 		memset(p_vend, 0, sizeof(*p_vend));
357*d6b92ffaSHans Petter Selasky 		status = osm_vendor_init(p_vend, p_log, timeout);
358*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
359*d6b92ffaSHans Petter Selasky 			osm_vendor_delete(&p_vend);
360*d6b92ffaSHans Petter Selasky 		}
361*d6b92ffaSHans Petter Selasky 	} else {
362*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
363*d6b92ffaSHans Petter Selasky 			"osm_vendor_new: ERR 3C07: "
364*d6b92ffaSHans Petter Selasky 			"Fail to allocate vendor object.\n");
365*d6b92ffaSHans Petter Selasky 	}
366*d6b92ffaSHans Petter Selasky 
367*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
368*d6b92ffaSHans Petter Selasky 	return (p_vend);
369*d6b92ffaSHans Petter Selasky }
370*d6b92ffaSHans Petter Selasky 
371*d6b92ffaSHans Petter Selasky /**********************************************************************
372*d6b92ffaSHans Petter Selasky  * IB_MGT RCV callback
373*d6b92ffaSHans Petter Selasky  *
374*d6b92ffaSHans Petter Selasky  **********************************************************************/
375*d6b92ffaSHans Petter Selasky void
__osm_mtl_rcv_callback(IN IB_MGT_mad_hndl_t mad_hndl,IN void * private_ctx_p,IN void * payload_p,IN IB_MGT_mad_rcv_desc_t * rcv_remote_info_p)376*d6b92ffaSHans Petter Selasky __osm_mtl_rcv_callback(IN IB_MGT_mad_hndl_t mad_hndl,
377*d6b92ffaSHans Petter Selasky 		       IN void *private_ctx_p,
378*d6b92ffaSHans Petter Selasky 		       IN void *payload_p,
379*d6b92ffaSHans Petter Selasky 		       IN IB_MGT_mad_rcv_desc_t * rcv_remote_info_p)
380*d6b92ffaSHans Petter Selasky {
381*d6b92ffaSHans Petter Selasky 	IB_MGT_ret_t status;
382*d6b92ffaSHans Petter Selasky 	osm_mtl_bind_info_t *bind_info_p = private_ctx_p;
383*d6b92ffaSHans Petter Selasky 	osm_madw_t *req_madw_p = NULL;
384*d6b92ffaSHans Petter Selasky 	osm_madw_t *madw_p;
385*d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *p_new_vw;
386*d6b92ffaSHans Petter Selasky 	osm_mad_addr_t mad_addr;
387*d6b92ffaSHans Petter Selasky 	ib_mad_t *mad_buf_p;
388*d6b92ffaSHans Petter Selasky 	osm_log_t *const p_log = bind_info_p->p_vend->p_log;
389*d6b92ffaSHans Petter Selasky 
390*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
391*d6b92ffaSHans Petter Selasky 
392*d6b92ffaSHans Petter Selasky 	/* if it is a response MAD we mustbe able to get the request */
393*d6b92ffaSHans Petter Selasky 	if (ib_mad_is_response((ib_mad_t *) payload_p)) {
394*d6b92ffaSHans Petter Selasky 		/* can we find a matching madw by this payload TID */
395*d6b92ffaSHans Petter Selasky 		status =
396*d6b92ffaSHans Petter Selasky 		    osm_transaction_mgr_get_madw_for_tid(bind_info_p->p_vend,
397*d6b92ffaSHans Petter Selasky 							 (ib_mad_t *) payload_p,
398*d6b92ffaSHans Petter Selasky 							 &req_madw_p);
399*d6b92ffaSHans Petter Selasky 		if (status != IB_MGT_OK) {
400*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
401*d6b92ffaSHans Petter Selasky 				"__osm_mtl_rcv_callback: ERR 3C08: "
402*d6b92ffaSHans Petter Selasky 				"Error obtaining request madw by TID (%d).\n",
403*d6b92ffaSHans Petter Selasky 				status);
404*d6b92ffaSHans Petter Selasky 			req_madw_p = NULL;
405*d6b92ffaSHans Petter Selasky 		}
406*d6b92ffaSHans Petter Selasky 
407*d6b92ffaSHans Petter Selasky 		if (req_madw_p == NULL) {
408*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
409*d6b92ffaSHans Petter Selasky 				"__osm_mtl_rcv_callback: ERR 3C09:  "
410*d6b92ffaSHans Petter Selasky 				"Fail to obtain request madw for received MAD.(method=%X attr=%X) Aborting CB.\n",
411*d6b92ffaSHans Petter Selasky 				((ib_mad_t *) payload_p)->method,
412*d6b92ffaSHans Petter Selasky 				cl_ntoh16(((ib_mad_t *) payload_p)->attr_id)
413*d6b92ffaSHans Petter Selasky 
414*d6b92ffaSHans Petter Selasky 			    );
415*d6b92ffaSHans Petter Selasky 			goto Exit;
416*d6b92ffaSHans Petter Selasky 		}
417*d6b92ffaSHans Petter Selasky 	}
418*d6b92ffaSHans Petter Selasky 
419*d6b92ffaSHans Petter Selasky 	/* do we have a request ??? */
420*d6b92ffaSHans Petter Selasky 	if (req_madw_p == NULL) {
421*d6b92ffaSHans Petter Selasky 
422*d6b92ffaSHans Petter Selasky 		/* first arrange an address */
423*d6b92ffaSHans Petter Selasky 		__osm_mtl_conv_ibmgt_rcv_desc_to_osm_addr(bind_info_p->p_vend,
424*d6b92ffaSHans Petter Selasky 							  rcv_remote_info_p,
425*d6b92ffaSHans Petter Selasky 							  (((ib_mad_t *)
426*d6b92ffaSHans Petter Selasky 							    payload_p)->
427*d6b92ffaSHans Petter Selasky 							   mgmt_class ==
428*d6b92ffaSHans Petter Selasky 							   IB_MCLASS_SUBN_LID)
429*d6b92ffaSHans Petter Selasky 							  || (((ib_mad_t *)
430*d6b92ffaSHans Petter Selasky 							       payload_p)->
431*d6b92ffaSHans Petter Selasky 							      mgmt_class ==
432*d6b92ffaSHans Petter Selasky 							      IB_MCLASS_SUBN_DIR),
433*d6b92ffaSHans Petter Selasky 							  &mad_addr);
434*d6b92ffaSHans Petter Selasky 
435*d6b92ffaSHans Petter Selasky 		osm_log(p_log, OSM_LOG_ERROR,
436*d6b92ffaSHans Petter Selasky 			"__osm_mtl_rcv_callback: : "
437*d6b92ffaSHans Petter Selasky 			"Received MAD from QP:%X.\n",
438*d6b92ffaSHans Petter Selasky 			cl_ntoh32(mad_addr.addr_type.gsi.remote_qp)
439*d6b92ffaSHans Petter Selasky 		    );
440*d6b92ffaSHans Petter Selasky 
441*d6b92ffaSHans Petter Selasky 		/* if not - get new osm_madw and arrange it. */
442*d6b92ffaSHans Petter Selasky 		/* create the new madw in the pool */
443*d6b92ffaSHans Petter Selasky 		madw_p = osm_mad_pool_get(bind_info_p->p_osm_pool,
444*d6b92ffaSHans Petter Selasky 					  (osm_bind_handle_t) bind_info_p,
445*d6b92ffaSHans Petter Selasky 					  MAD_BLOCK_SIZE, &mad_addr);
446*d6b92ffaSHans Petter Selasky 		if (madw_p == NULL) {
447*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
448*d6b92ffaSHans Petter Selasky 				"__osm_mtl_rcv_callback: ERR 3C10: "
449*d6b92ffaSHans Petter Selasky 				"Error request for a new madw.\n");
450*d6b92ffaSHans Petter Selasky 			goto Exit;
451*d6b92ffaSHans Petter Selasky 		}
452*d6b92ffaSHans Petter Selasky 		/* HACK: we cust to avoid the const ??? */
453*d6b92ffaSHans Petter Selasky 		mad_buf_p = (void *)madw_p->p_mad;
454*d6b92ffaSHans Petter Selasky 	} else {
455*d6b92ffaSHans Petter Selasky 		/* we have the madw defined during the send and stored in the vend_wrap */
456*d6b92ffaSHans Petter Selasky 		/* we need to make sure the wrapper is correctly init there */
457*d6b92ffaSHans Petter Selasky 		CL_ASSERT(req_madw_p->vend_wrap.p_resp_madw != 0);
458*d6b92ffaSHans Petter Selasky 		madw_p = req_madw_p->vend_wrap.p_resp_madw;
459*d6b92ffaSHans Petter Selasky 
460*d6b92ffaSHans Petter Selasky 		/* HACK: we do not Support RMPP */
461*d6b92ffaSHans Petter Selasky 		CL_ASSERT(madw_p->h_bind);
462*d6b92ffaSHans Petter Selasky 		mad_buf_p =
463*d6b92ffaSHans Petter Selasky 		    osm_vendor_get(madw_p->h_bind, MAD_BLOCK_SIZE,
464*d6b92ffaSHans Petter Selasky 				   &madw_p->vend_wrap);
465*d6b92ffaSHans Petter Selasky 
466*d6b92ffaSHans Petter Selasky 		if (mad_buf_p == NULL) {
467*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
468*d6b92ffaSHans Petter Selasky 				"__osm_mtl_rcv_callback: ERR 3C11: "
469*d6b92ffaSHans Petter Selasky 				"Unable to acquire wire MAD.\n");
470*d6b92ffaSHans Petter Selasky 
471*d6b92ffaSHans Petter Selasky 			goto Exit;
472*d6b92ffaSHans Petter Selasky 		}
473*d6b92ffaSHans Petter Selasky 
474*d6b92ffaSHans Petter Selasky 		/*
475*d6b92ffaSHans Petter Selasky 		   Finally, attach the wire MAD to this wrapper.
476*d6b92ffaSHans Petter Selasky 		 */
477*d6b92ffaSHans Petter Selasky 		osm_madw_set_mad(madw_p, mad_buf_p);
478*d6b92ffaSHans Petter Selasky 
479*d6b92ffaSHans Petter Selasky 		/* also we need to handle the size of the mad since we did not init ... */
480*d6b92ffaSHans Petter Selasky 		madw_p->mad_size = MAD_BLOCK_SIZE;
481*d6b92ffaSHans Petter Selasky 	}
482*d6b92ffaSHans Petter Selasky 
483*d6b92ffaSHans Petter Selasky 	/* init some fields of the vendor wrapper */
484*d6b92ffaSHans Petter Selasky 	p_new_vw = osm_madw_get_vend_ptr(madw_p);
485*d6b92ffaSHans Petter Selasky 	p_new_vw->h_bind = bind_info_p;
486*d6b92ffaSHans Petter Selasky 	p_new_vw->size = MAD_BLOCK_SIZE;
487*d6b92ffaSHans Petter Selasky 	p_new_vw->p_resp_madw = NULL;
488*d6b92ffaSHans Petter Selasky 	p_new_vw->mad_buf_p = mad_buf_p;
489*d6b92ffaSHans Petter Selasky 
490*d6b92ffaSHans Petter Selasky 	/* HACK: We do not support RMPP in receiving MADS */
491*d6b92ffaSHans Petter Selasky 	memcpy(p_new_vw->mad_buf_p, payload_p, MAD_BLOCK_SIZE);
492*d6b92ffaSHans Petter Selasky 
493*d6b92ffaSHans Petter Selasky 	/* attach the buffer to the wrapper */
494*d6b92ffaSHans Petter Selasky 	madw_p->p_mad = mad_buf_p;
495*d6b92ffaSHans Petter Selasky 
496*d6b92ffaSHans Petter Selasky 	/* we can also make sure we marked the size and bind on the returned madw */
497*d6b92ffaSHans Petter Selasky 	madw_p->h_bind = p_new_vw->h_bind;
498*d6b92ffaSHans Petter Selasky 
499*d6b92ffaSHans Petter Selasky 	/* call the CB */
500*d6b92ffaSHans Petter Selasky 	(*bind_info_p->rcv_callback) (madw_p, bind_info_p->client_context,
501*d6b92ffaSHans Petter Selasky 				      req_madw_p);
502*d6b92ffaSHans Petter Selasky 
503*d6b92ffaSHans Petter Selasky Exit:
504*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
505*d6b92ffaSHans Petter Selasky }
506*d6b92ffaSHans Petter Selasky 
507*d6b92ffaSHans Petter Selasky /**********************************************************************
508*d6b92ffaSHans Petter Selasky  * IB_MGT Send callback : invoked after each send
509*d6b92ffaSHans Petter Selasky  *
510*d6b92ffaSHans Petter Selasky  **********************************************************************/
511*d6b92ffaSHans Petter Selasky void
__osm_mtl_send_callback(IN IB_MGT_mad_hndl_t mad_hndl,IN u_int64_t wrid,IN IB_comp_status_t status,IN void * private_ctx_p)512*d6b92ffaSHans Petter Selasky __osm_mtl_send_callback(IN IB_MGT_mad_hndl_t mad_hndl,
513*d6b92ffaSHans Petter Selasky 			IN u_int64_t wrid,
514*d6b92ffaSHans Petter Selasky 			IN IB_comp_status_t status, IN void *private_ctx_p)
515*d6b92ffaSHans Petter Selasky {
516*d6b92ffaSHans Petter Selasky 	osm_madw_t *madw_p;
517*d6b92ffaSHans Petter Selasky 	osm_mtl_bind_info_t *bind_info_p =
518*d6b92ffaSHans Petter Selasky 	    (osm_mtl_bind_info_t *) private_ctx_p;
519*d6b92ffaSHans Petter Selasky 	osm_log_t *const p_log = bind_info_p->p_vend->p_log;
520*d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *p_vw;
521*d6b92ffaSHans Petter Selasky 	uint8_t is_resp;
522*d6b92ffaSHans Petter Selasky 
523*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
524*d6b92ffaSHans Petter Selasky 
525*d6b92ffaSHans Petter Selasky 	/* obtain the madp from the wrid */
526*d6b92ffaSHans Petter Selasky 	__osm_set_p_madw_and_resp_by_wrid(wrid, &is_resp, &madw_p);
527*d6b92ffaSHans Petter Selasky 
528*d6b92ffaSHans Petter Selasky 	osm_log(p_log, OSM_LOG_DEBUG,
529*d6b92ffaSHans Petter Selasky 		"__osm_mtl_send_callback: INFO 1008: "
530*d6b92ffaSHans Petter Selasky 		"Handling Send of MADW:%p Is Resp:%d.\n", madw_p, is_resp);
531*d6b92ffaSHans Petter Selasky 
532*d6b92ffaSHans Petter Selasky 	/* we need to handle requests and responses differently */
533*d6b92ffaSHans Petter Selasky 	if (is_resp) {
534*d6b92ffaSHans Petter Selasky 		if (status != IB_COMP_SUCCESS) {
535*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
536*d6b92ffaSHans Petter Selasky 				"__osm_mtl_send_callback: ERR 3C12: "
537*d6b92ffaSHans Petter Selasky 				"Error Sending Response MADW:%p.\n", madw_p);
538*d6b92ffaSHans Petter Selasky 		} else {
539*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_DEBUG,
540*d6b92ffaSHans Petter Selasky 				"__osm_mtl_send_callback: DBG 1008: "
541*d6b92ffaSHans Petter Selasky 				"Completed Sending Response MADW:%p.\n",
542*d6b92ffaSHans Petter Selasky 				madw_p);
543*d6b92ffaSHans Petter Selasky 		}
544*d6b92ffaSHans Petter Selasky 
545*d6b92ffaSHans Petter Selasky 		/* if we are a response - we need to clean it up */
546*d6b92ffaSHans Petter Selasky 		osm_mad_pool_put(bind_info_p->p_osm_pool, madw_p);
547*d6b92ffaSHans Petter Selasky 	} else {
548*d6b92ffaSHans Petter Selasky 
549*d6b92ffaSHans Petter Selasky 		/* this call back is invoked on completion of send - error or not */
550*d6b92ffaSHans Petter Selasky 		if (status != IB_COMP_SUCCESS) {
551*d6b92ffaSHans Petter Selasky 
552*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
553*d6b92ffaSHans Petter Selasky 				"__osm_mtl_send_callback: ERR 3C13: "
554*d6b92ffaSHans Petter Selasky 				"Received an Error from IB_MGT Send (%d).\n",
555*d6b92ffaSHans Petter Selasky 				status);
556*d6b92ffaSHans Petter Selasky 
557*d6b92ffaSHans Petter Selasky 			p_vw = osm_madw_get_vend_ptr(madw_p);
558*d6b92ffaSHans Petter Selasky 			CL_ASSERT(p_vw);
559*d6b92ffaSHans Petter Selasky 
560*d6b92ffaSHans Petter Selasky 			/*
561*d6b92ffaSHans Petter Selasky 			   Return any wrappers to the pool that may have been
562*d6b92ffaSHans Petter Selasky 			   pre-emptively allocated to handle a receive.
563*d6b92ffaSHans Petter Selasky 			 */
564*d6b92ffaSHans Petter Selasky 			if (p_vw->p_resp_madw) {
565*d6b92ffaSHans Petter Selasky 				osm_mad_pool_put(bind_info_p->p_osm_pool,
566*d6b92ffaSHans Petter Selasky 						 p_vw->p_resp_madw);
567*d6b92ffaSHans Petter Selasky 				p_vw->p_resp_madw = NULL;
568*d6b92ffaSHans Petter Selasky 			}
569*d6b92ffaSHans Petter Selasky 
570*d6b92ffaSHans Petter Selasky 			/* invoke the CB */
571*d6b92ffaSHans Petter Selasky 			(*bind_info_p->send_err_callback) (bind_info_p->
572*d6b92ffaSHans Petter Selasky 							   client_context,
573*d6b92ffaSHans Petter Selasky 							   madw_p);
574*d6b92ffaSHans Petter Selasky 		} else {
575*d6b92ffaSHans Petter Selasky 			/* successful request send - do nothing - the response will need the
576*d6b92ffaSHans Petter Selasky 			   out mad */
577*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_DEBUG,
578*d6b92ffaSHans Petter Selasky 				"__osm_mtl_send_callback: DBG 1008: "
579*d6b92ffaSHans Petter Selasky 				"Completed Sending Request MADW:%p.\n", madw_p);
580*d6b92ffaSHans Petter Selasky 		}
581*d6b92ffaSHans Petter Selasky 	}
582*d6b92ffaSHans Petter Selasky 
583*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
584*d6b92ffaSHans Petter Selasky }
585*d6b92ffaSHans Petter Selasky 
586*d6b92ffaSHans Petter Selasky /**********************************************************************
587*d6b92ffaSHans Petter Selasky  * BINDs a callback (rcv and send error) for a given class and method
588*d6b92ffaSHans Petter Selasky  * defined by the given:  osm_bind_info_t
589*d6b92ffaSHans Petter Selasky  **********************************************************************/
590*d6b92ffaSHans Petter Selasky osm_bind_handle_t
osm_vendor_bind(IN osm_vendor_t * const p_vend,IN osm_bind_info_t * const p_user_bind,IN osm_mad_pool_t * const p_mad_pool,IN osm_vend_mad_recv_callback_t mad_recv_callback,IN osm_vend_mad_send_err_callback_t send_err_callback,IN void * context)591*d6b92ffaSHans Petter Selasky osm_vendor_bind(IN osm_vendor_t * const p_vend,
592*d6b92ffaSHans Petter Selasky 		IN osm_bind_info_t * const p_user_bind,
593*d6b92ffaSHans Petter Selasky 		IN osm_mad_pool_t * const p_mad_pool,
594*d6b92ffaSHans Petter Selasky 		IN osm_vend_mad_recv_callback_t mad_recv_callback,
595*d6b92ffaSHans Petter Selasky 		IN osm_vend_mad_send_err_callback_t send_err_callback,
596*d6b92ffaSHans Petter Selasky 		IN void *context)
597*d6b92ffaSHans Petter Selasky {
598*d6b92ffaSHans Petter Selasky 	ib_net64_t port_guid;
599*d6b92ffaSHans Petter Selasky 	osm_mtl_bind_info_t *p_bind = NULL;
600*d6b92ffaSHans Petter Selasky 	VAPI_hca_hndl_t hca_hndl;
601*d6b92ffaSHans Petter Selasky 	VAPI_hca_id_t hca_id;
602*d6b92ffaSHans Petter Selasky 	IB_MGT_mad_type_t mad_type;
603*d6b92ffaSHans Petter Selasky 	uint32_t port_num;
604*d6b92ffaSHans Petter Selasky 	osm_vendor_mgt_bind_t *ib_mgt_hdl_p;
605*d6b92ffaSHans Petter Selasky 	IB_MGT_ret_t mgt_ret;
606*d6b92ffaSHans Petter Selasky 
607*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
608*d6b92ffaSHans Petter Selasky 
609*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_user_bind);
610*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_mad_pool);
611*d6b92ffaSHans Petter Selasky 	CL_ASSERT(mad_recv_callback);
612*d6b92ffaSHans Petter Selasky 	CL_ASSERT(send_err_callback);
613*d6b92ffaSHans Petter Selasky 
614*d6b92ffaSHans Petter Selasky 	/* cast back the AL handle to vendor mgt bind */
615*d6b92ffaSHans Petter Selasky 	ib_mgt_hdl_p = (osm_vendor_mgt_bind_t *) p_vend->h_al;
616*d6b92ffaSHans Petter Selasky 
617*d6b92ffaSHans Petter Selasky 	port_guid = p_user_bind->port_guid;
618*d6b92ffaSHans Petter Selasky 
619*d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_INFO,
620*d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: "
621*d6b92ffaSHans Petter Selasky 		"Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid));
622*d6b92ffaSHans Petter Selasky 
623*d6b92ffaSHans Petter Selasky 	/* obtain the hca name and port num from the guid */
624*d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
625*d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: "
626*d6b92ffaSHans Petter Selasky 		"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
627*d6b92ffaSHans Petter Selasky 		port_guid);
628*d6b92ffaSHans Petter Selasky 
629*d6b92ffaSHans Petter Selasky 	mgt_ret =
630*d6b92ffaSHans Petter Selasky 	    osm_vendor_get_guid_ca_and_port(p_vend, port_guid, &hca_hndl,
631*d6b92ffaSHans Petter Selasky 					    &hca_id, &port_num);
632*d6b92ffaSHans Petter Selasky 	if (mgt_ret != IB_MGT_OK) {
633*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
634*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 3C14: "
635*d6b92ffaSHans Petter Selasky 			"Unable to obtain CA and port (%d).\n");
636*d6b92ffaSHans Petter Selasky 		goto Exit;
637*d6b92ffaSHans Petter Selasky 	}
638*d6b92ffaSHans Petter Selasky 
639*d6b92ffaSHans Petter Selasky 	/* create the bind object tracking this binding */
640*d6b92ffaSHans Petter Selasky 	p_bind = (osm_mtl_bind_info_t *) malloc(sizeof(osm_mtl_bind_info_t));
641*d6b92ffaSHans Petter Selasky 	memset(p_bind, 0, sizeof(osm_mtl_bind_info_t));
642*d6b92ffaSHans Petter Selasky 	if (p_bind == NULL) {
643*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
644*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 3C15: "
645*d6b92ffaSHans Petter Selasky 			"Unable to allocate internal bind object.\n");
646*d6b92ffaSHans Petter Selasky 		goto Exit;
647*d6b92ffaSHans Petter Selasky 	}
648*d6b92ffaSHans Petter Selasky 
649*d6b92ffaSHans Petter Selasky 	/* track this bind request info */
650*d6b92ffaSHans Petter Selasky 	memcpy(p_bind->hca_id, hca_id, sizeof(VAPI_hca_id_t));
651*d6b92ffaSHans Petter Selasky 	p_bind->port_num = port_num;
652*d6b92ffaSHans Petter Selasky 	p_bind->p_vend = p_vend;
653*d6b92ffaSHans Petter Selasky 	p_bind->client_context = context;
654*d6b92ffaSHans Petter Selasky 	p_bind->rcv_callback = mad_recv_callback;
655*d6b92ffaSHans Petter Selasky 	p_bind->send_err_callback = send_err_callback;
656*d6b92ffaSHans Petter Selasky 	p_bind->p_osm_pool = p_mad_pool;
657*d6b92ffaSHans Petter Selasky 
658*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_bind->port_num);
659*d6b92ffaSHans Petter Selasky 
660*d6b92ffaSHans Petter Selasky 	/*
661*d6b92ffaSHans Petter Selasky 	 * Get the proper CLASS
662*d6b92ffaSHans Petter Selasky 	 */
663*d6b92ffaSHans Petter Selasky 
664*d6b92ffaSHans Petter Selasky 	switch (p_user_bind->mad_class) {
665*d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_LID:
666*d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_DIR:
667*d6b92ffaSHans Petter Selasky 		mad_type = IB_MGT_SMI;
668*d6b92ffaSHans Petter Selasky 		break;
669*d6b92ffaSHans Petter Selasky 
670*d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_ADM:
671*d6b92ffaSHans Petter Selasky 	default:
672*d6b92ffaSHans Petter Selasky 		mad_type = IB_MGT_GSI;
673*d6b92ffaSHans Petter Selasky 		break;
674*d6b92ffaSHans Petter Selasky 	}
675*d6b92ffaSHans Petter Selasky 
676*d6b92ffaSHans Petter Selasky 	/* we split here - based on the type of MADS GSI / SMI */
677*d6b92ffaSHans Petter Selasky 	/* HACK: we only support one class registration per SMI/GSI !!! */
678*d6b92ffaSHans Petter Selasky 	if (mad_type == IB_MGT_SMI) {
679*d6b92ffaSHans Petter Selasky 		/*
680*d6b92ffaSHans Petter Selasky 		 *  SMI CASE
681*d6b92ffaSHans Petter Selasky 		 */
682*d6b92ffaSHans Petter Selasky 
683*d6b92ffaSHans Petter Selasky 		/* we do not need to bind the handle if already available */
684*d6b92ffaSHans Petter Selasky 		if (ib_mgt_hdl_p->smi_init == FALSE) {
685*d6b92ffaSHans Petter Selasky 
686*d6b92ffaSHans Petter Selasky 			/* First we have to reg and get the handle for the mad */
687*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_ERROR,
688*d6b92ffaSHans Petter Selasky 				"osm_vendor_bind: "
689*d6b92ffaSHans Petter Selasky 				"Binding to IB_MGT SMI of %s port %u\n", hca_id,
690*d6b92ffaSHans Petter Selasky 				port_num);
691*d6b92ffaSHans Petter Selasky 
692*d6b92ffaSHans Petter Selasky 			mgt_ret =
693*d6b92ffaSHans Petter Selasky 			    IB_MGT_get_handle(hca_id, port_num, IB_MGT_SMI,
694*d6b92ffaSHans Petter Selasky 					      &(ib_mgt_hdl_p->smi_mads_hdl));
695*d6b92ffaSHans Petter Selasky 			if (IB_MGT_OK != mgt_ret) {
696*d6b92ffaSHans Petter Selasky 				free(p_bind);
697*d6b92ffaSHans Petter Selasky 				p_bind = NULL;
698*d6b92ffaSHans Petter Selasky 				osm_log(p_vend->p_log, OSM_LOG_ERROR,
699*d6b92ffaSHans Petter Selasky 					"osm_vendor_bind: ERR 3C16: "
700*d6b92ffaSHans Petter Selasky 					"Error obtaining IB_MGT handle to SMI.\n");
701*d6b92ffaSHans Petter Selasky 				goto Exit;
702*d6b92ffaSHans Petter Selasky 			}
703*d6b92ffaSHans Petter Selasky 
704*d6b92ffaSHans Petter Selasky 			/* bind it */
705*d6b92ffaSHans Petter Selasky 			mgt_ret = IB_MGT_bind_sm(ib_mgt_hdl_p->smi_mads_hdl);
706*d6b92ffaSHans Petter Selasky 			if (IB_MGT_OK != mgt_ret) {
707*d6b92ffaSHans Petter Selasky 				free(p_bind);
708*d6b92ffaSHans Petter Selasky 				p_bind = NULL;
709*d6b92ffaSHans Petter Selasky 				osm_log(p_vend->p_log, OSM_LOG_ERROR,
710*d6b92ffaSHans Petter Selasky 					"osm_vendor_bind: ERR 3C17: "
711*d6b92ffaSHans Petter Selasky 					"Error binding IB_MGT handle to SM.\n");
712*d6b92ffaSHans Petter Selasky 				goto Exit;
713*d6b92ffaSHans Petter Selasky 			}
714*d6b92ffaSHans Petter Selasky 
715*d6b92ffaSHans Petter Selasky 			ib_mgt_hdl_p->smi_init = TRUE;
716*d6b92ffaSHans Petter Selasky 
717*d6b92ffaSHans Petter Selasky 		}
718*d6b92ffaSHans Petter Selasky 
719*d6b92ffaSHans Petter Selasky 		/* attach to this bind info */
720*d6b92ffaSHans Petter Selasky 		p_bind->mad_hndl = ib_mgt_hdl_p->smi_mads_hdl;
721*d6b92ffaSHans Petter Selasky 		ib_mgt_hdl_p->smi_p_bind = p_bind;
722*d6b92ffaSHans Petter Selasky 
723*d6b92ffaSHans Petter Selasky 		/* now register the callback */
724*d6b92ffaSHans Petter Selasky 		mgt_ret = IB_MGT_reg_cb(p_bind->mad_hndl,
725*d6b92ffaSHans Petter Selasky 					&__osm_mtl_rcv_callback,
726*d6b92ffaSHans Petter Selasky 					p_bind,
727*d6b92ffaSHans Petter Selasky 					&__osm_mtl_send_callback,
728*d6b92ffaSHans Petter Selasky 					p_bind,
729*d6b92ffaSHans Petter Selasky 					IB_MGT_RCV_CB_MASK |
730*d6b92ffaSHans Petter Selasky 					IB_MGT_SEND_CB_MASK);
731*d6b92ffaSHans Petter Selasky 
732*d6b92ffaSHans Petter Selasky 	} else {
733*d6b92ffaSHans Petter Selasky 		/*
734*d6b92ffaSHans Petter Selasky 		 *  GSI CASE
735*d6b92ffaSHans Petter Selasky 		 */
736*d6b92ffaSHans Petter Selasky 
737*d6b92ffaSHans Petter Selasky 		if (ib_mgt_hdl_p->gsi_init == FALSE) {
738*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_ERROR,
739*d6b92ffaSHans Petter Selasky 				"osm_vendor_bind: " "Binding to IB_MGT GSI\n");
740*d6b92ffaSHans Petter Selasky 
741*d6b92ffaSHans Petter Selasky 			/* First we have to reg and get the handle for the mad */
742*d6b92ffaSHans Petter Selasky 			mgt_ret =
743*d6b92ffaSHans Petter Selasky 			    IB_MGT_get_handle(hca_id, port_num, IB_MGT_GSI,
744*d6b92ffaSHans Petter Selasky 					      &(ib_mgt_hdl_p->gsi_mads_hdl));
745*d6b92ffaSHans Petter Selasky 			if (IB_MGT_OK != mgt_ret) {
746*d6b92ffaSHans Petter Selasky 				free(p_bind);
747*d6b92ffaSHans Petter Selasky 				p_bind = NULL;
748*d6b92ffaSHans Petter Selasky 				osm_log(p_vend->p_log, OSM_LOG_ERROR,
749*d6b92ffaSHans Petter Selasky 					"osm_vendor_bind: ERR 3C20: "
750*d6b92ffaSHans Petter Selasky 					"Error obtaining IB_MGT handle to GSI.\n");
751*d6b92ffaSHans Petter Selasky 				goto Exit;
752*d6b92ffaSHans Petter Selasky 			}
753*d6b92ffaSHans Petter Selasky 
754*d6b92ffaSHans Petter Selasky 			/* bind it */
755*d6b92ffaSHans Petter Selasky 			mgt_ret =
756*d6b92ffaSHans Petter Selasky 			    IB_MGT_bind_gsi_class(ib_mgt_hdl_p->gsi_mads_hdl,
757*d6b92ffaSHans Petter Selasky 						  p_user_bind->mad_class);
758*d6b92ffaSHans Petter Selasky 			if (IB_MGT_OK != mgt_ret) {
759*d6b92ffaSHans Petter Selasky 				free(p_bind);
760*d6b92ffaSHans Petter Selasky 				p_bind = NULL;
761*d6b92ffaSHans Petter Selasky 				osm_log(p_vend->p_log, OSM_LOG_ERROR,
762*d6b92ffaSHans Petter Selasky 					"osm_vendor_bind: ERR 3C22: "
763*d6b92ffaSHans Petter Selasky 					"Error binding IB_MGT handle to GSI.\n");
764*d6b92ffaSHans Petter Selasky 				goto Exit;
765*d6b92ffaSHans Petter Selasky 			}
766*d6b92ffaSHans Petter Selasky 
767*d6b92ffaSHans Petter Selasky 			ib_mgt_hdl_p->gsi_init = TRUE;
768*d6b92ffaSHans Petter Selasky 
769*d6b92ffaSHans Petter Selasky 			/* attach to this bind info */
770*d6b92ffaSHans Petter Selasky 			p_bind->mad_hndl = ib_mgt_hdl_p->gsi_mads_hdl;
771*d6b92ffaSHans Petter Selasky 
772*d6b92ffaSHans Petter Selasky 			/* now register the callback */
773*d6b92ffaSHans Petter Selasky 			mgt_ret = IB_MGT_reg_cb(p_bind->mad_hndl,
774*d6b92ffaSHans Petter Selasky 						&__osm_mtl_rcv_callback,
775*d6b92ffaSHans Petter Selasky 						p_bind,
776*d6b92ffaSHans Petter Selasky 						&__osm_mtl_send_callback,
777*d6b92ffaSHans Petter Selasky 						p_bind,
778*d6b92ffaSHans Petter Selasky 						IB_MGT_RCV_CB_MASK |
779*d6b92ffaSHans Petter Selasky 						IB_MGT_SEND_CB_MASK);
780*d6b92ffaSHans Petter Selasky 
781*d6b92ffaSHans Petter Selasky 		} else {
782*d6b92ffaSHans Petter Selasky 			/* we can use the existing handle */
783*d6b92ffaSHans Petter Selasky 			p_bind->mad_hndl = ib_mgt_hdl_p->gsi_mads_hdl;
784*d6b92ffaSHans Petter Selasky 			mgt_ret = IB_MGT_OK;
785*d6b92ffaSHans Petter Selasky 		}
786*d6b92ffaSHans Petter Selasky 
787*d6b92ffaSHans Petter Selasky 	}
788*d6b92ffaSHans Petter Selasky 
789*d6b92ffaSHans Petter Selasky 	if (IB_MGT_OK != mgt_ret) {
790*d6b92ffaSHans Petter Selasky 		free(p_bind);
791*d6b92ffaSHans Petter Selasky 		p_bind = NULL;
792*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
793*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 3C23: "
794*d6b92ffaSHans Petter Selasky 			"Error binding IB_MGT CB (%d).\n", mgt_ret);
795*d6b92ffaSHans Petter Selasky 		goto Exit;
796*d6b92ffaSHans Petter Selasky 	}
797*d6b92ffaSHans Petter Selasky 
798*d6b92ffaSHans Petter Selasky 	/* HACK: Do we need to initialize an address vector ???? */
799*d6b92ffaSHans Petter Selasky 
800*d6b92ffaSHans Petter Selasky Exit:
801*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
802*d6b92ffaSHans Petter Selasky 	return ((osm_bind_handle_t) p_bind);
803*d6b92ffaSHans Petter Selasky }
804*d6b92ffaSHans Petter Selasky 
805*d6b92ffaSHans Petter Selasky /**********************************************************************
806*d6b92ffaSHans Petter Selasky Get a mad from the lower level.
807*d6b92ffaSHans Petter Selasky The osm_vend_wrap_t is a wrapper used to connect the mad to the response.
808*d6b92ffaSHans Petter Selasky **********************************************************************/
osm_vendor_get(IN osm_bind_handle_t h_bind,IN const uint32_t mad_size,IN osm_vend_wrap_t * const p_vw)809*d6b92ffaSHans Petter Selasky ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
810*d6b92ffaSHans Petter Selasky 			 IN const uint32_t mad_size,
811*d6b92ffaSHans Petter Selasky 			 IN osm_vend_wrap_t * const p_vw)
812*d6b92ffaSHans Petter Selasky {
813*d6b92ffaSHans Petter Selasky 	ib_mad_t *mad_p;
814*d6b92ffaSHans Petter Selasky 	osm_mtl_bind_info_t *p_bind = (osm_mtl_bind_info_t *) h_bind;
815*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
816*d6b92ffaSHans Petter Selasky 
817*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
818*d6b92ffaSHans Petter Selasky 
819*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw);
820*d6b92ffaSHans Petter Selasky 	/* HACK: We know we can not send through IB_MGT */
821*d6b92ffaSHans Petter Selasky 	CL_ASSERT(mad_size <= MAD_BLOCK_SIZE);
822*d6b92ffaSHans Petter Selasky 
823*d6b92ffaSHans Petter Selasky 	/* IB_MGT assumes it is 256 - we must follow */
824*d6b92ffaSHans Petter Selasky 	p_vw->size = MAD_BLOCK_SIZE;
825*d6b92ffaSHans Petter Selasky 
826*d6b92ffaSHans Petter Selasky 	/* allocate it */
827*d6b92ffaSHans Petter Selasky 	mad_p = (ib_mad_t *) malloc(p_vw->size);
828*d6b92ffaSHans Petter Selasky 	if (mad_p == NULL) {
829*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
830*d6b92ffaSHans Petter Selasky 			"osm_vendor_get: ERR 3C24: "
831*d6b92ffaSHans Petter Selasky 			"Error Obtaining MAD buffer.\n");
832*d6b92ffaSHans Petter Selasky 		goto Exit;
833*d6b92ffaSHans Petter Selasky 	}
834*d6b92ffaSHans Petter Selasky 
835*d6b92ffaSHans Petter Selasky 	memset(mad_p, 0, p_vw->size);
836*d6b92ffaSHans Petter Selasky 
837*d6b92ffaSHans Petter Selasky 	/* track locally */
838*d6b92ffaSHans Petter Selasky 	p_vw->mad_buf_p = mad_p;
839*d6b92ffaSHans Petter Selasky 	p_vw->h_bind = h_bind;
840*d6b92ffaSHans Petter Selasky 	p_vw->p_resp_madw = NULL;
841*d6b92ffaSHans Petter Selasky 
842*d6b92ffaSHans Petter Selasky 	if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
843*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
844*d6b92ffaSHans Petter Selasky 			"osm_vendor_get: "
845*d6b92ffaSHans Petter Selasky 			"Acquired MAD %p, size = %u.\n", mad_p, p_vw->size);
846*d6b92ffaSHans Petter Selasky 	}
847*d6b92ffaSHans Petter Selasky 
848*d6b92ffaSHans Petter Selasky Exit:
849*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
850*d6b92ffaSHans Petter Selasky 	return (mad_p);
851*d6b92ffaSHans Petter Selasky }
852*d6b92ffaSHans Petter Selasky 
853*d6b92ffaSHans Petter Selasky /**********************************************************************
854*d6b92ffaSHans Petter Selasky  * Return a MAD by providing it's wrapper object.
855*d6b92ffaSHans Petter Selasky  **********************************************************************/
856*d6b92ffaSHans Petter Selasky void
osm_vendor_put(IN osm_bind_handle_t h_bind,IN osm_vend_wrap_t * const p_vw)857*d6b92ffaSHans Petter Selasky osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw)
858*d6b92ffaSHans Petter Selasky {
859*d6b92ffaSHans Petter Selasky 	osm_mtl_bind_info_t *p_bind = (osm_mtl_bind_info_t *) h_bind;
860*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
861*d6b92ffaSHans Petter Selasky 	osm_madw_t *p_madw;
862*d6b92ffaSHans Petter Selasky 
863*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
864*d6b92ffaSHans Petter Selasky 
865*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw);
866*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw->mad_buf_p);
867*d6b92ffaSHans Petter Selasky 
868*d6b92ffaSHans Petter Selasky 	if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
869*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
870*d6b92ffaSHans Petter Selasky 			"osm_vendor_put: " "Retiring MAD %p.\n",
871*d6b92ffaSHans Petter Selasky 			p_vw->mad_buf_p);
872*d6b92ffaSHans Petter Selasky 	}
873*d6b92ffaSHans Petter Selasky 
874*d6b92ffaSHans Petter Selasky 	/*
875*d6b92ffaSHans Petter Selasky 	 * We moved the removal of the transaction to immediatly after
876*d6b92ffaSHans Petter Selasky 	 * it was looked up.
877*d6b92ffaSHans Petter Selasky 	 */
878*d6b92ffaSHans Petter Selasky 
879*d6b92ffaSHans Petter Selasky 	/* free the mad but the wrapper is part of the madw object */
880*d6b92ffaSHans Petter Selasky 	free(p_vw->mad_buf_p);
881*d6b92ffaSHans Petter Selasky 	p_vw->mad_buf_p = NULL;
882*d6b92ffaSHans Petter Selasky 	p_madw = PARENT_STRUCT(p_vw, osm_madw_t, vend_wrap);
883*d6b92ffaSHans Petter Selasky 	p_madw->p_mad = NULL;
884*d6b92ffaSHans Petter Selasky 
885*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
886*d6b92ffaSHans Petter Selasky }
887*d6b92ffaSHans Petter Selasky 
888*d6b92ffaSHans Petter Selasky /**********************************************************************
889*d6b92ffaSHans Petter Selasky Actually Send a MAD
890*d6b92ffaSHans Petter Selasky 
891*d6b92ffaSHans Petter Selasky This is for internal use by osm_vendor_send and the transaction mgr
892*d6b92ffaSHans Petter Selasky retry too.
893*d6b92ffaSHans Petter Selasky **********************************************************************/
894*d6b92ffaSHans Petter Selasky ib_api_status_t
osm_mtl_send_mad(IN osm_mtl_bind_info_t * p_bind,IN osm_madw_t * const p_madw)895*d6b92ffaSHans Petter Selasky osm_mtl_send_mad(IN osm_mtl_bind_info_t * p_bind, IN osm_madw_t * const p_madw)
896*d6b92ffaSHans Petter Selasky {
897*d6b92ffaSHans Petter Selasky 	osm_vendor_t *const p_vend = p_bind->p_vend;
898*d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
899*d6b92ffaSHans Petter Selasky 	osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
900*d6b92ffaSHans Petter Selasky 	ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw);
901*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
902*d6b92ffaSHans Petter Selasky 	IB_MGT_ret_t mgt_res;
903*d6b92ffaSHans Petter Selasky 	IB_ud_av_t av;
904*d6b92ffaSHans Petter Selasky 	uint64_t wrid;
905*d6b92ffaSHans Petter Selasky 	uint32_t qpn;
906*d6b92ffaSHans Petter Selasky 
907*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
908*d6b92ffaSHans Petter Selasky 
909*d6b92ffaSHans Petter Selasky 	/*
910*d6b92ffaSHans Petter Selasky 	 * For all sends other than directed route SM MADs,
911*d6b92ffaSHans Petter Selasky 	 * acquire an address vector for the destination.
912*d6b92ffaSHans Petter Selasky 	 */
913*d6b92ffaSHans Petter Selasky 	if (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) {
914*d6b92ffaSHans Petter Selasky 		__osm_mtl_conv_osm_addr_to_ibmgt_addr(p_mad_addr,
915*d6b92ffaSHans Petter Selasky 						      p_mad->mgmt_class ==
916*d6b92ffaSHans Petter Selasky 						      IB_MCLASS_SUBN_LID, &av);
917*d6b92ffaSHans Petter Selasky 	} else {
918*d6b92ffaSHans Petter Selasky 		/* is a directed route - we need to construct a permissive address */
919*d6b92ffaSHans Petter Selasky 		memset(&av, 0, sizeof(av));
920*d6b92ffaSHans Petter Selasky 		/* we do not need port number since it is part of the mad_hndl */
921*d6b92ffaSHans Petter Selasky 		av.dlid = IB_LID_PERMISSIVE;
922*d6b92ffaSHans Petter Selasky 	}
923*d6b92ffaSHans Petter Selasky 
924*d6b92ffaSHans Petter Selasky 	wrid = __osm_set_wrid_by_p_madw(p_madw);
925*d6b92ffaSHans Petter Selasky 
926*d6b92ffaSHans Petter Selasky 	/* send it */
927*d6b92ffaSHans Petter Selasky 	if ((p_mad->mgmt_class == IB_MCLASS_SUBN_DIR) ||
928*d6b92ffaSHans Petter Selasky 	    (p_mad->mgmt_class == IB_MCLASS_SUBN_LID)) {
929*d6b92ffaSHans Petter Selasky 
930*d6b92ffaSHans Petter Selasky 		/* SMI CASE */
931*d6b92ffaSHans Petter Selasky 		if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
932*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
933*d6b92ffaSHans Petter Selasky 				"osm_mtl_send_mad: "
934*d6b92ffaSHans Petter Selasky 				"av.dlid 0x%X, "
935*d6b92ffaSHans Petter Selasky 				"av.static_rate %d, "
936*d6b92ffaSHans Petter Selasky 				"av.path_bits %d.\n",
937*d6b92ffaSHans Petter Selasky 				cl_ntoh16(av.dlid), av.static_rate,
938*d6b92ffaSHans Petter Selasky 				av.src_path_bits);
939*d6b92ffaSHans Petter Selasky 		}
940*d6b92ffaSHans Petter Selasky 
941*d6b92ffaSHans Petter Selasky 		mgt_res = IB_MGT_send_mad(p_bind->mad_hndl, p_mad,	/*  actual payload */
942*d6b92ffaSHans Petter Selasky 					  &av,	/*  address vector */
943*d6b92ffaSHans Petter Selasky 					  wrid,	/*  casting the mad wrapper pointer for err cb */
944*d6b92ffaSHans Petter Selasky 					  p_vend->timeout);
945*d6b92ffaSHans Petter Selasky 
946*d6b92ffaSHans Petter Selasky 	} else {
947*d6b92ffaSHans Petter Selasky 		/* GSI CASE - Support Remote QP */
948*d6b92ffaSHans Petter Selasky 		if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
949*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
950*d6b92ffaSHans Petter Selasky 				"osm_mtl_send_mad: "
951*d6b92ffaSHans Petter Selasky 				"av.dlid 0x%X, av.static_rate %d, "
952*d6b92ffaSHans Petter Selasky 				"av.path_bits %d, remote qp: 0x%06X \n",
953*d6b92ffaSHans Petter Selasky 				av.dlid,
954*d6b92ffaSHans Petter Selasky 				av.static_rate,
955*d6b92ffaSHans Petter Selasky 				av.src_path_bits,
956*d6b92ffaSHans Petter Selasky 				cl_ntoh32(p_mad_addr->addr_type.gsi.remote_qp)
957*d6b92ffaSHans Petter Selasky 			    );
958*d6b92ffaSHans Petter Selasky 		}
959*d6b92ffaSHans Petter Selasky 
960*d6b92ffaSHans Petter Selasky 		/* IBMGT have a bug sending to a QP not 1 -
961*d6b92ffaSHans Petter Selasky 		   the QPN must be in network order except when it qpn 1 ... */
962*d6b92ffaSHans Petter Selasky 		qpn = cl_ntoh32(p_mad_addr->addr_type.gsi.remote_qp);
963*d6b92ffaSHans Petter Selasky 
964*d6b92ffaSHans Petter Selasky 		mgt_res = IB_MGT_send_mad_to_qp(p_bind->mad_hndl, p_mad,	/*  actual payload */
965*d6b92ffaSHans Petter Selasky 						&av,	/* address vector */
966*d6b92ffaSHans Petter Selasky 						wrid,	/* casting the mad wrapper pointer for err cb */
967*d6b92ffaSHans Petter Selasky 						p_vend->timeout, qpn);
968*d6b92ffaSHans Petter Selasky 	}
969*d6b92ffaSHans Petter Selasky 
970*d6b92ffaSHans Petter Selasky 	if (mgt_res != IB_MGT_OK) {
971*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
972*d6b92ffaSHans Petter Selasky 			"osm_mtl_send_mad: ERR 3C26: "
973*d6b92ffaSHans Petter Selasky 			"Error sending mad (%d).\n", mgt_res);
974*d6b92ffaSHans Petter Selasky 		if (p_vw->p_resp_madw)
975*d6b92ffaSHans Petter Selasky 			osm_mad_pool_put(p_bind->p_osm_pool, p_vw->p_resp_madw);
976*d6b92ffaSHans Petter Selasky 		status = IB_ERROR;
977*d6b92ffaSHans Petter Selasky 		goto Exit;
978*d6b92ffaSHans Petter Selasky 	}
979*d6b92ffaSHans Petter Selasky 
980*d6b92ffaSHans Petter Selasky 	status = IB_SUCCESS;
981*d6b92ffaSHans Petter Selasky 
982*d6b92ffaSHans Petter Selasky Exit:
983*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
984*d6b92ffaSHans Petter Selasky 	return (status);
985*d6b92ffaSHans Petter Selasky }
986*d6b92ffaSHans Petter Selasky 
987*d6b92ffaSHans Petter Selasky /**********************************************************************
988*d6b92ffaSHans Petter Selasky Send a MAD through.
989*d6b92ffaSHans Petter Selasky 
990*d6b92ffaSHans Petter Selasky What is unclear to me is the need for the setting of all the MAD Wrapper
991*d6b92ffaSHans Petter Selasky fields. Seems like the OSM uses these values during it's processing...
992*d6b92ffaSHans Petter Selasky **********************************************************************/
993*d6b92ffaSHans Petter Selasky ib_api_status_t
osm_vendor_send(IN osm_bind_handle_t h_bind,IN osm_madw_t * const p_madw,IN boolean_t const resp_expected)994*d6b92ffaSHans Petter Selasky osm_vendor_send(IN osm_bind_handle_t h_bind,
995*d6b92ffaSHans Petter Selasky 		IN osm_madw_t * const p_madw, IN boolean_t const resp_expected)
996*d6b92ffaSHans Petter Selasky {
997*d6b92ffaSHans Petter Selasky 	osm_mtl_bind_info_t *const p_bind = (osm_mtl_bind_info_t *) h_bind;
998*d6b92ffaSHans Petter Selasky 	osm_vendor_t *const p_vend = p_bind->p_vend;
999*d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
1000*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
1001*d6b92ffaSHans Petter Selasky 
1002*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
1003*d6b92ffaSHans Petter Selasky 
1004*d6b92ffaSHans Petter Selasky 	/*
1005*d6b92ffaSHans Petter Selasky 	 * If a response is expected to this MAD, then preallocate
1006*d6b92ffaSHans Petter Selasky 	 * a mad wrapper to contain the wire MAD received in the
1007*d6b92ffaSHans Petter Selasky 	 * response.  Allocating a wrapper here allows for easier
1008*d6b92ffaSHans Petter Selasky 	 * failure paths than after we already received the wire mad.
1009*d6b92ffaSHans Petter Selasky 	 */
1010*d6b92ffaSHans Petter Selasky 	if (resp_expected == TRUE) {
1011*d6b92ffaSHans Petter Selasky 		/* we track it in the vendor wrapper */
1012*d6b92ffaSHans Petter Selasky 		p_vw->p_resp_madw =
1013*d6b92ffaSHans Petter Selasky 		    osm_mad_pool_get_wrapper_raw(p_bind->p_osm_pool);
1014*d6b92ffaSHans Petter Selasky 		if (p_vw->p_resp_madw == NULL) {
1015*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_ERROR,
1016*d6b92ffaSHans Petter Selasky 				"osm_vendor_send: ERR 3C27: "
1017*d6b92ffaSHans Petter Selasky 				"Unable to allocate MAD wrapper.\n");
1018*d6b92ffaSHans Petter Selasky 			status = IB_INSUFFICIENT_RESOURCES;
1019*d6b92ffaSHans Petter Selasky 			goto Exit;
1020*d6b92ffaSHans Petter Selasky 		}
1021*d6b92ffaSHans Petter Selasky 
1022*d6b92ffaSHans Petter Selasky 		/* put some minimal info on that wrapper */
1023*d6b92ffaSHans Petter Selasky 		((osm_madw_t *) (p_vw->p_resp_madw))->h_bind = h_bind;
1024*d6b92ffaSHans Petter Selasky 
1025*d6b92ffaSHans Petter Selasky 		/* we also want to track it in the TID based map */
1026*d6b92ffaSHans Petter Selasky 		status = osm_transaction_mgr_insert_madw((osm_bind_handle_t)
1027*d6b92ffaSHans Petter Selasky 							 p_bind, p_madw);
1028*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
1029*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_ERROR,
1030*d6b92ffaSHans Petter Selasky 				"osm_vendor_send: ERR 3C25: "
1031*d6b92ffaSHans Petter Selasky 				"Error inserting request madw by TID (%d).\n",
1032*d6b92ffaSHans Petter Selasky 				status);
1033*d6b92ffaSHans Petter Selasky 		}
1034*d6b92ffaSHans Petter Selasky 
1035*d6b92ffaSHans Petter Selasky 	} else
1036*d6b92ffaSHans Petter Selasky 		p_vw->p_resp_madw = NULL;
1037*d6b92ffaSHans Petter Selasky 
1038*d6b92ffaSHans Petter Selasky 	/* do the actual send */
1039*d6b92ffaSHans Petter Selasky 	status = osm_mtl_send_mad(p_bind, p_madw);
1040*d6b92ffaSHans Petter Selasky 
1041*d6b92ffaSHans Petter Selasky Exit:
1042*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
1043*d6b92ffaSHans Petter Selasky 	return (status);
1044*d6b92ffaSHans Petter Selasky }
1045*d6b92ffaSHans Petter Selasky 
1046*d6b92ffaSHans Petter Selasky /**********************************************************************
1047*d6b92ffaSHans Petter Selasky  * the idea here is to change the content of the bind such that it
1048*d6b92ffaSHans Petter Selasky  * will hold the local address used for sending directed route by the SMA.
1049*d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)1050*d6b92ffaSHans Petter Selasky ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)
1051*d6b92ffaSHans Petter Selasky {
1052*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = ((osm_mtl_bind_info_t *) h_bind)->p_vend;
1053*d6b92ffaSHans Petter Selasky 
1054*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
1055*d6b92ffaSHans Petter Selasky 
1056*d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1057*d6b92ffaSHans Petter Selasky 		"osm_vendor_local_lid_change: DEBUG 2202: " "Change of LID.\n");
1058*d6b92ffaSHans Petter Selasky 
1059*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
1060*d6b92ffaSHans Petter Selasky 
1061*d6b92ffaSHans Petter Selasky 	return (IB_SUCCESS);
1062*d6b92ffaSHans Petter Selasky }
1063*d6b92ffaSHans Petter Selasky 
osm_vendor_set_sm(IN osm_bind_handle_t h_bind,IN boolean_t is_sm_val)1064*d6b92ffaSHans Petter Selasky void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
1065*d6b92ffaSHans Petter Selasky {
1066*d6b92ffaSHans Petter Selasky 	osm_mtl_bind_info_t *p_bind = (osm_mtl_bind_info_t *) h_bind;
1067*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
1068*d6b92ffaSHans Petter Selasky 	VAPI_ret_t status;
1069*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_t attr_mod;
1070*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_mask_t attr_mask;
1071*d6b92ffaSHans Petter Selasky 
1072*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
1073*d6b92ffaSHans Petter Selasky 
1074*d6b92ffaSHans Petter Selasky 	memset(&attr_mod, 0, sizeof(attr_mod));
1075*d6b92ffaSHans Petter Selasky 	memset(&attr_mask, 0, sizeof(attr_mask));
1076*d6b92ffaSHans Petter Selasky 
1077*d6b92ffaSHans Petter Selasky 	attr_mod.is_sm = is_sm_val;
1078*d6b92ffaSHans Petter Selasky 	attr_mask = HCA_ATTR_IS_SM;
1079*d6b92ffaSHans Petter Selasky 
1080*d6b92ffaSHans Petter Selasky 	status =
1081*d6b92ffaSHans Petter Selasky 	    VAPI_modify_hca_attr(p_bind->hca_hndl, p_bind->port_num, &attr_mod,
1082*d6b92ffaSHans Petter Selasky 				 &attr_mask);
1083*d6b92ffaSHans Petter Selasky 	if (status != VAPI_OK) {
1084*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
1085*d6b92ffaSHans Petter Selasky 			"osm_vendor_set_sm: ERR 3C28: "
1086*d6b92ffaSHans Petter Selasky 			"Unable set 'IS_SM' bit to:%u in port attributes (%d).\n",
1087*d6b92ffaSHans Petter Selasky 			is_sm_val, status);
1088*d6b92ffaSHans Petter Selasky 	}
1089*d6b92ffaSHans Petter Selasky 
1090*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
1091*d6b92ffaSHans Petter Selasky }
1092*d6b92ffaSHans Petter Selasky 
osm_vendor_set_debug(IN osm_vendor_t * const p_vend,IN int32_t level)1093*d6b92ffaSHans Petter Selasky void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level)
1094*d6b92ffaSHans Petter Selasky {
1095*d6b92ffaSHans Petter Selasky 
1096*d6b92ffaSHans Petter Selasky }
1097*d6b92ffaSHans Petter Selasky 
1098*d6b92ffaSHans Petter Selasky #endif				/* OSM_VENDOR_INTF_TEST */
1099