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 /*  AUTHOR                 Eitan Zahavi
37d6b92ffaSHans Petter Selasky  *
38d6b92ffaSHans Petter Selasky  *  DESCRIPTION
39d6b92ffaSHans Petter Selasky  *     The lower-level MAD transport interface implementation
40d6b92ffaSHans Petter Selasky  *     that allows sending a single MAD/receiving a callback
41d6b92ffaSHans Petter Selasky  *     when a single MAD is received.
42d6b92ffaSHans Petter Selasky  */
43d6b92ffaSHans Petter Selasky 
44d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
45d6b92ffaSHans Petter Selasky #  include <config.h>
46d6b92ffaSHans Petter Selasky #endif				/* HAVE_CONFIG_H */
47d6b92ffaSHans Petter Selasky 
48d6b92ffaSHans Petter Selasky #include <sys/types.h>
49d6b92ffaSHans Petter Selasky #include <sys/stat.h>
50d6b92ffaSHans Petter Selasky #include <sys/ioctl.h>
51d6b92ffaSHans Petter Selasky #include <fcntl.h>
52d6b92ffaSHans Petter Selasky #include <errno.h>
53d6b92ffaSHans Petter Selasky #include <stdlib.h>
54d6b92ffaSHans Petter Selasky #include <string.h>
55d6b92ffaSHans Petter Selasky 
56d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_api.h>
57d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mlx_transport.h>
58d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mlx_dispatcher.h>
59d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mlx_svc.h>
60d6b92ffaSHans Petter Selasky #include <complib/cl_thread.h>
61d6b92ffaSHans Petter Selasky 
62d6b92ffaSHans Petter Selasky /* the simulator messages definition */
63d6b92ffaSHans Petter Selasky #include <ibmgtsim/ibms_client_api.h>
64d6b92ffaSHans Petter Selasky 
65d6b92ffaSHans Petter Selasky typedef struct _osmv_ibms_transport_mgr {
66d6b92ffaSHans Petter Selasky 	ibms_conn_handle_t conHdl;	/* the connection handle we talk to */
67d6b92ffaSHans Petter Selasky 	ibms_bind_msg_t filter;	/* the bind message defining the filtering */
68d6b92ffaSHans Petter Selasky 	cl_thread_t receiver;	/* the thread waiting for incomming messages */
69d6b92ffaSHans Petter Selasky } osmv_ibms_transport_mgr_t;
70d6b92ffaSHans Petter Selasky 
71d6b92ffaSHans Petter Selasky static void
72d6b92ffaSHans Petter Selasky __osmv_ibms_mad_addr_to_osm_addr(IN osm_vendor_t const *p_vend,
73d6b92ffaSHans Petter Selasky 				 IN struct _ibms_mad_addr *p_ibms_addr,
74d6b92ffaSHans Petter Selasky 				 IN uint8_t is_smi,
75d6b92ffaSHans Petter Selasky 				 OUT osm_mad_addr_t * p_osm_addr);
76d6b92ffaSHans Petter Selasky 
77d6b92ffaSHans Petter Selasky static void
78d6b92ffaSHans Petter Selasky __osmv_ibms_osm_addr_to_mad_addr(IN const osm_mad_addr_t * p_osm_addr,
79d6b92ffaSHans Petter Selasky 				 IN uint8_t is_smi,
80d6b92ffaSHans Petter Selasky 				 OUT struct _ibms_mad_addr *p_ibms_addr);
81d6b92ffaSHans Petter Selasky 
82d6b92ffaSHans Petter Selasky /* this is the callback function the "server" will call on incoming
83d6b92ffaSHans Petter Selasky    messages */
__osmv_ibms_receiver_callback(void * p_ctx,ibms_mad_msg_t * p_mad)84d6b92ffaSHans Petter Selasky void __osmv_ibms_receiver_callback(void *p_ctx, ibms_mad_msg_t * p_mad)
85d6b92ffaSHans Petter Selasky {
86d6b92ffaSHans Petter Selasky 	osm_mad_addr_t mad_addr;
87d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *const p_bo = (osmv_bind_obj_t *) p_ctx;
88d6b92ffaSHans Petter Selasky 	ib_api_status_t status = IB_SUCCESS;
89d6b92ffaSHans Petter Selasky 
90d6b92ffaSHans Petter Selasky 	/* Make sure the p_bo object is still relevant */
91d6b92ffaSHans Petter Selasky 	if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing)
92d6b92ffaSHans Petter Selasky 		return;
93d6b92ffaSHans Petter Selasky 
94d6b92ffaSHans Petter Selasky 	{
95d6b92ffaSHans Petter Selasky 		OSM_LOG_ENTER(p_bo->p_vendor->p_log);
96d6b92ffaSHans Petter Selasky 
97d6b92ffaSHans Petter Selasky 		/* some logging */
98d6b92ffaSHans Petter Selasky 		osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
99d6b92ffaSHans Petter Selasky 			"__osmv_ibms_receiver_callback: "
100d6b92ffaSHans Petter Selasky 			"MAD QPN:%d SLID:0x%04x class:0x%02x "
101d6b92ffaSHans Petter Selasky 			"method:0x%02x attr:0x%04x status:0x%04x "
102d6b92ffaSHans Petter Selasky 			"tid:0x%016" PRIx64 "\n",
103d6b92ffaSHans Petter Selasky 			p_mad->addr.dqpn,
104d6b92ffaSHans Petter Selasky 			cl_ntoh16(p_mad->addr.slid),
105d6b92ffaSHans Petter Selasky 			p_mad->header.mgmt_class,
106d6b92ffaSHans Petter Selasky 			p_mad->header.method,
107d6b92ffaSHans Petter Selasky 			cl_ntoh16(p_mad->header.attr_id),
108d6b92ffaSHans Petter Selasky 			cl_ntoh16(p_mad->header.status),
109d6b92ffaSHans Petter Selasky 			cl_ntoh64(p_mad->header.trans_id));
110d6b92ffaSHans Petter Selasky 
111d6b92ffaSHans Petter Selasky 		/* first arrange an address */
112d6b92ffaSHans Petter Selasky 		__osmv_ibms_mad_addr_to_osm_addr(p_bo->p_vendor,
113d6b92ffaSHans Petter Selasky 						 &p_mad->addr,
114d6b92ffaSHans Petter Selasky 						 (((ib_mad_t *) & p_mad->
115d6b92ffaSHans Petter Selasky 						   header)->mgmt_class ==
116d6b92ffaSHans Petter Selasky 						  IB_MCLASS_SUBN_LID)
117d6b92ffaSHans Petter Selasky 						 ||
118d6b92ffaSHans Petter Selasky 						 (((ib_mad_t *) & p_mad->
119d6b92ffaSHans Petter Selasky 						   header)->mgmt_class ==
120d6b92ffaSHans Petter Selasky 						  IB_MCLASS_SUBN_DIR),
121d6b92ffaSHans Petter Selasky 						 &mad_addr);
122d6b92ffaSHans Petter Selasky 
123d6b92ffaSHans Petter Selasky 		/* call the receiver callback */
124d6b92ffaSHans Petter Selasky 
125d6b92ffaSHans Petter Selasky 		status =
126d6b92ffaSHans Petter Selasky 		    osmv_dispatch_mad((osm_bind_handle_t) p_bo,
127d6b92ffaSHans Petter Selasky 				      (void *)&p_mad->header, &mad_addr);
128d6b92ffaSHans Petter Selasky 
129d6b92ffaSHans Petter Selasky 		OSM_LOG_EXIT(p_bo->p_vendor->p_log);
130d6b92ffaSHans Petter Selasky 	}
131d6b92ffaSHans Petter Selasky }
132d6b92ffaSHans Petter Selasky 
133d6b92ffaSHans Petter Selasky ib_api_status_t
134d6b92ffaSHans Petter Selasky osm_vendor_get_guid_by_ca_and_port(IN osm_vendor_t * const p_vend,
135d6b92ffaSHans Petter Selasky 				   IN char *hca_id,
136d6b92ffaSHans Petter Selasky 				   IN uint32_t port_num,
137d6b92ffaSHans Petter Selasky 				   OUT uint64_t * p_port_guid);
138d6b92ffaSHans Petter Selasky 
139d6b92ffaSHans Petter Selasky /*
140d6b92ffaSHans Petter Selasky  * NAME
141d6b92ffaSHans Petter Selasky  *   osmv_transport_init
142d6b92ffaSHans Petter Selasky  *
143d6b92ffaSHans Petter Selasky  * DESCRIPTION
144d6b92ffaSHans Petter Selasky  *   Setup the MAD transport infrastructure (filters, callbacks etc).
145d6b92ffaSHans Petter Selasky  */
146d6b92ffaSHans Petter Selasky 
147d6b92ffaSHans Petter Selasky ib_api_status_t
osmv_transport_init(IN osm_bind_info_t * p_info,IN char hca_id[VENDOR_HCA_MAXNAMES],IN uint8_t hca_idx,IN osmv_bind_obj_t * p_bo)148d6b92ffaSHans Petter Selasky osmv_transport_init(IN osm_bind_info_t * p_info,
149d6b92ffaSHans Petter Selasky 		    IN char hca_id[VENDOR_HCA_MAXNAMES],
150d6b92ffaSHans Petter Selasky 		    IN uint8_t hca_idx, IN osmv_bind_obj_t * p_bo)
151d6b92ffaSHans Petter Selasky {
152d6b92ffaSHans Petter Selasky 	ibms_conn_handle_t conHdl;	/* the connection we talk to the simulator through */
153d6b92ffaSHans Petter Selasky 	osmv_ibms_transport_mgr_t *p_mgr =
154d6b92ffaSHans Petter Selasky 	    malloc(sizeof(osmv_ibms_transport_mgr_t));
155d6b92ffaSHans Petter Selasky 	int qpn;
156d6b92ffaSHans Petter Selasky 	int ibms_status;
157d6b92ffaSHans Petter Selasky 	uint64_t port_guid;
158d6b92ffaSHans Petter Selasky 
159d6b92ffaSHans Petter Selasky 	if (!p_mgr) {
160d6b92ffaSHans Petter Selasky 		return IB_INSUFFICIENT_MEMORY;
161d6b92ffaSHans Petter Selasky 	}
162d6b92ffaSHans Petter Selasky 
163d6b92ffaSHans Petter Selasky 	memset(p_mgr, 0, sizeof(osmv_ibms_transport_mgr_t));
164d6b92ffaSHans Petter Selasky 
165d6b92ffaSHans Petter Selasky 	/* create the client socket connected to the simulator */
166d6b92ffaSHans Petter Selasky 	/* also perform the "connect" message - such that we
167d6b92ffaSHans Petter Selasky 	   validate the target guid */
168d6b92ffaSHans Petter Selasky 	if (osm_vendor_get_guid_by_ca_and_port
169d6b92ffaSHans Petter Selasky 	    (p_bo->p_vendor, hca_id, p_bo->port_num, &port_guid)) {
170d6b92ffaSHans Petter Selasky 		return IB_INVALID_GUID;
171d6b92ffaSHans Petter Selasky 	}
172d6b92ffaSHans Petter Selasky 
173d6b92ffaSHans Petter Selasky 	conHdl =
174d6b92ffaSHans Petter Selasky 	    ibms_connect(port_guid, __osmv_ibms_receiver_callback,
175d6b92ffaSHans Petter Selasky 			 (void *)p_bo);
176d6b92ffaSHans Petter Selasky 	if (!conHdl) {
177d6b92ffaSHans Petter Selasky 		printf("fail to connect to the server.\n");
178d6b92ffaSHans Petter Selasky 		exit(1);
179d6b92ffaSHans Petter Selasky 	}
180d6b92ffaSHans Petter Selasky 
181d6b92ffaSHans Petter Selasky 	/*
182d6b92ffaSHans Petter Selasky 	 * Create the MAD filter on this file handle.
183d6b92ffaSHans Petter Selasky 	 */
184d6b92ffaSHans Petter Selasky 
185d6b92ffaSHans Petter Selasky 	p_mgr->filter.port = p_bo->port_num;
186d6b92ffaSHans Petter Selasky 	p_mgr->filter.only_input = 1;
187d6b92ffaSHans Petter Selasky 	p_mgr->filter.mask =
188d6b92ffaSHans Petter Selasky 	    IBMS_BIND_MASK_PORT |
189d6b92ffaSHans Petter Selasky 	    IBMS_BIND_MASK_INPUT | IBMS_BIND_MASK_QP | IBMS_BIND_MASK_CLASS;
190d6b92ffaSHans Petter Selasky 
191d6b92ffaSHans Petter Selasky 	switch (p_info->mad_class) {
192d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_LID:
193d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_DIR:
194d6b92ffaSHans Petter Selasky 		qpn = 0;
195d6b92ffaSHans Petter Selasky 		p_mgr->filter.qpn = qpn;
196d6b92ffaSHans Petter Selasky 		p_mgr->filter.mgt_class = IB_MCLASS_SUBN_LID;
197d6b92ffaSHans Petter Selasky 		ibms_status = ibms_bind(conHdl, &p_mgr->filter);
198d6b92ffaSHans Petter Selasky 		if (ibms_status) {
199d6b92ffaSHans Petter Selasky 			return IB_ERROR;
200d6b92ffaSHans Petter Selasky 		}
201d6b92ffaSHans Petter Selasky 
202d6b92ffaSHans Petter Selasky 		p_mgr->filter.mgt_class = IB_MCLASS_SUBN_DIR;
203d6b92ffaSHans Petter Selasky 		ibms_status = ibms_bind(conHdl, &p_mgr->filter);
204d6b92ffaSHans Petter Selasky 		if (ibms_status) {
205d6b92ffaSHans Petter Selasky 			return IB_ERROR;
206d6b92ffaSHans Petter Selasky 		}
207d6b92ffaSHans Petter Selasky 
208d6b92ffaSHans Petter Selasky 		break;
209d6b92ffaSHans Petter Selasky 
210d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_ADM:
211d6b92ffaSHans Petter Selasky 	default:
212d6b92ffaSHans Petter Selasky 		qpn = 1;
213d6b92ffaSHans Petter Selasky 		p_mgr->filter.qpn = qpn;
214d6b92ffaSHans Petter Selasky 		p_mgr->filter.mgt_class = p_info->mad_class;
215d6b92ffaSHans Petter Selasky 		ibms_status = ibms_bind(conHdl, &p_mgr->filter);
216d6b92ffaSHans Petter Selasky 		if (ibms_status) {
217d6b92ffaSHans Petter Selasky 			return IB_ERROR;
218d6b92ffaSHans Petter Selasky 		}
219d6b92ffaSHans Petter Selasky 		break;
220d6b92ffaSHans Petter Selasky 	}
221d6b92ffaSHans Petter Selasky 
222d6b92ffaSHans Petter Selasky 	p_mgr->conHdl = conHdl;
223d6b92ffaSHans Petter Selasky 
224d6b92ffaSHans Petter Selasky 	p_bo->p_transp_mgr = p_mgr;
225d6b92ffaSHans Petter Selasky 
226d6b92ffaSHans Petter Selasky 	/* Initialize the magic_ptr to the pointer of the p_bo info.
227d6b92ffaSHans Petter Selasky 	   This will be used to signal when the object is being destroyed, so no
228d6b92ffaSHans Petter Selasky 	   real action will be done then. */
229d6b92ffaSHans Petter Selasky 	p_bo->magic_ptr = p_bo;
230d6b92ffaSHans Petter Selasky 
231d6b92ffaSHans Petter Selasky 	return IB_SUCCESS;
232d6b92ffaSHans Petter Selasky }
233d6b92ffaSHans Petter Selasky 
234d6b92ffaSHans Petter Selasky /*
235d6b92ffaSHans Petter Selasky  * NAME
236d6b92ffaSHans Petter Selasky  *   osmv_transport_send_mad
237d6b92ffaSHans Petter Selasky  *
238d6b92ffaSHans Petter Selasky  * DESCRIPTION
239d6b92ffaSHans Petter Selasky  *   Send a single MAD (256 byte)
240d6b92ffaSHans Petter Selasky  */
241d6b92ffaSHans Petter Selasky 
242d6b92ffaSHans Petter Selasky ib_api_status_t
osmv_transport_mad_send(IN const osm_bind_handle_t h_bind,IN void * p_mad,IN const osm_mad_addr_t * p_mad_addr)243d6b92ffaSHans Petter Selasky osmv_transport_mad_send(IN const osm_bind_handle_t h_bind,
244d6b92ffaSHans Petter Selasky 			IN void *p_mad, IN const osm_mad_addr_t * p_mad_addr)
245d6b92ffaSHans Petter Selasky {
246d6b92ffaSHans Petter Selasky 
247d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
248d6b92ffaSHans Petter Selasky 	osm_vendor_t const *p_vend = p_bo->p_vendor;
249d6b92ffaSHans Petter Selasky 	int ret;
250d6b92ffaSHans Petter Selasky 	ibms_mad_msg_t mad_msg;
251d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
252d6b92ffaSHans Petter Selasky 
253d6b92ffaSHans Petter Selasky 	const ib_mad_t *p_mad_hdr = p_mad;
254d6b92ffaSHans Petter Selasky 
255d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
256d6b92ffaSHans Petter Selasky 
257d6b92ffaSHans Petter Selasky 	memset(&mad_msg, 0, sizeof(mad_msg));
258d6b92ffaSHans Petter Selasky 
259d6b92ffaSHans Petter Selasky 	/* Make sure the p_bo object is still relevant */
260d6b92ffaSHans Petter Selasky 	if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing)
261d6b92ffaSHans Petter Selasky 		return IB_INVALID_CALLBACK;
262d6b92ffaSHans Petter Selasky 
263d6b92ffaSHans Petter Selasky 	/*
264d6b92ffaSHans Petter Selasky 	 * Copy the MAD over to the sent mad
265d6b92ffaSHans Petter Selasky 	 */
266d6b92ffaSHans Petter Selasky 	memcpy(&mad_msg.header, p_mad_hdr, MAD_BLOCK_SIZE);
267d6b92ffaSHans Petter Selasky 
268d6b92ffaSHans Petter Selasky 	/*
269d6b92ffaSHans Petter Selasky 	 * For all sends other than directed route SM MADs,
270d6b92ffaSHans Petter Selasky 	 * acquire an address vector for the destination.
271d6b92ffaSHans Petter Selasky 	 */
272d6b92ffaSHans Petter Selasky 	if (p_mad_hdr->mgmt_class != IB_MCLASS_SUBN_DIR) {
273d6b92ffaSHans Petter Selasky 
274d6b92ffaSHans Petter Selasky 		__osmv_ibms_osm_addr_to_mad_addr(p_mad_addr,
275d6b92ffaSHans Petter Selasky 						 p_mad_hdr->mgmt_class ==
276d6b92ffaSHans Petter Selasky 						 IB_MCLASS_SUBN_LID,
277d6b92ffaSHans Petter Selasky 						 &mad_msg.addr);
278d6b92ffaSHans Petter Selasky 	} else {
279d6b92ffaSHans Petter Selasky 		/* is a directed route - we need to construct a permissive address */
280d6b92ffaSHans Petter Selasky 		/* we do not need port number since it is part of the mad_hndl */
281d6b92ffaSHans Petter Selasky 		mad_msg.addr.dlid = IB_LID_PERMISSIVE;
282d6b92ffaSHans Petter Selasky 		mad_msg.addr.slid = IB_LID_PERMISSIVE;
283d6b92ffaSHans Petter Selasky 		mad_msg.addr.sqpn = 0;
284d6b92ffaSHans Petter Selasky 		mad_msg.addr.dqpn = 0;
285d6b92ffaSHans Petter Selasky 	}
286d6b92ffaSHans Petter Selasky 
287d6b92ffaSHans Petter Selasky 	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
288d6b92ffaSHans Petter Selasky 		"osmv_transport_mad_send: "
289d6b92ffaSHans Petter Selasky 		"Sending QPN:%d DLID:0x%04x class:0x%02x "
290d6b92ffaSHans Petter Selasky 		"method:0x%02x attr:0x%04x status:0x%04x "
291d6b92ffaSHans Petter Selasky 		"tid:0x%016" PRIx64 "\n",
292d6b92ffaSHans Petter Selasky 		mad_msg.addr.dqpn,
293d6b92ffaSHans Petter Selasky 		cl_ntoh16(mad_msg.addr.dlid),
294d6b92ffaSHans Petter Selasky 		mad_msg.header.mgmt_class,
295d6b92ffaSHans Petter Selasky 		mad_msg.header.method,
296d6b92ffaSHans Petter Selasky 		cl_ntoh16(mad_msg.header.attr_id),
297d6b92ffaSHans Petter Selasky 		cl_ntoh16(mad_msg.header.status),
298d6b92ffaSHans Petter Selasky 		cl_ntoh64(mad_msg.header.trans_id)
299d6b92ffaSHans Petter Selasky 	    );
300d6b92ffaSHans Petter Selasky 
301d6b92ffaSHans Petter Selasky 	/* send it */
302d6b92ffaSHans Petter Selasky 	ret =
303d6b92ffaSHans Petter Selasky 	    ibms_send(((osmv_ibms_transport_mgr_t *) (p_bo->p_transp_mgr))->
304d6b92ffaSHans Petter Selasky 		      conHdl, &mad_msg);
305d6b92ffaSHans Petter Selasky 	if (ret) {
306d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
307d6b92ffaSHans Petter Selasky 			"osmv_transport_mad_send: ERR 5304: "
308d6b92ffaSHans Petter Selasky 			"Error sending mad (%d).\n", ret);
309d6b92ffaSHans Petter Selasky 		status = IB_ERROR;
310d6b92ffaSHans Petter Selasky 		goto Exit;
311d6b92ffaSHans Petter Selasky 	}
312d6b92ffaSHans Petter Selasky 
313d6b92ffaSHans Petter Selasky 	status = IB_SUCCESS;
314d6b92ffaSHans Petter Selasky 
315d6b92ffaSHans Petter Selasky Exit:
316d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
317d6b92ffaSHans Petter Selasky 	return (status);
318d6b92ffaSHans Petter Selasky }
319d6b92ffaSHans Petter Selasky 
osmv_transport_done(IN const osm_bind_handle_t h_bind)320d6b92ffaSHans Petter Selasky void osmv_transport_done(IN const osm_bind_handle_t h_bind)
321d6b92ffaSHans Petter Selasky {
322d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
323d6b92ffaSHans Petter Selasky 	osmv_ibms_transport_mgr_t *p_tpot_mgr =
324d6b92ffaSHans Petter Selasky 	    (osmv_ibms_transport_mgr_t *) (p_bo->p_transp_mgr);
325d6b92ffaSHans Petter Selasky 
326d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_bo);
327d6b92ffaSHans Petter Selasky 
328d6b92ffaSHans Petter Selasky 	/* First of all - zero out the magic_ptr, so if a callback is called -
329d6b92ffaSHans Petter Selasky 	   it'll know that we are currently closing down, and will not handle the
330d6b92ffaSHans Petter Selasky 	   mad. */
331d6b92ffaSHans Petter Selasky 	p_bo->magic_ptr = 0;
332d6b92ffaSHans Petter Selasky 	/* usleep(3000000); */
333d6b92ffaSHans Petter Selasky 
334d6b92ffaSHans Petter Selasky 	ibms_disconnect(p_tpot_mgr->conHdl);
335d6b92ffaSHans Petter Selasky 
336d6b92ffaSHans Petter Selasky 	/* seems the only way to abort a blocking read is to make it read something */
337d6b92ffaSHans Petter Selasky 	free(p_tpot_mgr);
338d6b92ffaSHans Petter Selasky }
339d6b92ffaSHans Petter Selasky 
340d6b92ffaSHans Petter Selasky static void
__osmv_ibms_osm_addr_to_mad_addr(IN const osm_mad_addr_t * p_osm_addr,IN uint8_t is_smi,OUT struct _ibms_mad_addr * p_ibms_addr)341d6b92ffaSHans Petter Selasky __osmv_ibms_osm_addr_to_mad_addr(IN const osm_mad_addr_t * p_osm_addr,
342d6b92ffaSHans Petter Selasky 				 IN uint8_t is_smi,
343d6b92ffaSHans Petter Selasky 				 OUT struct _ibms_mad_addr *p_ibms_addr)
344d6b92ffaSHans Petter Selasky {
345d6b92ffaSHans Petter Selasky 
346d6b92ffaSHans Petter Selasky 	/* For global destination or Multicast address: */
347d6b92ffaSHans Petter Selasky 	p_ibms_addr->dlid = cl_ntoh16(p_osm_addr->dest_lid);
348d6b92ffaSHans Petter Selasky 	p_ibms_addr->sl = p_osm_addr->addr_type.gsi.service_level;
349d6b92ffaSHans Petter Selasky 	if (is_smi) {
350d6b92ffaSHans Petter Selasky 		p_ibms_addr->sqpn = 0;
351d6b92ffaSHans Petter Selasky 		p_ibms_addr->dqpn = 0;
352d6b92ffaSHans Petter Selasky 	} else {
353d6b92ffaSHans Petter Selasky 		p_ibms_addr->sqpn = 1;
354d6b92ffaSHans Petter Selasky 		p_ibms_addr->dqpn =
355d6b92ffaSHans Petter Selasky 		    cl_ntoh32(p_osm_addr->addr_type.gsi.remote_qp);
356d6b92ffaSHans Petter Selasky 	}
357d6b92ffaSHans Petter Selasky 	/*
358d6b92ffaSHans Petter Selasky 	   HACK we limit to the first PKey Index assuming it will
359d6b92ffaSHans Petter Selasky 	   always be the default PKey
360d6b92ffaSHans Petter Selasky 	 */
361d6b92ffaSHans Petter Selasky 	p_ibms_addr->pkey_index = 0;
362d6b92ffaSHans Petter Selasky }
363d6b92ffaSHans Petter Selasky 
364d6b92ffaSHans Petter Selasky static void
__osmv_ibms_mad_addr_to_osm_addr(IN osm_vendor_t const * p_vend,IN struct _ibms_mad_addr * p_ibms_addr,IN uint8_t is_smi,OUT osm_mad_addr_t * p_osm_addr)365d6b92ffaSHans Petter Selasky __osmv_ibms_mad_addr_to_osm_addr(IN osm_vendor_t const *p_vend,
366d6b92ffaSHans Petter Selasky 				 IN struct _ibms_mad_addr *p_ibms_addr,
367d6b92ffaSHans Petter Selasky 				 IN uint8_t is_smi,
368d6b92ffaSHans Petter Selasky 				 OUT osm_mad_addr_t * p_osm_addr)
369d6b92ffaSHans Petter Selasky {
370d6b92ffaSHans Petter Selasky 	memset(p_osm_addr, 0, sizeof(osm_mad_addr_t));
371d6b92ffaSHans Petter Selasky 	p_osm_addr->dest_lid = cl_hton16(p_ibms_addr->slid);
372d6b92ffaSHans Petter Selasky 	p_osm_addr->static_rate = 0;
373d6b92ffaSHans Petter Selasky 	p_osm_addr->path_bits = 0;
374d6b92ffaSHans Petter Selasky 	if (is_smi) {
375d6b92ffaSHans Petter Selasky 		/* SMI */
376d6b92ffaSHans Petter Selasky 		p_osm_addr->addr_type.smi.source_lid =
377d6b92ffaSHans Petter Selasky 		    cl_hton16(p_ibms_addr->slid);
378d6b92ffaSHans Petter Selasky 		p_osm_addr->addr_type.smi.port_num = 1;	/* TODO add if required p_ibms_addr->port; */
379d6b92ffaSHans Petter Selasky 	} else {
380d6b92ffaSHans Petter Selasky 		/* GSI */
381d6b92ffaSHans Petter Selasky 		p_osm_addr->addr_type.gsi.remote_qp =
382d6b92ffaSHans Petter Selasky 		    cl_ntoh32(p_ibms_addr->sqpn);
383d6b92ffaSHans Petter Selasky 		p_osm_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
384d6b92ffaSHans Petter Selasky 		p_osm_addr->addr_type.gsi.pkey_ix = p_ibms_addr->pkey_index;
385d6b92ffaSHans Petter Selasky 		p_osm_addr->addr_type.gsi.service_level = p_ibms_addr->sl;
386d6b92ffaSHans Petter Selasky 
387d6b92ffaSHans Petter Selasky 		p_osm_addr->addr_type.gsi.global_route = FALSE;
388d6b92ffaSHans Petter Selasky 		/* copy the GRH data if relevant - TopSpin imp doesnt relate to GRH!!! */
389d6b92ffaSHans Petter Selasky 		/*
390d6b92ffaSHans Petter Selasky 		   if (p_osm_addr->addr_type.gsi.global_route)
391d6b92ffaSHans Petter Selasky 		   {
392d6b92ffaSHans Petter Selasky 		   p_osm_addr->addr_type.gsi.grh_info.ver_class_flow =
393d6b92ffaSHans Petter Selasky 		   ib_grh_set_ver_class_flow(p_rcv_desc->grh.IP_version,
394d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.traffic_class,
395d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.flow_label);
396d6b92ffaSHans Petter Selasky 		   p_osm_addr->addr_type.gsi.grh_info.hop_limit =  p_rcv_desc->grh.hop_limit;
397d6b92ffaSHans Petter Selasky 		   memcpy(&p_osm_addr->addr_type.gsi.grh_info.src_gid.raw,
398d6b92ffaSHans Petter Selasky 		   &p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
399d6b92ffaSHans Petter Selasky 		   memcpy(&p_osm_addr->addr_type.gsi.grh_info.dest_gid.raw,
400d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.dgid,  sizeof(ib_net64_t));
401d6b92ffaSHans Petter Selasky 		   }
402d6b92ffaSHans Petter Selasky 		 */
403d6b92ffaSHans Petter Selasky 	}
404d6b92ffaSHans Petter Selasky }
405d6b92ffaSHans Petter Selasky 
406d6b92ffaSHans Petter Selasky /*
407d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_set_sm
408d6b92ffaSHans Petter Selasky  *
409d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Modifies the port info for the bound port to set the "IS_SM" bit
410d6b92ffaSHans Petter Selasky  *                  according to the value given (TRUE or FALSE).
411d6b92ffaSHans Petter Selasky  */
412d6b92ffaSHans Petter Selasky 
osm_vendor_set_sm(IN osm_bind_handle_t h_bind,IN boolean_t is_sm_val)413d6b92ffaSHans Petter Selasky void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
414d6b92ffaSHans Petter Selasky {
415d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
416d6b92ffaSHans Petter Selasky 	osm_vendor_t const *p_vend = p_bo->p_vendor;
417d6b92ffaSHans Petter Selasky 	int ret;
418d6b92ffaSHans Petter Selasky 	ibms_cap_msg_t cap_msg;
419d6b92ffaSHans Petter Selasky 
420d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
421d6b92ffaSHans Petter Selasky 
422d6b92ffaSHans Petter Selasky 	cap_msg.mask = IB_PORT_CAP_IS_SM;
423d6b92ffaSHans Petter Selasky 	if (is_sm_val)
424d6b92ffaSHans Petter Selasky 		cap_msg.capabilities = IB_PORT_CAP_IS_SM;
425d6b92ffaSHans Petter Selasky 	else
426d6b92ffaSHans Petter Selasky 		cap_msg.capabilities = 0;
427d6b92ffaSHans Petter Selasky 
428d6b92ffaSHans Petter Selasky 	ret = ibms_set_cap(((osmv_ibms_transport_mgr_t *) (p_bo->
429d6b92ffaSHans Petter Selasky 							   p_transp_mgr))->
430d6b92ffaSHans Petter Selasky 			   conHdl, &cap_msg);
431d6b92ffaSHans Petter Selasky 
432d6b92ffaSHans Petter Selasky 	if (ret) {
433d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
434d6b92ffaSHans Petter Selasky 			"osm_vendor_set_sm: ERR 5312: "
435d6b92ffaSHans Petter Selasky 			"Unable set 'IS_SM' bit to:%u in port attributes.\n",
436d6b92ffaSHans Petter Selasky 			is_sm_val);
437d6b92ffaSHans Petter Selasky 	}
438d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
439d6b92ffaSHans Petter Selasky }
440