1 /*
2 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2007,2009 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 * Copyright (c) 2009,2010 HNR Consulting. All rights reserved.
6 *
7 * This software is available to you under a choice of one of two
8 * licenses. You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * OpenIB.org BSD license below:
12 *
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
15 * conditions are met:
16 *
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer.
20 *
21 * - Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials
24 * provided with the distribution.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 * SOFTWARE.
34 *
35 */
36
37 #if HAVE_CONFIG_H
38 # include <config.h>
39 #endif /* HAVE_CONFIG_H */
40
41 #include <stdlib.h>
42 #include <string.h>
43 #include <sys/time.h>
44 #include <vendor/osm_vendor_api.h>
45 #include <vendor/osm_vendor_sa_api.h>
46 #include <complib/cl_event.h>
47
48 /* this struct is the internal rep of the bind handle */
49 typedef struct _osmv_sa_bind_info {
50 osm_bind_handle_t h_bind;
51 osm_log_t *p_log;
52 osm_vendor_t *p_vendor;
53 osm_mad_pool_t *p_mad_pool;
54 cl_event_t sync_event;
55 time_t last_lids_update_sec;
56 } osmv_sa_bind_info_t;
57
58 /*
59 Call back on new mad received:
60
61 We basically only need to set the context of the query.
62 Or report an error.
63
64 A pointer to the actual context of the request (a copy of the oriignal
65 request structure) is attached as the p_madw->context.ni_context.node_guid
66 */
67 static void
__osmv_sa_mad_rcv_cb(IN osm_madw_t * p_madw,IN void * bind_context,IN osm_madw_t * p_req_madw)68 __osmv_sa_mad_rcv_cb(IN osm_madw_t * p_madw,
69 IN void *bind_context, IN osm_madw_t * p_req_madw)
70 {
71 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context;
72 osmv_query_req_t *p_query_req_copy = NULL;
73 osmv_query_res_t query_res;
74 ib_sa_mad_t *p_sa_mad;
75 ib_net16_t mad_status;
76
77 OSM_LOG_ENTER(p_bind->p_log);
78
79 if (!p_req_madw) {
80 OSM_LOG(p_bind->p_log, OSM_LOG_DEBUG,
81 "Ignoring a non-response mad\n");
82 osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
83 goto Exit;
84 }
85
86 /* obtain the sent context since we store it during send in the ni_ctx */
87 p_query_req_copy = (osmv_query_req_t *)
88 (uintptr_t)(osm_madw_get_ni_context_ptr(p_req_madw)->node_guid);
89
90 /* provide the context of the original request in the result */
91 query_res.query_context = p_query_req_copy->query_context;
92
93 /* provide the resulting madw */
94 query_res.p_result_madw = p_madw;
95
96 /* update the req fields */
97 p_sa_mad = (ib_sa_mad_t *) p_madw->p_mad;
98
99 /* if we got a remote error track it in the status */
100 mad_status = (ib_net16_t) (p_sa_mad->status & IB_SMP_STATUS_MASK);
101 if (mad_status != IB_SUCCESS) {
102 OSM_LOG(p_bind->p_log, OSM_LOG_ERROR, "ERR 5501: "
103 "Remote error: 0x%04X\n", cl_ntoh16(mad_status));
104 query_res.status = IB_REMOTE_ERROR;
105 } else
106 query_res.status = IB_SUCCESS;
107
108 /* what if we have got back an empty mad ? */
109 if (!p_madw->mad_size) {
110 OSM_LOG(p_bind->p_log, OSM_LOG_ERROR, "ERR 5502: "
111 "Got an empty mad\n");
112 query_res.status = IB_ERROR;
113 }
114
115 if (IB_SUCCESS == mad_status) {
116
117 /* if we are in not in a method response of an rmpp nature we must get only 1 */
118 /* HACK: in the future we might need to be smarter for other methods... */
119 if (p_sa_mad->method != IB_MAD_METHOD_GETTABLE_RESP) {
120 query_res.result_cnt = 1;
121 } else {
122 #ifndef VENDOR_RMPP_SUPPORT
123 if (mad_status != IB_SUCCESS)
124 query_res.result_cnt = 0;
125 else
126 query_res.result_cnt = 1;
127 #else
128 if (ib_get_attr_size(p_sa_mad->attr_offset)) {
129 /* we used the offset value to calculate the
130 number of records in here */
131 query_res.result_cnt =
132 (p_madw->mad_size - IB_SA_MAD_HDR_SIZE) /
133 ib_get_attr_size(p_sa_mad->attr_offset);
134 OSM_LOG(p_bind->p_log, OSM_LOG_DEBUG,
135 "Count = %u = %zu / %u (%zu)\n",
136 query_res.result_cnt,
137 p_madw->mad_size - IB_SA_MAD_HDR_SIZE,
138 ib_get_attr_size(p_sa_mad->attr_offset),
139 (p_madw->mad_size -
140 IB_SA_MAD_HDR_SIZE) %
141 ib_get_attr_size(p_sa_mad->attr_offset));
142 } else
143 query_res.result_cnt = 0;
144 #endif
145 }
146 }
147
148 query_res.query_type = p_query_req_copy->query_type;
149
150 p_query_req_copy->pfn_query_cb(&query_res);
151
152 if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
153 cl_event_signal(&p_bind->sync_event);
154
155 Exit:
156
157 /* free the copied query request if found */
158 if (p_query_req_copy)
159 free(p_query_req_copy);
160
161 /* put back the request madw */
162 if (p_req_madw)
163 osm_mad_pool_put(p_bind->p_mad_pool, p_req_madw);
164
165 OSM_LOG_EXIT(p_bind->p_log);
166 }
167
168 /*
169 Send Error Callback:
170
171 Only report the error and get rid of the mad wrapper
172 */
__osmv_sa_mad_err_cb(IN void * bind_context,IN osm_madw_t * p_madw)173 static void __osmv_sa_mad_err_cb(IN void *bind_context, IN osm_madw_t * p_madw)
174 {
175 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context;
176 osmv_query_req_t *p_query_req_copy = NULL;
177 osmv_query_res_t query_res;
178
179 OSM_LOG_ENTER(p_bind->p_log);
180
181 /* Obtain the sent context etc */
182 p_query_req_copy = (osmv_query_req_t *)
183 (uintptr_t)(osm_madw_get_ni_context_ptr(p_madw)->node_guid);
184
185 /* provide the context of the original request in the result */
186 query_res.query_context = p_query_req_copy->query_context;
187
188 query_res.p_result_madw = p_madw;
189
190 query_res.status = IB_TIMEOUT;
191 query_res.result_cnt = 0;
192
193 query_res.query_type = p_query_req_copy->query_type;
194
195 p_query_req_copy->pfn_query_cb(&query_res);
196
197 if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
198 cl_event_signal(&p_bind->sync_event);
199
200 free(p_query_req_copy);
201 OSM_LOG_EXIT(p_bind->p_log);
202 }
203
204 /*****************************************************************************
205 Update lids of vendor umad_port.
206 *****************************************************************************/
update_umad_port(osm_vendor_t * p_vend)207 static ib_api_status_t update_umad_port(osm_vendor_t * p_vend)
208 {
209 umad_port_t port;
210 if (umad_get_port(p_vend->umad_port.ca_name,
211 p_vend->umad_port.portnum, &port) < 0)
212 return IB_ERROR;
213 p_vend->umad_port.base_lid = port.base_lid;
214 p_vend->umad_port.sm_lid = port.sm_lid;
215 umad_release_port(&port);
216 return IB_SUCCESS;
217 }
218
219 osm_bind_handle_t
osmv_bind_sa(IN osm_vendor_t * const p_vend,IN osm_mad_pool_t * const p_mad_pool,IN ib_net64_t port_guid)220 osmv_bind_sa(IN osm_vendor_t * const p_vend,
221 IN osm_mad_pool_t * const p_mad_pool, IN ib_net64_t port_guid)
222 {
223 osm_bind_info_t bind_info;
224 osm_log_t *p_log = p_vend->p_log;
225 osmv_sa_bind_info_t *p_sa_bind_info;
226 cl_status_t cl_status;
227
228 OSM_LOG_ENTER(p_log);
229
230 OSM_LOG(p_log, OSM_LOG_DEBUG,
231 "Binding to port 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
232
233 bind_info.port_guid = port_guid;
234 bind_info.mad_class = IB_MCLASS_SUBN_ADM;
235 bind_info.class_version = 2;
236 bind_info.is_responder = FALSE;
237 bind_info.is_trap_processor = FALSE;
238 bind_info.is_report_processor = FALSE;
239 bind_info.send_q_size = OSM_SM_DEFAULT_QP1_RCV_SIZE;
240 bind_info.recv_q_size = OSM_SM_DEFAULT_QP1_SEND_SIZE;
241 bind_info.timeout = p_vend->timeout;
242 bind_info.retries = OSM_DEFAULT_RETRY_COUNT;
243
244 /* allocate the new sa bind info */
245 p_sa_bind_info =
246 (osmv_sa_bind_info_t *) malloc(sizeof(osmv_sa_bind_info_t));
247 if (!p_sa_bind_info) {
248 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5505: "
249 "Failed to allocate new bind structure\n");
250 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
251 goto Exit;
252 }
253
254 /* store some important context */
255 p_sa_bind_info->p_log = p_log;
256 p_sa_bind_info->p_mad_pool = p_mad_pool;
257 p_sa_bind_info->p_vendor = p_vend;
258
259 /* Bind to the lower level */
260 p_sa_bind_info->h_bind = osm_vendor_bind(p_vend, &bind_info, p_mad_pool, __osmv_sa_mad_rcv_cb, __osmv_sa_mad_err_cb, p_sa_bind_info); /* context provided to CBs */
261
262 if (p_sa_bind_info->h_bind == OSM_BIND_INVALID_HANDLE) {
263 free(p_sa_bind_info);
264 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
265 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5506: "
266 "Failed to bind to vendor GSI\n");
267 goto Exit;
268 }
269
270 /* update time umad_port is initialized now */
271 p_sa_bind_info->last_lids_update_sec = time(NULL);
272
273 /* initialize the sync_event */
274 cl_event_construct(&p_sa_bind_info->sync_event);
275 cl_status = cl_event_init(&p_sa_bind_info->sync_event, TRUE);
276 if (cl_status != CL_SUCCESS) {
277 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5508: "
278 "cl_init_event failed: %s\n", ib_get_err_str(cl_status));
279 free(p_sa_bind_info);
280 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
281 }
282
283 Exit:
284 OSM_LOG_EXIT(p_log);
285 return (p_sa_bind_info);
286 }
287
288 /****t* OSM Vendor SA Client/osmv_sa_mad_data
289 * NAME
290 * osmv_sa_mad_data
291 *
292 * DESCRIPTION
293 * Extra fields required to perform a mad query
294 * This struct is passed to the actual send method
295 *
296 * SYNOPSIS
297 */
298 typedef struct _osmv_sa_mad_data {
299 /* MAD data. */
300 uint8_t method;
301 ib_net16_t attr_id;
302 ib_net16_t attr_offset;
303 ib_net32_t attr_mod;
304 ib_net64_t comp_mask;
305 void *p_attr;
306 } osmv_sa_mad_data_t;
307 /*
308 * method
309 * The method of the mad to be sent
310 *
311 * attr_id
312 * Attribute ID
313 *
314 * attr_offset
315 * Offset as defined by RMPP
316 *
317 * attr_mod
318 * Attribute modifier
319 *
320 * comp_mask
321 * The component mask of the query
322 *
323 * p_attr
324 * A pointer to the record of the attribute to be sent.
325 *
326 *****/
327
328 /* Send a MAD out on the GSI interface */
329 static ib_api_status_t
__osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind,IN const osmv_sa_mad_data_t * const p_sa_mad_data,IN const osmv_query_req_t * const p_query_req)330 __osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind,
331 IN const osmv_sa_mad_data_t * const p_sa_mad_data,
332 IN const osmv_query_req_t * const p_query_req)
333 {
334 ib_api_status_t status;
335 ib_mad_t *p_mad_hdr;
336 ib_sa_mad_t *p_sa_mad;
337 osm_madw_t *p_madw;
338 osm_log_t *p_log = p_bind->p_log;
339 static atomic32_t trans_id;
340 boolean_t sync;
341 osmv_query_req_t *p_query_req_copy;
342 uint32_t sa_size;
343
344 OSM_LOG_ENTER(p_log);
345
346 /*
347 since the sm_lid might change we obtain it every send
348 (actually it is cached in the bind object and refreshed
349 every 30sec by this proc)
350 */
351 if (time(NULL) > p_bind->last_lids_update_sec + 30) {
352 status = update_umad_port(p_bind->p_vendor);
353 if (status != IB_SUCCESS) {
354 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5509: "
355 "Failed to obtain the SM lid\n");
356 goto Exit;
357 }
358 p_bind->last_lids_update_sec = time(NULL);
359 }
360
361 /* Get a MAD wrapper for the send */
362 p_madw = osm_mad_pool_get(p_bind->p_mad_pool,
363 p_bind->h_bind, MAD_BLOCK_SIZE, NULL);
364
365 if (p_madw == NULL) {
366 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5510: "
367 "Unable to acquire MAD\n");
368 status = IB_INSUFFICIENT_RESOURCES;
369 goto Exit;
370 }
371
372 /* Initialize the Sent MAD: */
373
374 /* Initialize the MAD buffer for the send operation. */
375 p_mad_hdr = osm_madw_get_mad_ptr(p_madw);
376 p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
377
378 /* Get a new transaction Id */
379 cl_atomic_inc(&trans_id);
380
381 /* Cleanup the MAD from any residue */
382 memset(p_sa_mad, 0, MAD_BLOCK_SIZE);
383
384 /* Initialize the standard MAD header. */
385 ib_mad_init_new(p_mad_hdr, /* mad pointer */
386 IB_MCLASS_SUBN_ADM, /* class */
387 (uint8_t) 2, /* version */
388 p_sa_mad_data->method, /* method */
389 cl_hton64((uint64_t) trans_id), /* tid */
390 p_sa_mad_data->attr_id, /* attr id */
391 p_sa_mad_data->attr_mod /* attr mod */);
392
393 /* Set the query information. */
394 p_sa_mad->sm_key = p_query_req->sm_key;
395 p_sa_mad->attr_offset = 0;
396 p_sa_mad->comp_mask = p_sa_mad_data->comp_mask;
397 #ifdef DUAL_SIDED_RMPP
398 if (p_sa_mad->method == IB_MAD_METHOD_GETMULTI)
399 p_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
400 #endif
401 if (p_sa_mad->comp_mask) {
402 p_sa_mad_data->attr_offset ? (sa_size = ib_get_attr_size(p_sa_mad_data->attr_offset)) : (sa_size = IB_SA_DATA_SIZE);
403 memcpy(p_sa_mad->data, p_sa_mad_data->p_attr, sa_size);
404 }
405
406 /*
407 Provide the address to send to
408 */
409 p_madw->mad_addr.dest_lid =
410 cl_hton16(p_bind->p_vendor->umad_port.sm_lid);
411 p_madw->mad_addr.addr_type.smi.source_lid =
412 cl_hton16(p_bind->p_vendor->umad_port.base_lid);
413 p_madw->mad_addr.addr_type.gsi.remote_qp = CL_HTON32(1);
414 p_madw->resp_expected = TRUE;
415 p_madw->fail_msg = CL_DISP_MSGID_NONE;
416
417 /*
418 add grh
419 */
420 if (p_query_req->with_grh) {
421 OSM_LOG(p_log, OSM_LOG_DEBUG, "sending sa query with GRH "
422 "GID 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
423 cl_ntoh64(p_query_req->gid.unicast.prefix),
424 cl_ntoh64(p_query_req->gid.unicast.interface_id));
425 p_madw->mad_addr.addr_type.gsi.global_route = 1;
426 memset(&p_madw->mad_addr.addr_type.gsi.grh_info, 0,
427 sizeof(p_madw->mad_addr.addr_type.gsi.grh_info));
428 memcpy(&p_madw->mad_addr.addr_type.gsi.grh_info.dest_gid, &(p_query_req->gid), 16);
429 }
430
431 /*
432 Provide MAD context such that the call back will know what to do.
433 We have to keep the entire request structure so we know the CB.
434 Since we can not rely on the client to keep it around until
435 the response - we duplicate it and will later dispose it (in CB).
436 To store on the MADW we cast it into what opensm has:
437 p_madw->context.ni_context.node_guid
438 */
439 p_query_req_copy = malloc(sizeof(*p_query_req_copy));
440 if (!p_query_req_copy) {
441 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5511: "
442 "Unable to acquire memory for query copy\n");
443 osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
444 status = IB_INSUFFICIENT_RESOURCES;
445 goto Exit;
446 }
447 *p_query_req_copy = *p_query_req;
448 osm_madw_get_ni_context_ptr(p_madw)->node_guid =
449 (ib_net64_t) (uintptr_t)p_query_req_copy;
450
451 /* we can support async as well as sync calls */
452 sync = ((p_query_req->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC);
453
454 /* send the mad asynchronously */
455 status = osm_vendor_send(osm_madw_get_bind_handle(p_madw),
456 p_madw, p_madw->resp_expected);
457
458 /* if synchronous - wait on the event */
459 if (sync) {
460 OSM_LOG(p_log, OSM_LOG_DEBUG, "Waiting for async event\n");
461 cl_event_wait_on(&p_bind->sync_event, EVENT_NO_TIMEOUT, FALSE);
462 cl_event_reset(&p_bind->sync_event);
463 status = p_madw->status;
464 }
465
466 Exit:
467 OSM_LOG_EXIT(p_log);
468 return status;
469 }
470
471 /*
472 * Query the SA based on the user's request.
473 */
474 ib_api_status_t
osmv_query_sa(IN osm_bind_handle_t h_bind,IN const osmv_query_req_t * const p_query_req)475 osmv_query_sa(IN osm_bind_handle_t h_bind,
476 IN const osmv_query_req_t * const p_query_req)
477 {
478 union {
479 ib_service_record_t svc_rec;
480 ib_node_record_t node_rec;
481 ib_portinfo_record_t port_info;
482 ib_path_rec_t path_rec;
483 #ifdef DUAL_SIDED_RMPP
484 ib_multipath_rec_t multipath_rec;
485 #endif
486 ib_class_port_info_t class_port_info;
487 } u;
488 osmv_sa_mad_data_t sa_mad_data;
489 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) h_bind;
490 osmv_user_query_t *p_user_query;
491 #ifdef DUAL_SIDED_RMPP
492 osmv_multipath_req_t *p_mpr_req;
493 int i, j;
494 #endif
495 osm_log_t *p_log = p_bind->p_log;
496 ib_api_status_t status;
497
498 OSM_LOG_ENTER(p_log);
499
500 /* Set the request information. */
501 sa_mad_data.method = IB_MAD_METHOD_GETTABLE;
502 sa_mad_data.attr_mod = 0;
503 sa_mad_data.attr_offset = 0;
504
505 /* Set the MAD attributes and component mask correctly. */
506 switch (p_query_req->query_type) {
507
508 case OSMV_QUERY_USER_DEFINED:
509 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 USER_DEFINED\n");
510 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
511 if (p_user_query->method)
512 sa_mad_data.method = p_user_query->method;
513 #ifdef DUAL_SIDED_RMPP
514 if (sa_mad_data.method == IB_MAD_METHOD_GETMULTI ||
515 sa_mad_data.method == IB_MAD_METHOD_GETTRACETABLE)
516 sa_mad_data.attr_offset = p_user_query->attr_offset;
517 #endif
518 sa_mad_data.attr_id = p_user_query->attr_id;
519 sa_mad_data.attr_mod = p_user_query->attr_mod;
520 sa_mad_data.comp_mask = p_user_query->comp_mask;
521 sa_mad_data.p_attr = p_user_query->p_attr;
522 break;
523
524 case OSMV_QUERY_ALL_SVC_RECS:
525 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_NAME\n");
526 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
527 sa_mad_data.comp_mask = 0;
528 sa_mad_data.p_attr = &u.svc_rec;
529 break;
530
531 case OSMV_QUERY_SVC_REC_BY_NAME:
532 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_NAME\n");
533 sa_mad_data.method = IB_MAD_METHOD_GET;
534 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
535 sa_mad_data.comp_mask = IB_SR_COMPMASK_SNAME;
536 sa_mad_data.p_attr = &u.svc_rec;
537 memcpy(u.svc_rec.service_name, p_query_req->p_query_input,
538 sizeof(ib_svc_name_t));
539 break;
540
541 case OSMV_QUERY_SVC_REC_BY_ID:
542 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_ID\n");
543 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
544 sa_mad_data.comp_mask = IB_SR_COMPMASK_SID;
545 sa_mad_data.p_attr = &u.svc_rec;
546 u.svc_rec.service_id =
547 *(ib_net64_t *) (p_query_req->p_query_input);
548 break;
549
550 case OSMV_QUERY_CLASS_PORT_INFO:
551 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 CLASS_PORT_INFO\n");
552 sa_mad_data.method = IB_MAD_METHOD_GET;
553 sa_mad_data.attr_id = IB_MAD_ATTR_CLASS_PORT_INFO;
554 sa_mad_data.comp_mask = 0;
555 sa_mad_data.p_attr = &u.class_port_info;
556 break;
557
558 case OSMV_QUERY_NODE_REC_BY_NODE_GUID:
559 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 NODE_REC_BY_NODE_GUID\n");
560 sa_mad_data.attr_id = IB_MAD_ATTR_NODE_RECORD;
561 sa_mad_data.comp_mask = IB_NR_COMPMASK_NODEGUID;
562 sa_mad_data.p_attr = &u.node_rec;
563 u.node_rec.node_info.node_guid =
564 *(ib_net64_t *) (p_query_req->p_query_input);
565 break;
566
567 case OSMV_QUERY_PORT_REC_BY_LID:
568 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PORT_REC_BY_LID\n");
569 sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
570 sa_mad_data.comp_mask = IB_PIR_COMPMASK_LID;
571 sa_mad_data.p_attr = &u.port_info;
572 u.port_info.lid = *(ib_net16_t *) (p_query_req->p_query_input);
573 break;
574
575 case OSMV_QUERY_PORT_REC_BY_LID_AND_NUM:
576 sa_mad_data.method = IB_MAD_METHOD_GET;
577 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
578 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PORT_REC_BY_LID_AND_NUM\n");
579 sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
580 sa_mad_data.comp_mask =
581 IB_PIR_COMPMASK_LID | IB_PIR_COMPMASK_PORTNUM;
582 sa_mad_data.p_attr = p_user_query->p_attr;
583 break;
584
585 case OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK:
586 sa_mad_data.method = IB_MAD_METHOD_GET;
587 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
588 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n");
589 sa_mad_data.attr_id = IB_MAD_ATTR_VLARB_RECORD;
590 sa_mad_data.comp_mask =
591 IB_VLA_COMPMASK_LID | IB_VLA_COMPMASK_OUT_PORT |
592 IB_VLA_COMPMASK_BLOCK;
593 sa_mad_data.p_attr = p_user_query->p_attr;
594 break;
595
596 case OSMV_QUERY_SLVL_BY_LID_AND_PORTS:
597 sa_mad_data.method = IB_MAD_METHOD_GET;
598 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
599 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n");
600 sa_mad_data.attr_id = IB_MAD_ATTR_SLVL_RECORD;
601 sa_mad_data.comp_mask =
602 IB_SLVL_COMPMASK_LID | IB_SLVL_COMPMASK_OUT_PORT |
603 IB_SLVL_COMPMASK_IN_PORT;
604 sa_mad_data.p_attr = p_user_query->p_attr;
605 break;
606
607 case OSMV_QUERY_PATH_REC_BY_PORT_GUIDS:
608 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_PORT_GUIDS\n");
609 memset(&u.path_rec, 0, sizeof(ib_path_rec_t));
610 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
611 sa_mad_data.comp_mask =
612 (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID | IB_PR_COMPMASK_NUMBPATH);
613 u.path_rec.num_path = 0x7f;
614 sa_mad_data.p_attr = &u.path_rec;
615 ib_gid_set_default(&u.path_rec.dgid,
616 ((osmv_guid_pair_t *) (p_query_req->
617 p_query_input))->
618 dest_guid);
619 ib_gid_set_default(&u.path_rec.sgid,
620 ((osmv_guid_pair_t *) (p_query_req->
621 p_query_input))->
622 src_guid);
623 break;
624
625 case OSMV_QUERY_PATH_REC_BY_GIDS:
626 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_GIDS\n");
627 memset(&u.path_rec, 0, sizeof(ib_path_rec_t));
628 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
629 sa_mad_data.comp_mask =
630 (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID | IB_PR_COMPMASK_NUMBPATH);
631 u.path_rec.num_path = 0x7f;
632 sa_mad_data.p_attr = &u.path_rec;
633 memcpy(&u.path_rec.dgid,
634 &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
635 dest_gid,
636 sizeof(ib_gid_t));
637 memcpy(&u.path_rec.sgid,
638 &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
639 src_gid,
640 sizeof(ib_gid_t));
641 break;
642
643 case OSMV_QUERY_PATH_REC_BY_LIDS:
644 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_LIDS\n");
645 memset(&u.path_rec, 0, sizeof(ib_path_rec_t));
646 sa_mad_data.method = IB_MAD_METHOD_GET;
647 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
648 sa_mad_data.comp_mask =
649 (IB_PR_COMPMASK_DLID | IB_PR_COMPMASK_SLID);
650 sa_mad_data.p_attr = &u.path_rec;
651 u.path_rec.dlid =
652 ((osmv_lid_pair_t *) (p_query_req->p_query_input))->dest_lid;
653 u.path_rec.slid =
654 ((osmv_lid_pair_t *) (p_query_req->p_query_input))->src_lid;
655 break;
656
657 case OSMV_QUERY_UD_MULTICAST_SET:
658 sa_mad_data.method = IB_MAD_METHOD_SET;
659 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
660 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_UD_MULTICAST_SET\n");
661 sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
662 sa_mad_data.comp_mask = p_user_query->comp_mask;
663 sa_mad_data.p_attr = p_user_query->p_attr;
664 break;
665
666 case OSMV_QUERY_UD_MULTICAST_DELETE:
667 sa_mad_data.method = IB_MAD_METHOD_DELETE;
668 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
669 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_UD_MULTICAST_DELETE\n");
670 sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
671 sa_mad_data.comp_mask = p_user_query->comp_mask;
672 sa_mad_data.p_attr = p_user_query->p_attr;
673 break;
674
675 #ifdef DUAL_SIDED_RMPP
676 case OSMV_QUERY_MULTIPATH_REC:
677 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 MULTIPATH_REC\n");
678 /* Validate sgid/dgid counts against SA client limit */
679 p_mpr_req = (osmv_multipath_req_t *) p_query_req->p_query_input;
680 if (p_mpr_req->sgid_count + p_mpr_req->dgid_count >
681 IB_MULTIPATH_MAX_GIDS) {
682 OSM_LOG(p_log, OSM_LOG_ERROR, "DBG:001 MULTIPATH_REC "
683 "SGID count %d DGID count %d max count %d\n",
684 p_mpr_req->sgid_count, p_mpr_req->dgid_count,
685 IB_MULTIPATH_MAX_GIDS);
686 CL_ASSERT(0);
687 return IB_ERROR;
688 }
689 memset(&u.multipath_rec, 0, sizeof(ib_multipath_rec_t));
690 sa_mad_data.method = IB_MAD_METHOD_GETMULTI;
691 sa_mad_data.attr_id = IB_MAD_ATTR_MULTIPATH_RECORD;
692 sa_mad_data.attr_offset =
693 ib_get_attr_offset(sizeof(ib_multipath_rec_t));
694 sa_mad_data.p_attr = &u.multipath_rec;
695 sa_mad_data.comp_mask = p_mpr_req->comp_mask;
696 u.multipath_rec.num_path = p_mpr_req->num_path;
697 if (p_mpr_req->reversible)
698 u.multipath_rec.num_path |= 0x80;
699 else
700 u.multipath_rec.num_path &= ~0x80;
701 u.multipath_rec.pkey = p_mpr_req->pkey;
702 ib_multipath_rec_set_sl(&u.multipath_rec, p_mpr_req->sl);
703 ib_multipath_rec_set_qos_class(&u.multipath_rec, 0);
704 u.multipath_rec.independence = p_mpr_req->independence;
705 u.multipath_rec.sgid_count = p_mpr_req->sgid_count;
706 u.multipath_rec.dgid_count = p_mpr_req->dgid_count;
707 j = 0;
708 for (i = 0; i < p_mpr_req->sgid_count; i++, j++)
709 u.multipath_rec.gids[j] = p_mpr_req->gids[j];
710 for (i = 0; i < p_mpr_req->dgid_count; i++, j++)
711 u.multipath_rec.gids[j] = p_mpr_req->gids[j];
712 break;
713 #endif
714
715 default:
716 OSM_LOG(p_log, OSM_LOG_ERROR, "DBG:001 UNKNOWN\n");
717 CL_ASSERT(0);
718 return IB_ERROR;
719 }
720
721 status = __osmv_send_sa_req(h_bind, &sa_mad_data, p_query_req);
722
723 OSM_LOG_EXIT(p_log);
724 return status;
725 }
726