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