1d6b92ffaSHans Petter Selasky /*
2d6b92ffaSHans Petter Selasky  * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3d6b92ffaSHans Petter Selasky  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4d6b92ffaSHans Petter Selasky  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5d6b92ffaSHans Petter Selasky  *
6d6b92ffaSHans Petter Selasky  * This software is available to you under a choice of one of two
7d6b92ffaSHans Petter Selasky  * licenses.  You may choose to be licensed under the terms of the GNU
8d6b92ffaSHans Petter Selasky  * General Public License (GPL) Version 2, available from the file
9d6b92ffaSHans Petter Selasky  * COPYING in the main directory of this source tree, or the
10d6b92ffaSHans Petter Selasky  * OpenIB.org BSD license below:
11d6b92ffaSHans Petter Selasky  *
12d6b92ffaSHans Petter Selasky  *     Redistribution and use in source and binary forms, with or
13d6b92ffaSHans Petter Selasky  *     without modification, are permitted provided that the following
14d6b92ffaSHans Petter Selasky  *     conditions are met:
15d6b92ffaSHans Petter Selasky  *
16d6b92ffaSHans Petter Selasky  *      - Redistributions of source code must retain the above
17d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
18d6b92ffaSHans Petter Selasky  *        disclaimer.
19d6b92ffaSHans Petter Selasky  *
20d6b92ffaSHans Petter Selasky  *      - Redistributions in binary form must reproduce the above
21d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
22d6b92ffaSHans Petter Selasky  *        disclaimer in the documentation and/or other materials
23d6b92ffaSHans Petter Selasky  *        provided with the distribution.
24d6b92ffaSHans Petter Selasky  *
25d6b92ffaSHans Petter Selasky  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26d6b92ffaSHans Petter Selasky  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27d6b92ffaSHans Petter Selasky  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28d6b92ffaSHans Petter Selasky  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29d6b92ffaSHans Petter Selasky  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30d6b92ffaSHans Petter Selasky  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31d6b92ffaSHans Petter Selasky  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32d6b92ffaSHans Petter Selasky  * SOFTWARE.
33d6b92ffaSHans Petter Selasky  *
34d6b92ffaSHans Petter Selasky  */
35d6b92ffaSHans Petter Selasky 
36d6b92ffaSHans Petter Selasky #undef __init
37d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
38d6b92ffaSHans Petter Selasky #  include <config.h>
39d6b92ffaSHans Petter Selasky #endif				/* HAVE_CONFIG_H */
40d6b92ffaSHans Petter Selasky 
41d6b92ffaSHans Petter Selasky #include <stdlib.h>
42d6b92ffaSHans Petter Selasky #include <string.h>
43d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_ts.h>
44d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_api.h>
45d6b92ffaSHans Petter Selasky #include <vendor/osm_ts_useraccess.h>
46d6b92ffaSHans Petter Selasky #include <opensm/osm_subnet.h>
47d6b92ffaSHans Petter Selasky #include <opensm/osm_opensm.h>
48d6b92ffaSHans Petter Selasky 
49d6b92ffaSHans Petter Selasky /*
50d6b92ffaSHans Petter Selasky   Since a race can accure on requests. Meaning - a response is received before
51d6b92ffaSHans Petter Selasky   the send_callback is called - we will save both the madw_p and the fact
52d6b92ffaSHans Petter Selasky   whether or not it is a response. A race can occure only on requests that did
53d6b92ffaSHans Petter Selasky   not fail, and then the madw_p will be put back in the pool before the
54d6b92ffaSHans Petter Selasky   callback.
55d6b92ffaSHans Petter Selasky */
__osm_set_wrid_by_p_madw(IN osm_madw_t * p_madw)56d6b92ffaSHans Petter Selasky uint64_t __osm_set_wrid_by_p_madw(IN osm_madw_t * p_madw)
57d6b92ffaSHans Petter Selasky {
58d6b92ffaSHans Petter Selasky 	uint64_t wrid = 0;
59d6b92ffaSHans Petter Selasky 
60d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw->p_mad);
61d6b92ffaSHans Petter Selasky 
62d6b92ffaSHans Petter Selasky 	memcpy(&wrid, &p_madw, sizeof(osm_madw_t *));
63d6b92ffaSHans Petter Selasky 	wrid = (wrid << 1) |
64d6b92ffaSHans Petter Selasky 	    ib_mad_is_response(p_madw->p_mad);
65d6b92ffaSHans Petter Selasky 	return wrid;
66d6b92ffaSHans Petter Selasky }
67d6b92ffaSHans Petter Selasky 
68d6b92ffaSHans 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)69d6b92ffaSHans Petter Selasky __osm_set_p_madw_and_resp_by_wrid(IN uint64_t wrid,
70d6b92ffaSHans Petter Selasky 				  OUT uint8_t * is_resp,
71d6b92ffaSHans Petter Selasky 				  OUT osm_madw_t ** pp_madw)
72d6b92ffaSHans Petter Selasky {
73d6b92ffaSHans Petter Selasky 	*is_resp = wrid & 0x0000000000000001;
74d6b92ffaSHans Petter Selasky 	wrid = wrid >> 1;
75d6b92ffaSHans Petter Selasky 	memcpy(pp_madw, &wrid, sizeof(osm_madw_t *));
76d6b92ffaSHans Petter Selasky }
77d6b92ffaSHans Petter Selasky 
78d6b92ffaSHans Petter Selasky /**********************************************************************
79d6b92ffaSHans Petter Selasky  * TS MAD to OSM ADDRESS VECTOR
80d6b92ffaSHans Petter Selasky  **********************************************************************/
81d6b92ffaSHans Petter Selasky void
__osm_ts_conv_mad_rcv_desc_to_osm_addr(IN osm_vendor_t * const p_vend,IN struct ib_mad * p_mad,IN uint8_t is_smi,OUT osm_mad_addr_t * p_mad_addr)82d6b92ffaSHans Petter Selasky __osm_ts_conv_mad_rcv_desc_to_osm_addr(IN osm_vendor_t * const p_vend,
83d6b92ffaSHans Petter Selasky 				       IN struct ib_mad *p_mad,
84d6b92ffaSHans Petter Selasky 				       IN uint8_t is_smi,
85d6b92ffaSHans Petter Selasky 				       OUT osm_mad_addr_t * p_mad_addr)
86d6b92ffaSHans Petter Selasky {
87d6b92ffaSHans Petter Selasky 	p_mad_addr->dest_lid = cl_hton16(p_mad->slid);
88d6b92ffaSHans Petter Selasky 	p_mad_addr->static_rate = 0;	/*  HACK - we do not know the rate ! */
89d6b92ffaSHans Petter Selasky 	p_mad_addr->path_bits = 0;	/*  HACK - no way to know in TS */
90d6b92ffaSHans Petter Selasky 	if (is_smi) {
91d6b92ffaSHans Petter Selasky 		/* SMI */
92d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.smi.source_lid = cl_hton16(p_mad->slid);
93d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.smi.port_num = p_mad->port;
94d6b92ffaSHans Petter Selasky 	} else {
95d6b92ffaSHans Petter Selasky 		/* GSI */
96d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.remote_qp = p_mad->sqpn;
97d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
98d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.pkey_ix = p_mad->pkey_index;
99d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.service_level = 0;	/*  HACK no way to know */
100d6b92ffaSHans Petter Selasky 
101d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.global_route = FALSE;	/*  HACK no way to know */
102d6b92ffaSHans Petter Selasky 		/* copy the GRH data if relevant */
103d6b92ffaSHans Petter Selasky 		/*
104d6b92ffaSHans Petter Selasky 		   if (p_mad_addr->addr_type.gsi.global_route)
105d6b92ffaSHans Petter Selasky 		   {
106d6b92ffaSHans Petter Selasky 		   p_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
107d6b92ffaSHans Petter Selasky 		   ib_grh_set_ver_class_flow(p_rcv_desc->grh.IP_version,
108d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.traffic_class,
109d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.flow_label);
110d6b92ffaSHans Petter Selasky 		   p_mad_addr->addr_type.gsi.grh_info.hop_limit =  p_rcv_desc->grh.hop_limit;
111d6b92ffaSHans Petter Selasky 		   memcpy(&p_mad_addr->addr_type.gsi.grh_info.src_gid.raw,
112d6b92ffaSHans Petter Selasky 		   &p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
113d6b92ffaSHans Petter Selasky 		   memcpy(&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
114d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.dgid,  sizeof(ib_net64_t));
115d6b92ffaSHans Petter Selasky 		   }
116d6b92ffaSHans Petter Selasky 		 */
117d6b92ffaSHans Petter Selasky 	}
118d6b92ffaSHans Petter Selasky }
119d6b92ffaSHans Petter Selasky 
120d6b92ffaSHans Petter Selasky /**********************************************************************
121d6b92ffaSHans Petter Selasky  * OSM ADDR VECTOR TO TS MAD:
122d6b92ffaSHans Petter Selasky  **********************************************************************/
123d6b92ffaSHans Petter Selasky void
__osm_ts_conv_osm_addr_to_ts_addr(IN osm_mad_addr_t * p_mad_addr,IN uint8_t is_smi,OUT struct ib_mad * p_mad)124d6b92ffaSHans Petter Selasky __osm_ts_conv_osm_addr_to_ts_addr(IN osm_mad_addr_t * p_mad_addr,
125d6b92ffaSHans Petter Selasky 				  IN uint8_t is_smi, OUT struct ib_mad *p_mad)
126d6b92ffaSHans Petter Selasky {
127d6b92ffaSHans Petter Selasky 
128d6b92ffaSHans Petter Selasky 	/* For global destination or Multicast address: */
129d6b92ffaSHans Petter Selasky 	p_mad->dlid = cl_ntoh16(p_mad_addr->dest_lid);
130d6b92ffaSHans Petter Selasky 	p_mad->sl = 0;
131d6b92ffaSHans Petter Selasky 	if (is_smi) {
132d6b92ffaSHans Petter Selasky 		p_mad->sqpn = 0;
133d6b92ffaSHans Petter Selasky 		p_mad->dqpn = 0;
134d6b92ffaSHans Petter Selasky 	} else {
135d6b92ffaSHans Petter Selasky 		p_mad->sqpn = 1;
136d6b92ffaSHans Petter Selasky 		p_mad->dqpn = p_mad_addr->addr_type.gsi.remote_qp;
137d6b92ffaSHans Petter Selasky 	}
138d6b92ffaSHans Petter Selasky }
139d6b92ffaSHans Petter Selasky 
__osm_vendor_clear_sm(IN osm_bind_handle_t h_bind)140d6b92ffaSHans Petter Selasky void __osm_vendor_clear_sm(IN osm_bind_handle_t h_bind)
141d6b92ffaSHans Petter Selasky {
142d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
143d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
144d6b92ffaSHans Petter Selasky 	VAPI_ret_t status;
145d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_t attr_mod;
146d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_mask_t attr_mask;
147d6b92ffaSHans Petter Selasky 
148d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
149d6b92ffaSHans Petter Selasky 
150d6b92ffaSHans Petter Selasky 	memset(&attr_mod, 0, sizeof(attr_mod));
151d6b92ffaSHans Petter Selasky 	memset(&attr_mask, 0, sizeof(attr_mask));
152d6b92ffaSHans Petter Selasky 
153d6b92ffaSHans Petter Selasky 	attr_mod.is_sm = FALSE;
154d6b92ffaSHans Petter Selasky 	attr_mask = HCA_ATTR_IS_SM;
155d6b92ffaSHans Petter Selasky 
156d6b92ffaSHans Petter Selasky 	status =
157d6b92ffaSHans Petter Selasky 	    VAPI_modify_hca_attr(p_bind->hca_hndl, p_bind->port_num, &attr_mod,
158d6b92ffaSHans Petter Selasky 				 &attr_mask);
159d6b92ffaSHans Petter Selasky 	if (status != VAPI_OK) {
160d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
161d6b92ffaSHans Petter Selasky 			"__osm_vendor_clear_sm: ERR 5021: "
162d6b92ffaSHans Petter Selasky 			"Unable set 'IS_SM' bit in port attributes (%d).\n",
163d6b92ffaSHans Petter Selasky 			status);
164d6b92ffaSHans Petter Selasky 	}
165d6b92ffaSHans Petter Selasky 
166d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
167d6b92ffaSHans Petter Selasky }
168d6b92ffaSHans Petter Selasky 
169d6b92ffaSHans Petter Selasky /**********************************************************************
170d6b92ffaSHans Petter Selasky  * ANY CONSTRUCTION OF THE osm_vendor_t OBJECT
171d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_construct(IN osm_vendor_t * const p_vend)172d6b92ffaSHans Petter Selasky void osm_vendor_construct(IN osm_vendor_t * const p_vend)
173d6b92ffaSHans Petter Selasky {
174d6b92ffaSHans Petter Selasky 	memset(p_vend, 0, sizeof(*p_vend));
175d6b92ffaSHans Petter Selasky 	cl_thread_construct(&(p_vend->smi_bind.poller));
176d6b92ffaSHans Petter Selasky 	cl_thread_construct(&(p_vend->gsi_bind.poller));
177d6b92ffaSHans Petter Selasky }
178d6b92ffaSHans Petter Selasky 
179d6b92ffaSHans Petter Selasky /**********************************************************************
180d6b92ffaSHans Petter Selasky  * DEALOCATE osm_vendor_t
181d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_destroy(IN osm_vendor_t * const p_vend)182d6b92ffaSHans Petter Selasky void osm_vendor_destroy(IN osm_vendor_t * const p_vend)
183d6b92ffaSHans Petter Selasky {
184d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
185d6b92ffaSHans Petter Selasky 	osm_transaction_mgr_destroy(p_vend);
186d6b92ffaSHans Petter Selasky 
187d6b92ffaSHans Petter Selasky 	/* Destroy the poller threads */
188d6b92ffaSHans Petter Selasky 	/* HACK: can you destroy an un-initialized thread ? */
189d6b92ffaSHans Petter Selasky 	pthread_cancel(p_vend->smi_bind.poller.osd.id);
190d6b92ffaSHans Petter Selasky 	pthread_cancel(p_vend->gsi_bind.poller.osd.id);
191d6b92ffaSHans Petter Selasky 	cl_thread_destroy(&(p_vend->smi_bind.poller));
192d6b92ffaSHans Petter Selasky 	cl_thread_destroy(&(p_vend->gsi_bind.poller));
193d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
194d6b92ffaSHans Petter Selasky }
195d6b92ffaSHans Petter Selasky 
196d6b92ffaSHans Petter Selasky /**********************************************************************
197d6b92ffaSHans Petter Selasky DEALLOCATE A POINTER TO osm_vendor_t
198d6b92ffaSHans Petter Selasky **********************************************************************/
osm_vendor_delete(IN osm_vendor_t ** const pp_vend)199d6b92ffaSHans Petter Selasky void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
200d6b92ffaSHans Petter Selasky {
201d6b92ffaSHans Petter Selasky 	CL_ASSERT(pp_vend);
202d6b92ffaSHans Petter Selasky 
203d6b92ffaSHans Petter Selasky 	osm_vendor_destroy(*pp_vend);
204d6b92ffaSHans Petter Selasky 	free(*pp_vend);
205d6b92ffaSHans Petter Selasky 	*pp_vend = NULL;
206d6b92ffaSHans Petter Selasky }
207d6b92ffaSHans Petter Selasky 
208d6b92ffaSHans Petter Selasky /**********************************************************************
209d6b92ffaSHans Petter Selasky  Initializes the vendor:
210d6b92ffaSHans Petter Selasky **********************************************************************/
211d6b92ffaSHans Petter Selasky 
212d6b92ffaSHans 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)213d6b92ffaSHans Petter Selasky osm_vendor_init(IN osm_vendor_t * const p_vend,
214d6b92ffaSHans Petter Selasky 		IN osm_log_t * const p_log, IN const uint32_t timeout)
215d6b92ffaSHans Petter Selasky {
216d6b92ffaSHans Petter Selasky 	ib_api_status_t status = IB_SUCCESS;
217d6b92ffaSHans Petter Selasky 
218d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
219d6b92ffaSHans Petter Selasky 
220d6b92ffaSHans Petter Selasky 	p_vend->p_log = p_log;
221d6b92ffaSHans Petter Selasky 	p_vend->p_transaction_mgr = NULL;
222d6b92ffaSHans Petter Selasky 	osm_transaction_mgr_init(p_vend);
223d6b92ffaSHans Petter Selasky 	p_vend->timeout = timeout;
224d6b92ffaSHans Petter Selasky 
225d6b92ffaSHans Petter Selasky 	/* we use the file handle to track the binding */
226d6b92ffaSHans Petter Selasky 	p_vend->smi_bind.ul_dev_fd = -1;
227d6b92ffaSHans Petter Selasky 	p_vend->gsi_bind.ul_dev_fd = -1;
228d6b92ffaSHans Petter Selasky 
229d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
230d6b92ffaSHans Petter Selasky 	return (status);
231d6b92ffaSHans Petter Selasky }
232d6b92ffaSHans Petter Selasky 
233d6b92ffaSHans Petter Selasky /**********************************************************************
234d6b92ffaSHans Petter Selasky  *  Create and Initialize osm_vendor_t Object
235d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_new(IN osm_log_t * const p_log,IN const uint32_t timeout)236d6b92ffaSHans Petter Selasky osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
237d6b92ffaSHans Petter Selasky 			     IN const uint32_t timeout)
238d6b92ffaSHans Petter Selasky {
239d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
240d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend;
241d6b92ffaSHans Petter Selasky 
242d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
243d6b92ffaSHans Petter Selasky 
244d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_log);
245d6b92ffaSHans Petter Selasky 
246d6b92ffaSHans Petter Selasky 	p_vend = malloc(sizeof(*p_vend));
247d6b92ffaSHans Petter Selasky 	if (p_vend != NULL) {
248d6b92ffaSHans Petter Selasky 		memset(p_vend, 0, sizeof(*p_vend));
249d6b92ffaSHans Petter Selasky 
250d6b92ffaSHans Petter Selasky 		status = osm_vendor_init(p_vend, p_log, timeout);
251d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
252d6b92ffaSHans Petter Selasky 			osm_vendor_delete(&p_vend);
253d6b92ffaSHans Petter Selasky 		}
254d6b92ffaSHans Petter Selasky 	} else {
255d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
256d6b92ffaSHans Petter Selasky 			"osm_vendor_new: ERR 5007: "
257d6b92ffaSHans Petter Selasky 			"Fail to allocate vendor object.\n");
258d6b92ffaSHans Petter Selasky 	}
259d6b92ffaSHans Petter Selasky 
260d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
261d6b92ffaSHans Petter Selasky 	return (p_vend);
262d6b92ffaSHans Petter Selasky }
263d6b92ffaSHans Petter Selasky 
264d6b92ffaSHans Petter Selasky /**********************************************************************
265d6b92ffaSHans Petter Selasky  * TS RCV Thread callback
266d6b92ffaSHans Petter Selasky  * HACK: - we need to make this support arbitrary size mads.
267d6b92ffaSHans Petter Selasky  **********************************************************************/
268d6b92ffaSHans Petter Selasky void
__osm_ts_rcv_callback(IN osm_ts_bind_info_t * p_bind,IN osm_mad_addr_t * p_mad_addr,IN uint32_t mad_size,IN void * p_mad)269d6b92ffaSHans Petter Selasky __osm_ts_rcv_callback(IN osm_ts_bind_info_t * p_bind,
270d6b92ffaSHans Petter Selasky 		      IN osm_mad_addr_t * p_mad_addr,
271d6b92ffaSHans Petter Selasky 		      IN uint32_t mad_size, IN void *p_mad)
272d6b92ffaSHans Petter Selasky {
273d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
274d6b92ffaSHans Petter Selasky 	osm_madw_t *p_req_madw = NULL;
275d6b92ffaSHans Petter Selasky 	osm_madw_t *p_madw;
276d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *p_new_vw;
277d6b92ffaSHans Petter Selasky 	ib_mad_t *p_mad_buf;
278d6b92ffaSHans Petter Selasky 	osm_log_t *const p_log = p_bind->p_vend->p_log;
279d6b92ffaSHans Petter Selasky 
280d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
281d6b92ffaSHans Petter Selasky 
282d6b92ffaSHans Petter Selasky 	/* if it is a response MAD we mustbe able to get the request */
283d6b92ffaSHans Petter Selasky 	if (ib_mad_is_response((ib_mad_t *) p_mad)) {
284d6b92ffaSHans Petter Selasky 		/* can we find a matching madw by this payload TID */
285d6b92ffaSHans Petter Selasky 		status =
286d6b92ffaSHans Petter Selasky 		    osm_transaction_mgr_get_madw_for_tid(p_bind->p_vend,
287d6b92ffaSHans Petter Selasky 							 (ib_mad_t *) p_mad,
288d6b92ffaSHans Petter Selasky 							 &p_req_madw);
289d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
290d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
291d6b92ffaSHans Petter Selasky 				"__osm_ts_rcv_callback: ERR 5008: "
292d6b92ffaSHans Petter Selasky 				"Error obtaining request madw by TID (%d).\n",
293d6b92ffaSHans Petter Selasky 				status);
294d6b92ffaSHans Petter Selasky 			p_req_madw = NULL;
295d6b92ffaSHans Petter Selasky 		}
296d6b92ffaSHans Petter Selasky 
297d6b92ffaSHans Petter Selasky 		if (p_req_madw == NULL) {
298d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
299d6b92ffaSHans Petter Selasky 				"__osm_ts_rcv_callback: ERR 5009:  "
300d6b92ffaSHans Petter Selasky 				"Fail to obtain request madw for receined MAD. Aborting CB.\n");
301d6b92ffaSHans Petter Selasky 			goto Exit;
302d6b92ffaSHans Petter Selasky 		}
303d6b92ffaSHans Petter Selasky 	}
304d6b92ffaSHans Petter Selasky 
305d6b92ffaSHans Petter Selasky 	/* do we have a request ??? */
306d6b92ffaSHans Petter Selasky 	if (p_req_madw == NULL) {
307d6b92ffaSHans Petter Selasky 
308d6b92ffaSHans Petter Selasky 		/* if not - get new osm_madw and arrange it. */
309d6b92ffaSHans Petter Selasky 		/* create the new madw in the pool */
310d6b92ffaSHans Petter Selasky 		p_madw = osm_mad_pool_get(p_bind->p_osm_pool,
311d6b92ffaSHans Petter Selasky 					  (osm_bind_handle_t) p_bind,
312d6b92ffaSHans Petter Selasky 					  mad_size, p_mad_addr);
313d6b92ffaSHans Petter Selasky 		if (p_madw == NULL) {
314d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
315d6b92ffaSHans Petter Selasky 				"__osm_ts_rcv_callback: ERR 5010: "
316d6b92ffaSHans Petter Selasky 				"Error request for a new madw.\n");
317d6b92ffaSHans Petter Selasky 			goto Exit;
318d6b92ffaSHans Petter Selasky 		}
319d6b92ffaSHans Petter Selasky 		/* HACK: we cust to avoid the const ??? */
320d6b92ffaSHans Petter Selasky 		p_mad_buf = (void *)p_madw->p_mad;
321d6b92ffaSHans Petter Selasky 	} else {
322d6b92ffaSHans Petter Selasky 		/* we have the madw defined during the send and stored in the vend_wrap */
323d6b92ffaSHans Petter Selasky 		/* we need to make sure the wrapper is correctly init there */
324d6b92ffaSHans Petter Selasky 		CL_ASSERT(p_req_madw->vend_wrap.p_resp_madw != 0);
325d6b92ffaSHans Petter Selasky 		p_madw = p_req_madw->vend_wrap.p_resp_madw;
326d6b92ffaSHans Petter Selasky 
327d6b92ffaSHans Petter Selasky 		CL_ASSERT(p_madw->h_bind);
328d6b92ffaSHans Petter Selasky 		p_mad_buf =
329d6b92ffaSHans Petter Selasky 		    osm_vendor_get(p_madw->h_bind, mad_size,
330d6b92ffaSHans Petter Selasky 				   &p_madw->vend_wrap);
331d6b92ffaSHans Petter Selasky 
332d6b92ffaSHans Petter Selasky 		if (p_mad_buf == NULL) {
333d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
334d6b92ffaSHans Petter Selasky 				"__osm_ts_rcv_callback: ERR 5011: "
335d6b92ffaSHans Petter Selasky 				"Unable to acquire wire MAD.\n");
336d6b92ffaSHans Petter Selasky 
337d6b92ffaSHans Petter Selasky 			goto Exit;
338d6b92ffaSHans Petter Selasky 		}
339d6b92ffaSHans Petter Selasky 
340d6b92ffaSHans Petter Selasky 		/*
341d6b92ffaSHans Petter Selasky 		   Finally, attach the wire MAD to this wrapper.
342d6b92ffaSHans Petter Selasky 		 */
343d6b92ffaSHans Petter Selasky 		osm_madw_set_mad(p_madw, p_mad_buf);
344d6b92ffaSHans Petter Selasky 	}
345d6b92ffaSHans Petter Selasky 
346d6b92ffaSHans Petter Selasky 	/* init some fields of the vendor wrapper */
347d6b92ffaSHans Petter Selasky 	p_new_vw = osm_madw_get_vend_ptr(p_madw);
348d6b92ffaSHans Petter Selasky 	p_new_vw->h_bind = p_bind;
349d6b92ffaSHans Petter Selasky 	p_new_vw->size = mad_size;
350d6b92ffaSHans Petter Selasky 	p_new_vw->p_resp_madw = NULL;
351d6b92ffaSHans Petter Selasky 	p_new_vw->p_mad_buf = p_mad_buf;
352d6b92ffaSHans Petter Selasky 
353d6b92ffaSHans Petter Selasky 	memcpy(p_new_vw->p_mad_buf, p_mad, mad_size);
354d6b92ffaSHans Petter Selasky 
355d6b92ffaSHans Petter Selasky 	/* attach the buffer to the wrapper */
356d6b92ffaSHans Petter Selasky 	p_madw->p_mad = p_mad_buf;
357d6b92ffaSHans Petter Selasky 
358d6b92ffaSHans Petter Selasky 	/* we can also make sure we marked the size and bind on the returned madw */
359d6b92ffaSHans Petter Selasky 	p_madw->h_bind = p_new_vw->h_bind;
360d6b92ffaSHans Petter Selasky 
361d6b92ffaSHans Petter Selasky 	/* call the CB */
362d6b92ffaSHans Petter Selasky 	(*(osm_vend_mad_recv_callback_t) p_bind->rcv_callback)
363d6b92ffaSHans Petter Selasky 	    (p_madw, p_bind->client_context, p_req_madw);
364d6b92ffaSHans Petter Selasky 
365d6b92ffaSHans Petter Selasky Exit:
366d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
367d6b92ffaSHans Petter Selasky }
368d6b92ffaSHans Petter Selasky 
369d6b92ffaSHans Petter Selasky /**********************************************************************
370d6b92ffaSHans Petter Selasky  * TS Send callback : invoked after each send
371d6b92ffaSHans Petter Selasky  *
372d6b92ffaSHans Petter Selasky  **********************************************************************/
373d6b92ffaSHans Petter Selasky void
__osm_ts_send_callback(IN osm_ts_bind_info_t * bind_info_p,IN boolean_t is_resp,IN osm_madw_t * madw_p,IN IB_comp_status_t status)374d6b92ffaSHans Petter Selasky __osm_ts_send_callback(IN osm_ts_bind_info_t * bind_info_p,
375d6b92ffaSHans Petter Selasky 		       IN boolean_t is_resp,
376d6b92ffaSHans Petter Selasky 		       IN osm_madw_t * madw_p, IN IB_comp_status_t status)
377d6b92ffaSHans Petter Selasky {
378d6b92ffaSHans Petter Selasky 	osm_log_t *const p_log = bind_info_p->p_vend->p_log;
379d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *p_vw;
380d6b92ffaSHans Petter Selasky 
381d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
382d6b92ffaSHans Petter Selasky 
383d6b92ffaSHans Petter Selasky 	osm_log(p_log, OSM_LOG_DEBUG,
384d6b92ffaSHans Petter Selasky 		"__osm_ts_send_callback: INFO 1008: "
385d6b92ffaSHans Petter Selasky 		"Handling Send of MADW:%p Is Resp:%d.\n", madw_p, is_resp);
386d6b92ffaSHans Petter Selasky 
387d6b92ffaSHans Petter Selasky 	/* we need to handle requests and responses differently */
388d6b92ffaSHans Petter Selasky 	if (is_resp) {
389d6b92ffaSHans Petter Selasky 		if (status != IB_COMP_SUCCESS) {
390d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
391d6b92ffaSHans Petter Selasky 				"__osm_ts_send_callback: ERR 5012: "
392d6b92ffaSHans Petter Selasky 				"Error Sending Response MADW:%p.\n", madw_p);
393d6b92ffaSHans Petter Selasky 		} else {
394d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_DEBUG,
395d6b92ffaSHans Petter Selasky 				"__osm_ts_send_callback: DBG 1008: "
396d6b92ffaSHans Petter Selasky 				"Completed Sending Response MADW:%p.\n",
397d6b92ffaSHans Petter Selasky 				madw_p);
398d6b92ffaSHans Petter Selasky 		}
399d6b92ffaSHans Petter Selasky 
400d6b92ffaSHans Petter Selasky 		/* if we are a response - we need to clean it up */
401d6b92ffaSHans Petter Selasky 		osm_mad_pool_put(bind_info_p->p_osm_pool, madw_p);
402d6b92ffaSHans Petter Selasky 	} else {
403d6b92ffaSHans Petter Selasky 
404d6b92ffaSHans Petter Selasky 		/* this call back is invoked on completion of send - error or not */
405d6b92ffaSHans Petter Selasky 		if (status != IB_COMP_SUCCESS) {
406d6b92ffaSHans Petter Selasky 
407d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
408d6b92ffaSHans Petter Selasky 				"__osm_ts_send_callback: ERR 5013: "
409d6b92ffaSHans Petter Selasky 				"Received an Error from IB_MGT Send (%d).\n",
410d6b92ffaSHans Petter Selasky 				status);
411d6b92ffaSHans Petter Selasky 
412d6b92ffaSHans Petter Selasky 			p_vw = osm_madw_get_vend_ptr(madw_p);
413d6b92ffaSHans Petter Selasky 			CL_ASSERT(p_vw);
414d6b92ffaSHans Petter Selasky 
415d6b92ffaSHans Petter Selasky 			/*
416d6b92ffaSHans Petter Selasky 			   Return any wrappers to the pool that may have been
417d6b92ffaSHans Petter Selasky 			   pre-emptively allocated to handle a receive.
418d6b92ffaSHans Petter Selasky 			 */
419d6b92ffaSHans Petter Selasky 			if (p_vw->p_resp_madw) {
420d6b92ffaSHans Petter Selasky 				osm_mad_pool_put(bind_info_p->p_osm_pool,
421d6b92ffaSHans Petter Selasky 						 p_vw->p_resp_madw);
422d6b92ffaSHans Petter Selasky 				p_vw->p_resp_madw = NULL;
423d6b92ffaSHans Petter Selasky 			}
424d6b92ffaSHans Petter Selasky 
425d6b92ffaSHans Petter Selasky 			/* invoke the CB */
426d6b92ffaSHans Petter Selasky 			(*(osm_vend_mad_send_err_callback_t) bind_info_p->
427d6b92ffaSHans Petter Selasky 			 send_err_callback)
428d6b92ffaSHans Petter Selasky 			    (bind_info_p->client_context, madw_p);
429d6b92ffaSHans Petter Selasky 		} else {
430d6b92ffaSHans Petter Selasky 			/* successful request send - do nothing - the response will need the
431d6b92ffaSHans Petter Selasky 			   out mad */
432d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_DEBUG,
433d6b92ffaSHans Petter Selasky 				"__osm_ts_send_callback: DBG 1008: "
434d6b92ffaSHans Petter Selasky 				"Completed Sending Request MADW:%p.\n", madw_p);
435d6b92ffaSHans Petter Selasky 		}
436d6b92ffaSHans Petter Selasky 	}
437d6b92ffaSHans Petter Selasky 
438d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
439d6b92ffaSHans Petter Selasky }
440d6b92ffaSHans Petter Selasky 
441d6b92ffaSHans Petter Selasky /**********************************************************************
442d6b92ffaSHans Petter Selasky  * Poller thread:
443d6b92ffaSHans Petter Selasky  * Always receive 256byte mads from the devcie file
444d6b92ffaSHans Petter Selasky  **********************************************************************/
__osm_vendor_ts_poller(IN void * p_ptr)445d6b92ffaSHans Petter Selasky void __osm_vendor_ts_poller(IN void *p_ptr)
446d6b92ffaSHans Petter Selasky {
447d6b92ffaSHans Petter Selasky 	int ts_ret_code;
448d6b92ffaSHans Petter Selasky 	struct ib_mad mad;
449d6b92ffaSHans Petter Selasky 	osm_mad_addr_t mad_addr;
450d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *const p_bind = (osm_ts_bind_info_t *) p_ptr;
451d6b92ffaSHans Petter Selasky 
452d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_bind->p_vend->p_log);
453d6b92ffaSHans Petter Selasky 	/* we set the type of cancelation for this thread */
454d6b92ffaSHans Petter Selasky 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
455d6b92ffaSHans Petter Selasky 
456d6b92ffaSHans Petter Selasky 	while (1) {
457d6b92ffaSHans Petter Selasky 		/* we read one mad at a time and pass it to the read callback function */
458d6b92ffaSHans Petter Selasky 		ts_ret_code = read(p_bind->ul_dev_fd, &mad, sizeof(mad));
459d6b92ffaSHans Petter Selasky 		if (ts_ret_code != sizeof(mad)) {
460d6b92ffaSHans Petter Selasky 			osm_log(p_bind->p_vend->p_log, OSM_LOG_ERROR,
461d6b92ffaSHans Petter Selasky 				"__osm_vendor_ts_poller: ERR 5003: "
462d6b92ffaSHans Petter Selasky 				"error with read, bytes = %d, errno = %d\n",
463d6b92ffaSHans Petter Selasky 				ts_ret_code, errno);
464d6b92ffaSHans Petter Selasky 		} else {
465d6b92ffaSHans Petter Selasky 			osm_log(p_bind->p_vend->p_log, OSM_LOG_DEBUG,
466d6b92ffaSHans Petter Selasky 				"__osm_vendor_ts_poller: "
467d6b92ffaSHans Petter Selasky 				"MAD QPN:%d SLID:0x%04x class:0x%02x "
468d6b92ffaSHans Petter Selasky 				"__osm_vendor_ts_poller:0x%02x attr:0x%04x status:0x%04x "
469d6b92ffaSHans Petter Selasky 				"__osm_vendor_ts_poller:0x%016" PRIx64 "\n",
470d6b92ffaSHans Petter Selasky 				cl_ntoh32(mad.dqpn),
471d6b92ffaSHans Petter Selasky 				cl_ntoh16(mad.slid),
472d6b92ffaSHans Petter Selasky 				mad.mgmt_class,
473d6b92ffaSHans Petter Selasky 				mad.r_method,
474d6b92ffaSHans Petter Selasky 				cl_ntoh16(mad.attribute_id),
475d6b92ffaSHans Petter Selasky 				cl_ntoh16(mad.status),
476d6b92ffaSHans Petter Selasky 				cl_ntoh64(mad.transaction_id));
477d6b92ffaSHans Petter Selasky 
478d6b92ffaSHans Petter Selasky 			/* first arrange an address */
479d6b92ffaSHans Petter Selasky 			__osm_ts_conv_mad_rcv_desc_to_osm_addr(p_bind->p_vend,
480d6b92ffaSHans Petter Selasky 							       &mad,
481d6b92ffaSHans Petter Selasky 							       (((ib_mad_t *) &
482d6b92ffaSHans Petter Selasky 								 mad)->
483d6b92ffaSHans Petter Selasky 								mgmt_class ==
484d6b92ffaSHans Petter Selasky 								IB_MCLASS_SUBN_LID)
485d6b92ffaSHans Petter Selasky 							       ||
486d6b92ffaSHans Petter Selasky 							       (((ib_mad_t *) &
487d6b92ffaSHans Petter Selasky 								 mad)->
488d6b92ffaSHans Petter Selasky 								mgmt_class ==
489d6b92ffaSHans Petter Selasky 								IB_MCLASS_SUBN_DIR),
490d6b92ffaSHans Petter Selasky 							       &mad_addr);
491d6b92ffaSHans Petter Selasky 
492d6b92ffaSHans Petter Selasky 			/* call the receiver callback */
493d6b92ffaSHans Petter Selasky 			/* HACK: this should be replaced with a call to the RMPP Assembly ... */
494d6b92ffaSHans Petter Selasky 			__osm_ts_rcv_callback(p_bind, &mad_addr, 256, &mad);
495d6b92ffaSHans Petter Selasky 		}
496d6b92ffaSHans Petter Selasky 	}
497d6b92ffaSHans Petter Selasky 
498d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_bind->p_vend->p_log);
499d6b92ffaSHans Petter Selasky }
500d6b92ffaSHans Petter Selasky 
501d6b92ffaSHans Petter Selasky /**********************************************************************
502d6b92ffaSHans Petter Selasky  * BINDs a callback (rcv and send error) for a given class and method
503d6b92ffaSHans Petter Selasky  * defined by the given:  osm_bind_info_t
504d6b92ffaSHans Petter Selasky  **********************************************************************/
505d6b92ffaSHans 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)506d6b92ffaSHans Petter Selasky osm_vendor_bind(IN osm_vendor_t * const p_vend,
507d6b92ffaSHans Petter Selasky 		IN osm_bind_info_t * const p_user_bind,
508d6b92ffaSHans Petter Selasky 		IN osm_mad_pool_t * const p_mad_pool,
509d6b92ffaSHans Petter Selasky 		IN osm_vend_mad_recv_callback_t mad_recv_callback,
510d6b92ffaSHans Petter Selasky 		IN osm_vend_mad_send_err_callback_t send_err_callback,
511d6b92ffaSHans Petter Selasky 		IN void *context)
512d6b92ffaSHans Petter Selasky {
513d6b92ffaSHans Petter Selasky 	ib_net64_t port_guid;
514d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = NULL;
515d6b92ffaSHans Petter Selasky 	VAPI_hca_hndl_t hca_hndl;
516d6b92ffaSHans Petter Selasky 	VAPI_hca_id_t hca_id;
517d6b92ffaSHans Petter Selasky 	uint32_t port_num;
518d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
519d6b92ffaSHans Petter Selasky 	int device_fd;
520d6b92ffaSHans Petter Selasky 	char device_file[16];
521d6b92ffaSHans Petter Selasky 	osm_ts_user_mad_filter filter;
522d6b92ffaSHans Petter Selasky 	int ts_ioctl_ret;
523d6b92ffaSHans Petter Selasky 	int qpn;
524d6b92ffaSHans Petter Selasky 
525d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
526d6b92ffaSHans Petter Selasky 
527d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_mad_pool);
528d6b92ffaSHans Petter Selasky 
529d6b92ffaSHans Petter Selasky 	port_guid = p_user_bind->port_guid;
530d6b92ffaSHans Petter Selasky 
531d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_INFO,
532d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: "
533d6b92ffaSHans Petter Selasky 		"Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid));
534d6b92ffaSHans Petter Selasky 
535d6b92ffaSHans Petter Selasky 	switch (p_user_bind->mad_class) {
536d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_LID:
537d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_DIR:
538d6b92ffaSHans Petter Selasky 		p_bind = &(p_vend->smi_bind);
539d6b92ffaSHans Petter Selasky 		qpn = 0;
540d6b92ffaSHans Petter Selasky 		break;
541d6b92ffaSHans Petter Selasky 
542d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_ADM:
543d6b92ffaSHans Petter Selasky 	default:
544d6b92ffaSHans Petter Selasky 		p_bind = &(p_vend->gsi_bind);
545d6b92ffaSHans Petter Selasky 		qpn = 1;
546d6b92ffaSHans Petter Selasky 		break;
547d6b92ffaSHans Petter Selasky 	}
548d6b92ffaSHans Petter Selasky 
549d6b92ffaSHans Petter Selasky 	/* Make sure we did not previously opened the file */
550d6b92ffaSHans Petter Selasky 	if (p_bind->ul_dev_fd >= 0) {
551d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
552d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 5004: "
553d6b92ffaSHans Petter Selasky 			"Already binded to port %u\n", p_bind->port_num);
554d6b92ffaSHans Petter Selasky 		goto Exit;
555d6b92ffaSHans Petter Selasky 	}
556d6b92ffaSHans Petter Selasky 
557d6b92ffaSHans Petter Selasky 	/*
558d6b92ffaSHans Petter Selasky 	   We need to figure out what is the TS file name to attach to.
559d6b92ffaSHans Petter Selasky 	   I guess it is following the index of the port in the table of
560d6b92ffaSHans Petter Selasky 	   ports.
561d6b92ffaSHans Petter Selasky 	 */
562d6b92ffaSHans Petter Selasky 
563d6b92ffaSHans Petter Selasky 	/* obtain the hca name and port num from the guid */
564d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
565d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: "
566d6b92ffaSHans Petter Selasky 		"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
567d6b92ffaSHans Petter Selasky 		cl_ntoh64(port_guid));
568d6b92ffaSHans Petter Selasky 	status =
569d6b92ffaSHans Petter Selasky 	    osm_vendor_get_guid_ca_and_port(p_vend, port_guid, &hca_hndl,
570d6b92ffaSHans Petter Selasky 					    &hca_id, &port_num);
571d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS) {
572d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
573d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 5005: "
574d6b92ffaSHans Petter Selasky 			"Fail to find port number of port guid:0x%016" PRIx64
575d6b92ffaSHans Petter Selasky 			"\n", port_guid);
576d6b92ffaSHans Petter Selasky 		goto Exit;
577d6b92ffaSHans Petter Selasky 	}
578d6b92ffaSHans Petter Selasky 
579d6b92ffaSHans Petter Selasky 	/* the file name is just /dev/ts_ua0: */
580d6b92ffaSHans Petter Selasky 	strcpy(device_file, "/dev/ts_ua0");
581d6b92ffaSHans Petter Selasky 
582d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_ERROR,
583d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: " "Opening TS UL dev file:%s\n", device_file);
584d6b92ffaSHans Petter Selasky 
585d6b92ffaSHans Petter Selasky 	/* Open the file ... */
586d6b92ffaSHans Petter Selasky 	device_fd = open(device_file, O_RDWR);
587d6b92ffaSHans Petter Selasky 	if (device_fd < 0) {
588d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
589d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 5006: "
590d6b92ffaSHans Petter Selasky 			"Fail to open TS UL dev file:%s\n", device_file);
591d6b92ffaSHans Petter Selasky 		goto Exit;
592d6b92ffaSHans Petter Selasky 	}
593d6b92ffaSHans Petter Selasky 
594d6b92ffaSHans Petter Selasky 	/* track this bind request info */
595d6b92ffaSHans Petter Selasky 	p_bind->ul_dev_fd = device_fd;
596d6b92ffaSHans Petter Selasky 	p_bind->port_num = port_num;
597d6b92ffaSHans Petter Selasky 	p_bind->p_vend = p_vend;
598d6b92ffaSHans Petter Selasky 	p_bind->client_context = context;
599d6b92ffaSHans Petter Selasky 	p_bind->rcv_callback = mad_recv_callback;
600d6b92ffaSHans Petter Selasky 	p_bind->send_err_callback = send_err_callback;
601d6b92ffaSHans Petter Selasky 	p_bind->p_osm_pool = p_mad_pool;
602d6b92ffaSHans Petter Selasky 	p_bind->hca_hndl = hca_hndl;
603d6b92ffaSHans Petter Selasky 
604d6b92ffaSHans Petter Selasky 	/*
605d6b92ffaSHans Petter Selasky 	 * Create the MAD filter on this file handle.
606d6b92ffaSHans Petter Selasky 	 */
607d6b92ffaSHans Petter Selasky 	filter.port = port_num;
608d6b92ffaSHans Petter Selasky 
609d6b92ffaSHans Petter Selasky 	filter.qpn = qpn;
610d6b92ffaSHans Petter Selasky 	filter.mgmt_class = p_user_bind->mad_class;
611d6b92ffaSHans Petter Selasky 	filter.direction = TS_IB_MAD_DIRECTION_IN;
612d6b92ffaSHans Petter Selasky 	filter.mask =
613d6b92ffaSHans Petter Selasky 	    TS_IB_MAD_FILTER_DIRECTION |
614d6b92ffaSHans Petter Selasky 	    TS_IB_MAD_FILTER_PORT |
615d6b92ffaSHans Petter Selasky 	    TS_IB_MAD_FILTER_QPN | TS_IB_MAD_FILTER_MGMT_CLASS;
616d6b92ffaSHans Petter Selasky 
617d6b92ffaSHans Petter Selasky 	ts_ioctl_ret = ioctl(device_fd, TS_IB_IOCSMADFILTADD, &filter);
618d6b92ffaSHans Petter Selasky 	if (ts_ioctl_ret < 0) {
619d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
620d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 5014: "
621d6b92ffaSHans Petter Selasky 			"Fail to register MAD filter with err:%u\n",
622d6b92ffaSHans Petter Selasky 			ts_ioctl_ret);
623d6b92ffaSHans Petter Selasky 		goto Exit;
624d6b92ffaSHans Petter Selasky 	}
625d6b92ffaSHans Petter Selasky 
626d6b92ffaSHans Petter Selasky 	/* Initialize the listener thread for this port */
627d6b92ffaSHans Petter Selasky 	status = cl_thread_init(&p_bind->poller,
628d6b92ffaSHans Petter Selasky 				__osm_vendor_ts_poller, p_bind,
629d6b92ffaSHans Petter Selasky 				"osm ts poller");
630d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS)
631d6b92ffaSHans Petter Selasky 		goto Exit;
632d6b92ffaSHans Petter Selasky 
633d6b92ffaSHans Petter Selasky Exit:
634d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
635d6b92ffaSHans Petter Selasky 	return ((osm_bind_handle_t) p_bind);
636d6b92ffaSHans Petter Selasky }
637d6b92ffaSHans Petter Selasky 
638d6b92ffaSHans Petter Selasky /**********************************************************************
639d6b92ffaSHans Petter Selasky Get a mad from the lower level.
640d6b92ffaSHans Petter Selasky The osm_vend_wrap_t is a wrapper used to connect the mad to the response.
641d6b92ffaSHans 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)642d6b92ffaSHans Petter Selasky ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
643d6b92ffaSHans Petter Selasky 			 IN const uint32_t mad_size,
644d6b92ffaSHans Petter Selasky 			 IN osm_vend_wrap_t * const p_vw)
645d6b92ffaSHans Petter Selasky {
646d6b92ffaSHans Petter Selasky 	ib_mad_t *p_mad;
647d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
648d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
649d6b92ffaSHans Petter Selasky 
650d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
651d6b92ffaSHans Petter Selasky 
652d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw);
653d6b92ffaSHans Petter Selasky 
654d6b92ffaSHans Petter Selasky 	p_vw->size = mad_size;
655d6b92ffaSHans Petter Selasky 
656d6b92ffaSHans Petter Selasky 	/* allocate it */
657d6b92ffaSHans Petter Selasky 	p_mad = (ib_mad_t *) malloc(p_vw->size);
658d6b92ffaSHans Petter Selasky 	if (p_mad == NULL) {
659d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
660d6b92ffaSHans Petter Selasky 			"osm_vendor_get: ERR 5022: "
661d6b92ffaSHans Petter Selasky 			"Error Obtaining MAD buffer.\n");
662d6b92ffaSHans Petter Selasky 		goto Exit;
663d6b92ffaSHans Petter Selasky 	}
664d6b92ffaSHans Petter Selasky 
665d6b92ffaSHans Petter Selasky 	memset(p_mad, 0, p_vw->size);
666d6b92ffaSHans Petter Selasky 
667d6b92ffaSHans Petter Selasky 	/* track locally */
668d6b92ffaSHans Petter Selasky 	p_vw->p_mad_buf = p_mad;
669d6b92ffaSHans Petter Selasky 	p_vw->h_bind = h_bind;
670d6b92ffaSHans Petter Selasky 	p_vw->p_resp_madw = NULL;
671d6b92ffaSHans Petter Selasky 
672d6b92ffaSHans Petter Selasky 	if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
673d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
674d6b92ffaSHans Petter Selasky 			"osm_vendor_get: "
675d6b92ffaSHans Petter Selasky 			"Acquired MAD %p, size = %u.\n", p_mad, p_vw->size);
676d6b92ffaSHans Petter Selasky 	}
677d6b92ffaSHans Petter Selasky 
678d6b92ffaSHans Petter Selasky Exit:
679d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
680d6b92ffaSHans Petter Selasky 	return (p_mad);
681d6b92ffaSHans Petter Selasky }
682d6b92ffaSHans Petter Selasky 
683d6b92ffaSHans Petter Selasky /**********************************************************************
684d6b92ffaSHans Petter Selasky  * Return a MAD by providing it's wrapper object.
685d6b92ffaSHans Petter Selasky  **********************************************************************/
686d6b92ffaSHans Petter Selasky void
osm_vendor_put(IN osm_bind_handle_t h_bind,IN osm_vend_wrap_t * const p_vw)687d6b92ffaSHans Petter Selasky osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw)
688d6b92ffaSHans Petter Selasky {
689d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
690d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
691d6b92ffaSHans Petter Selasky 	osm_madw_t *p_madw;
692d6b92ffaSHans Petter Selasky 
693d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
694d6b92ffaSHans Petter Selasky 
695d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw);
696d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw->p_mad_buf);
697d6b92ffaSHans Petter Selasky 
698d6b92ffaSHans Petter Selasky 	if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
699d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
700d6b92ffaSHans Petter Selasky 			"osm_vendor_put: " "Retiring MAD %p.\n",
701d6b92ffaSHans Petter Selasky 			p_vw->p_mad_buf);
702d6b92ffaSHans Petter Selasky 	}
703d6b92ffaSHans Petter Selasky 
704d6b92ffaSHans Petter Selasky 	/*
705d6b92ffaSHans Petter Selasky 	 * We moved the removal of the transaction to immediatly after
706d6b92ffaSHans Petter Selasky 	 * it was looked up.
707d6b92ffaSHans Petter Selasky 	 */
708d6b92ffaSHans Petter Selasky 
709d6b92ffaSHans Petter Selasky 	/* free the mad but the wrapper is part of the madw object */
710d6b92ffaSHans Petter Selasky 	free(p_vw->p_mad_buf);
711d6b92ffaSHans Petter Selasky 	p_vw->p_mad_buf = NULL;
712d6b92ffaSHans Petter Selasky 	p_madw = PARENT_STRUCT(p_vw, osm_madw_t, vend_wrap);
713d6b92ffaSHans Petter Selasky 	p_madw->p_mad = NULL;
714d6b92ffaSHans Petter Selasky 
715d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
716d6b92ffaSHans Petter Selasky }
717d6b92ffaSHans Petter Selasky 
718d6b92ffaSHans Petter Selasky /**********************************************************************
719d6b92ffaSHans Petter Selasky Actually Send a MAD
720d6b92ffaSHans Petter Selasky 
721d6b92ffaSHans Petter Selasky MADs are buffers of type: struct ib_mad - so they are limited by size.
722d6b92ffaSHans Petter Selasky This is for internal use by osm_vendor_send and the transaction mgr
723d6b92ffaSHans Petter Selasky retry too.
724d6b92ffaSHans Petter Selasky **********************************************************************/
725d6b92ffaSHans Petter Selasky ib_api_status_t
osm_ts_send_mad(IN osm_ts_bind_info_t * p_bind,IN osm_madw_t * const p_madw)726d6b92ffaSHans Petter Selasky osm_ts_send_mad(IN osm_ts_bind_info_t * p_bind, IN osm_madw_t * const p_madw)
727d6b92ffaSHans Petter Selasky {
728d6b92ffaSHans Petter Selasky 	osm_vendor_t *const p_vend = p_bind->p_vend;
729d6b92ffaSHans Petter Selasky 	osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
730d6b92ffaSHans Petter Selasky 	ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw);
731d6b92ffaSHans Petter Selasky 	struct ib_mad ts_mad;
732d6b92ffaSHans Petter Selasky 	int ret;
733d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
734d6b92ffaSHans Petter Selasky 
735d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
736d6b92ffaSHans Petter Selasky 
737d6b92ffaSHans Petter Selasky 	/*
738d6b92ffaSHans Petter Selasky 	 * Copy the MAD over to the sent mad
739d6b92ffaSHans Petter Selasky 	 */
740d6b92ffaSHans Petter Selasky 	memcpy(&ts_mad, p_mad, 256);
741d6b92ffaSHans Petter Selasky 
742d6b92ffaSHans Petter Selasky 	/*
743d6b92ffaSHans Petter Selasky 	 * For all sends other than directed route SM MADs,
744d6b92ffaSHans Petter Selasky 	 * acquire an address vector for the destination.
745d6b92ffaSHans Petter Selasky 	 */
746d6b92ffaSHans Petter Selasky 	if (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) {
747d6b92ffaSHans Petter Selasky 		__osm_ts_conv_osm_addr_to_ts_addr(p_mad_addr,
748d6b92ffaSHans Petter Selasky 						  p_mad->mgmt_class ==
749d6b92ffaSHans Petter Selasky 						  IB_MCLASS_SUBN_LID, &ts_mad);
750d6b92ffaSHans Petter Selasky 	} else {
751d6b92ffaSHans Petter Selasky 		/* is a directed route - we need to construct a permissive address */
752d6b92ffaSHans Petter Selasky 		/* we do not need port number since it is part of the mad_hndl */
753d6b92ffaSHans Petter Selasky 		ts_mad.dlid = IB_LID_PERMISSIVE;
754d6b92ffaSHans Petter Selasky 		ts_mad.slid = IB_LID_PERMISSIVE;
755d6b92ffaSHans Petter Selasky 	}
756d6b92ffaSHans Petter Selasky 	if ((p_mad->mgmt_class == IB_MCLASS_SUBN_DIR) ||
757d6b92ffaSHans Petter Selasky 	    (p_mad->mgmt_class == IB_MCLASS_SUBN_LID)) {
758d6b92ffaSHans Petter Selasky 		ts_mad.sqpn = 0;
759d6b92ffaSHans Petter Selasky 		ts_mad.dqpn = 0;
760d6b92ffaSHans Petter Selasky 	} else {
761d6b92ffaSHans Petter Selasky 		ts_mad.sqpn = 1;
762d6b92ffaSHans Petter Selasky 		ts_mad.dqpn = 1;
763d6b92ffaSHans Petter Selasky 	}
764d6b92ffaSHans Petter Selasky 	ts_mad.port = p_bind->port_num;
765d6b92ffaSHans Petter Selasky 
766d6b92ffaSHans Petter Selasky 	/* send it */
767d6b92ffaSHans Petter Selasky 	ret = write(p_bind->ul_dev_fd, &ts_mad, sizeof(ts_mad));
768d6b92ffaSHans Petter Selasky 
769d6b92ffaSHans Petter Selasky 	if (ret != sizeof(ts_mad)) {
770d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
771d6b92ffaSHans Petter Selasky 			"osm_ts_send_mad: ERR 5026: "
772d6b92ffaSHans Petter Selasky 			"Error sending mad (%d).\n", ret);
773d6b92ffaSHans Petter Selasky 		status = IB_ERROR;
774d6b92ffaSHans Petter Selasky 		goto Exit;
775d6b92ffaSHans Petter Selasky 	}
776d6b92ffaSHans Petter Selasky 
777d6b92ffaSHans Petter Selasky 	status = IB_SUCCESS;
778d6b92ffaSHans Petter Selasky 
779d6b92ffaSHans Petter Selasky Exit:
780d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
781d6b92ffaSHans Petter Selasky 	return (status);
782d6b92ffaSHans Petter Selasky }
783d6b92ffaSHans Petter Selasky 
784d6b92ffaSHans Petter Selasky /**********************************************************************
785d6b92ffaSHans Petter Selasky Send a MAD through.
786d6b92ffaSHans Petter Selasky 
787d6b92ffaSHans Petter Selasky What is unclear to me is the need for the setting of all the MAD Wrapper
788d6b92ffaSHans Petter Selasky fields. Seems like the OSM uses these values during it's processing...
789d6b92ffaSHans Petter Selasky **********************************************************************/
790d6b92ffaSHans 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)791d6b92ffaSHans Petter Selasky osm_vendor_send(IN osm_bind_handle_t h_bind,
792d6b92ffaSHans Petter Selasky 		IN osm_madw_t * const p_madw, IN boolean_t const resp_expected)
793d6b92ffaSHans Petter Selasky {
794d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
795d6b92ffaSHans Petter Selasky 	osm_vendor_t *const p_vend = p_bind->p_vend;
796d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
797d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
798d6b92ffaSHans Petter Selasky 
799d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
800d6b92ffaSHans Petter Selasky 
801d6b92ffaSHans Petter Selasky 	/*
802d6b92ffaSHans Petter Selasky 	 * If a response is expected to this MAD, then preallocate
803d6b92ffaSHans Petter Selasky 	 * a mad wrapper to contain the wire MAD received in the
804d6b92ffaSHans Petter Selasky 	 * response.  Allocating a wrapper here allows for easier
805d6b92ffaSHans Petter Selasky 	 * failure paths than after we already received the wire mad.
806d6b92ffaSHans Petter Selasky 	 */
807d6b92ffaSHans Petter Selasky 	if (resp_expected == TRUE) {
808d6b92ffaSHans Petter Selasky 		/* we track it in the vendor wrapper */
809d6b92ffaSHans Petter Selasky 		p_vw->p_resp_madw =
810d6b92ffaSHans Petter Selasky 		    osm_mad_pool_get_wrapper_raw(p_bind->p_osm_pool);
811d6b92ffaSHans Petter Selasky 		if (p_vw->p_resp_madw == NULL) {
812d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_ERROR,
813d6b92ffaSHans Petter Selasky 				"osm_vendor_send: ERR 5024: "
814d6b92ffaSHans Petter Selasky 				"Unable to allocate MAD wrapper.\n");
815d6b92ffaSHans Petter Selasky 			status = IB_INSUFFICIENT_RESOURCES;
816d6b92ffaSHans Petter Selasky 			goto Exit;
817d6b92ffaSHans Petter Selasky 		}
818d6b92ffaSHans Petter Selasky 
819d6b92ffaSHans Petter Selasky 		/* put some minimal info on that wrapper */
820d6b92ffaSHans Petter Selasky 		((osm_madw_t *) (p_vw->p_resp_madw))->h_bind = h_bind;
821d6b92ffaSHans Petter Selasky 
822d6b92ffaSHans Petter Selasky 		/* we also want to track it in the TID based map */
823d6b92ffaSHans Petter Selasky 		status = osm_transaction_mgr_insert_madw((osm_bind_handle_t *)
824d6b92ffaSHans Petter Selasky 							 p_bind, p_madw);
825d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
826d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_ERROR,
827d6b92ffaSHans Petter Selasky 				"osm_vendor_send: ERR 5025: "
828d6b92ffaSHans Petter Selasky 				"Error inserting request madw by TID (%d).\n",
829d6b92ffaSHans Petter Selasky 				status);
830d6b92ffaSHans Petter Selasky 		}
831d6b92ffaSHans Petter Selasky 	} else
832d6b92ffaSHans Petter Selasky 		p_vw->p_resp_madw = NULL;
833d6b92ffaSHans Petter Selasky 
834d6b92ffaSHans Petter Selasky 	/* do the actual send */
835d6b92ffaSHans Petter Selasky 	/* HACK: to be replaced by call to RMPP Segmentation */
836d6b92ffaSHans Petter Selasky 	status = osm_ts_send_mad(p_bind, p_madw);
837d6b92ffaSHans Petter Selasky 
838d6b92ffaSHans Petter Selasky 	/* we do not get an asycn callback so call it ourselves */
839d6b92ffaSHans Petter Selasky 	/* this will handle all cleanup if neccessary */
840d6b92ffaSHans Petter Selasky 	__osm_ts_send_callback(p_bind, !resp_expected, p_madw, status);
841d6b92ffaSHans Petter Selasky 
842d6b92ffaSHans Petter Selasky Exit:
843d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
844d6b92ffaSHans Petter Selasky 	return (status);
845d6b92ffaSHans Petter Selasky }
846d6b92ffaSHans Petter Selasky 
847d6b92ffaSHans Petter Selasky /**********************************************************************
848d6b92ffaSHans Petter Selasky  * the idea here is to change the content of the bind such that it
849d6b92ffaSHans Petter Selasky  * will hold the local address used for sending directed route by the SMA.
850d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)851d6b92ffaSHans Petter Selasky ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)
852d6b92ffaSHans Petter Selasky {
853d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = ((osm_ts_bind_info_t *) h_bind)->p_vend;
854d6b92ffaSHans Petter Selasky 
855d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
856d6b92ffaSHans Petter Selasky 
857d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
858d6b92ffaSHans Petter Selasky 		"osm_vendor_local_lid_change: DEBUG 2202: " "Change of LID.\n");
859d6b92ffaSHans Petter Selasky 
860d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
861d6b92ffaSHans Petter Selasky 
862d6b92ffaSHans Petter Selasky 	return (IB_SUCCESS);
863d6b92ffaSHans Petter Selasky }
864d6b92ffaSHans Petter Selasky 
osm_vendor_set_sm(IN osm_bind_handle_t h_bind,IN boolean_t is_sm_val)865d6b92ffaSHans Petter Selasky void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
866d6b92ffaSHans Petter Selasky {
867d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
868d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
869d6b92ffaSHans Petter Selasky 	VAPI_ret_t status;
870d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_t attr_mod;
871d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_mask_t attr_mask;
872d6b92ffaSHans Petter Selasky 
873d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
874d6b92ffaSHans Petter Selasky 
875d6b92ffaSHans Petter Selasky 	memset(&attr_mod, 0, sizeof(attr_mod));
876d6b92ffaSHans Petter Selasky 	memset(&attr_mask, 0, sizeof(attr_mask));
877d6b92ffaSHans Petter Selasky 
878d6b92ffaSHans Petter Selasky 	attr_mod.is_sm = is_sm_val;
879d6b92ffaSHans Petter Selasky 	attr_mask = HCA_ATTR_IS_SM;
880d6b92ffaSHans Petter Selasky 
881d6b92ffaSHans Petter Selasky 	status =
882d6b92ffaSHans Petter Selasky 	    VAPI_modify_hca_attr(p_bind->hca_hndl, p_bind->port_num, &attr_mod,
883d6b92ffaSHans Petter Selasky 				 &attr_mask);
884d6b92ffaSHans Petter Selasky 	if (status != VAPI_OK) {
885d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
886d6b92ffaSHans Petter Selasky 			"osm_vendor_set_sm: ERR 5027: "
887d6b92ffaSHans Petter Selasky 			"Unable set 'IS_SM' bit to:%u in port attributes (%d).\n",
888d6b92ffaSHans Petter Selasky 			is_sm_val, status);
889d6b92ffaSHans Petter Selasky 	}
890d6b92ffaSHans Petter Selasky 
891d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
892d6b92ffaSHans Petter Selasky }
893d6b92ffaSHans Petter Selasky 
osm_vendor_set_debug(IN osm_vendor_t * const p_vend,IN int32_t level)894d6b92ffaSHans Petter Selasky void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level)
895d6b92ffaSHans Petter Selasky {
896d6b92ffaSHans Petter Selasky 
897d6b92ffaSHans Petter Selasky }
898