1 /*
2 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36 /*
37 * Abstract:
38 * Implementation of osm_req_t.
39 * This object represents the generic attribute requester.
40 * This object is part of the opensm family of objects.
41 *
42 */
43
44 /*
45 Next available error code: 0x300
46 */
47
48 #if HAVE_CONFIG_H
49 # include <config.h>
50 #endif /* HAVE_CONFIG_H */
51
52 #ifdef OSM_VENDOR_INTF_AL
53
54 #include <stdlib.h>
55 #include <string.h>
56 #include <complib/cl_qlist.h>
57 #include <complib/cl_thread.h>
58 #include <complib/cl_math.h>
59 #include <complib/cl_debug.h>
60 #include <iba/ib_types.h>
61 #include <opensm/osm_madw.h>
62 #include <opensm/osm_log.h>
63 #include <opensm/osm_mad_pool.h>
64 #include <vendor/osm_vendor_api.h>
65
66 /****s* OpenSM: Vendor AL/osm_al_bind_info_t
67 * NAME
68 * osm_al_bind_info_t
69 *
70 * DESCRIPTION
71 * Structure containing bind information.
72 *
73 * SYNOPSIS
74 */
75 typedef struct _osm_al_bind_info {
76 osm_vendor_t *p_vend;
77 void *client_context;
78 ib_qp_handle_t h_qp;
79 ib_mad_svc_handle_t h_svc;
80 uint8_t port_num;
81 ib_pool_key_t pool_key;
82 osm_vend_mad_recv_callback_t rcv_callback;
83 osm_vend_mad_send_err_callback_t send_err_callback;
84 osm_mad_pool_t *p_osm_pool;
85 ib_av_handle_t h_dr_av;
86
87 } osm_al_bind_info_t;
88 /*
89 * FIELDS
90 * p_vend
91 * Pointer to the vendor object.
92 *
93 * client_context
94 * User's context passed during osm_bind
95 *
96 * h_qp
97 * Handle the QP for this bind.
98 *
99 * h_qp_svc
100 * Handle the QP mad service for this bind.
101 *
102 * port_num
103 * Port number (within the HCA) of the bound port.
104 *
105 * pool_key
106 * Pool key returned by all for this QP.
107 *
108 * h_dr_av
109 * Address vector handle used for all directed route SMPs.
110 *
111 * SEE ALSO
112 *********/
113
114 inline static ib_api_status_t
__osm_al_convert_wcs(IN ib_wc_status_t const wc_status)115 __osm_al_convert_wcs(IN ib_wc_status_t const wc_status)
116 {
117 switch (wc_status) {
118 case IB_WCS_SUCCESS:
119 return (IB_SUCCESS);
120
121 case IB_WCS_TIMEOUT_RETRY_ERR:
122 return (IB_TIMEOUT);
123
124 default:
125 return (IB_ERROR);
126 }
127 }
128
__osm_al_ca_err_callback(IN ib_async_event_rec_t * p_async_rec)129 static void __osm_al_ca_err_callback(IN ib_async_event_rec_t * p_async_rec)
130 {
131 osm_vendor_t *p_vend = (osm_vendor_t *) p_async_rec->context;
132 OSM_LOG_ENTER(p_vend->p_log);
133
134 osm_log(p_vend->p_log, OSM_LOG_ERROR,
135 "__osm_al_ca_err_callback: ERR 3B01: "
136 "Event on channel adapter (%s).\n",
137 ib_get_async_event_str(p_async_rec->code));
138
139 OSM_LOG_EXIT(p_vend->p_log);
140 }
141
__osm_al_ca_destroy_callback(IN void * context)142 static void __osm_al_ca_destroy_callback(IN void *context)
143 {
144 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) context;
145 osm_vendor_t *p_vend = p_bind->p_vend;
146 OSM_LOG_ENTER(p_vend->p_log);
147
148 osm_log(p_vend->p_log, OSM_LOG_INFO,
149 "__osm_al_ca_destroy_callback: "
150 "Closing local channel adapter.\n");
151
152 OSM_LOG_EXIT(p_vend->p_log);
153 }
154
__osm_al_err_callback(IN ib_async_event_rec_t * p_async_rec)155 static void __osm_al_err_callback(IN ib_async_event_rec_t * p_async_rec)
156 {
157 osm_al_bind_info_t *p_bind =
158 (osm_al_bind_info_t *) p_async_rec->context;
159 osm_vendor_t *p_vend = p_bind->p_vend;
160 OSM_LOG_ENTER(p_vend->p_log);
161
162 osm_log(p_vend->p_log, OSM_LOG_ERROR,
163 "__osm_al_err_callback: ERR 3B02: "
164 "Error on QP (%s).\n",
165 ib_get_async_event_str(p_async_rec->code));
166
167 OSM_LOG_EXIT(p_vend->p_log);
168 }
169
170 static void
__osm_al_send_callback(IN void * mad_svc_context,IN ib_mad_element_t * p_elem)171 __osm_al_send_callback(IN void *mad_svc_context, IN ib_mad_element_t * p_elem)
172 {
173 osm_al_bind_info_t *const p_bind =
174 (osm_al_bind_info_t *) mad_svc_context;
175 osm_vendor_t *const p_vend = p_bind->p_vend;
176 osm_madw_t *const p_madw = (osm_madw_t *) p_elem->context1;
177 osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
178 ib_mad_t *p_mad;
179
180 OSM_LOG_ENTER(p_vend->p_log);
181
182 CL_ASSERT(p_vw);
183 CL_ASSERT(p_vw->h_av);
184
185 /*
186 Destroy the address vector as necessary.
187 */
188 if (p_vw->h_av != p_bind->h_dr_av) {
189 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
190 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
191 "__osm_al_send_callback: "
192 "Destroying av handle %p.\n", p_vw->h_av);
193 }
194
195 ib_destroy_av(p_vw->h_av);
196 }
197
198 p_mad = ib_get_mad_buf(p_elem);
199
200 if (p_elem->resp_expected) {
201 /*
202 If the send was unsuccessful, notify the user
203 for MADs that were expecting a response.
204 A NULL mad wrapper parameter is the user's clue
205 that the transaction turned sour.
206
207 Otherwise, do nothing for successful sends when a
208 reponse is expected. The mad will be returned to the
209 pool later.
210 */
211 p_madw->status = __osm_al_convert_wcs(p_elem->status);
212 if (p_elem->status != IB_WCS_SUCCESS) {
213 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
214 "__osm_al_send_callback: "
215 "MAD completed with work queue error: %s.\n",
216 ib_get_wc_status_str(p_elem->status));
217 /*
218 Return any wrappers to the pool that may have been
219 pre-emptively allocated to handle a receive.
220 */
221 if (p_vw->p_resp_madw) {
222 osm_mad_pool_put(p_bind->p_osm_pool,
223 p_vw->p_resp_madw);
224 p_vw->p_resp_madw = NULL;
225 }
226
227 p_bind->send_err_callback(p_bind->client_context,
228 p_madw);
229 }
230 } else {
231 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
232 "__osm_al_send_callback: "
233 "Returning MAD to pool, TID = 0x%" PRIx64 ".\n",
234 cl_ntoh64(p_mad->trans_id));
235 osm_mad_pool_put(p_bind->p_osm_pool, p_madw);
236 goto Exit;
237 }
238
239 Exit:
240 OSM_LOG_EXIT(p_vend->p_log);
241 }
242
243 static void
__osm_al_rcv_callback(IN void * mad_svc_context,IN ib_mad_element_t * p_elem)244 __osm_al_rcv_callback(IN void *mad_svc_context, IN ib_mad_element_t * p_elem)
245 {
246 osm_al_bind_info_t *const p_bind =
247 (osm_al_bind_info_t *) mad_svc_context;
248 osm_vendor_t *const p_vend = p_bind->p_vend;
249 osm_madw_t *p_old_madw;
250 osm_madw_t *p_new_madw;
251 osm_vend_wrap_t *p_old_vw;
252 osm_vend_wrap_t *p_new_vw;
253 ib_mad_t *p_new_mad;
254 osm_mad_addr_t mad_addr;
255
256 OSM_LOG_ENTER(p_vend->p_log);
257
258 CL_ASSERT(p_elem->context1 == NULL);
259 CL_ASSERT(p_elem->context2 == NULL);
260
261 p_new_mad = ib_get_mad_buf(p_elem);
262
263 /*
264 In preperation for initializing the new mad wrapper,
265 Initialize the mad_addr structure for the received wire MAD.
266 */
267 mad_addr.dest_lid = p_elem->remote_lid;
268 mad_addr.path_bits = p_elem->path_bits;
269
270 /* TO DO - figure out which #define to use for the 2.5 Gb rate... */
271 mad_addr.static_rate = 0;
272
273 if (p_new_mad->mgmt_class == IB_MCLASS_SUBN_LID ||
274 p_new_mad->mgmt_class == IB_MCLASS_SUBN_DIR) {
275 mad_addr.addr_type.smi.source_lid = p_elem->remote_lid;
276 } else {
277 mad_addr.addr_type.gsi.remote_qp = p_elem->remote_qp;
278 mad_addr.addr_type.gsi.remote_qkey = p_elem->remote_qkey;
279 mad_addr.addr_type.gsi.pkey_ix = p_elem->pkey_index;
280 mad_addr.addr_type.gsi.service_level = p_elem->remote_sl;
281 mad_addr.addr_type.gsi.global_route = FALSE;
282 }
283
284 /*
285 If this MAD is a response to a previous request,
286 then grab our pre-allocated MAD wrapper.
287 Otherwise, allocate a new MAD wrapper.
288 */
289 if (ib_mad_is_response(p_new_mad)) {
290 CL_ASSERT(p_elem->send_context1 != NULL);
291 CL_ASSERT(p_elem->send_context2 == NULL);
292
293 p_old_madw = (osm_madw_t *) p_elem->send_context1;
294 p_old_vw = osm_madw_get_vend_ptr(p_old_madw);
295 p_new_madw = p_old_vw->p_resp_madw;
296
297 CL_ASSERT(p_new_madw);
298
299 osm_madw_init(p_new_madw, p_bind, p_elem->size, &mad_addr);
300 osm_madw_set_mad(p_new_madw, p_new_mad);
301 } else {
302 CL_ASSERT(p_elem->send_context1 == NULL);
303 CL_ASSERT(p_elem->send_context2 == NULL);
304
305 p_new_madw = osm_mad_pool_get_wrapper(p_bind->p_osm_pool,
306 p_bind, p_elem->size,
307 p_new_mad, &mad_addr);
308 }
309
310 CL_ASSERT(p_new_madw);
311 p_new_vw = osm_madw_get_vend_ptr(p_new_madw);
312
313 p_new_vw->h_bind = p_bind;
314 p_new_vw->size = p_elem->size;
315 p_new_vw->p_elem = p_elem;
316 p_new_vw->h_av = 0;
317 p_new_vw->p_resp_madw = NULL;
318
319 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
320 "__osm_al_rcv_callback: "
321 "Calling receive callback function %p.\n",
322 p_bind->rcv_callback);
323
324 p_bind->rcv_callback(p_new_madw, p_bind->client_context,
325 p_elem->send_context1);
326
327 OSM_LOG_EXIT(p_vend->p_log);
328 }
329
330 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)331 osm_vendor_init(IN osm_vendor_t * const p_vend,
332 IN osm_log_t * const p_log, IN const uint32_t timeout)
333 {
334 ib_api_status_t status;
335 OSM_LOG_ENTER(p_log);
336
337 p_vend->p_log = p_log;
338
339 /*
340 Open our instance of AL.
341 */
342 status = ib_open_al(&p_vend->h_al);
343 if (status != IB_SUCCESS) {
344 osm_log(p_vend->p_log, OSM_LOG_ERROR,
345 "osm_vendor_init: ERR 3B03: "
346 "Error opening AL (%s).\n", ib_get_err_str(status));
347
348 goto Exit;
349 }
350
351 p_vend->timeout = timeout;
352
353 Exit:
354 OSM_LOG_EXIT(p_log);
355 return (status);
356 }
357
osm_vendor_new(IN osm_log_t * const p_log,IN const uint32_t timeout)358 osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
359 IN const uint32_t timeout)
360 {
361 ib_api_status_t status;
362 osm_vendor_t *p_vend;
363
364 OSM_LOG_ENTER(p_log);
365
366 p_vend = malloc(sizeof(*p_vend));
367 if (p_vend == NULL) {
368 osm_log(p_vend->p_log, OSM_LOG_ERROR,
369 "osm_vendor_new: ERR 3B04: "
370 "Unable to allocate vendor object.\n");
371 goto Exit;
372 }
373
374 memset(p_vend, 0, sizeof(*p_vend));
375
376 status = osm_vendor_init(p_vend, p_log, timeout);
377 if (status != IB_SUCCESS) {
378 free(p_vend);
379 p_vend = NULL;
380 }
381
382 Exit:
383 OSM_LOG_EXIT(p_log);
384 return (p_vend);
385 }
386
osm_vendor_delete(IN osm_vendor_t ** const pp_vend)387 void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
388 {
389 /* TO DO - fill this in */
390 ib_close_al((*pp_vend)->h_al);
391 free(*pp_vend);
392 *pp_vend = NULL;
393 }
394
395 static ib_api_status_t
__osm_ca_info_init(IN osm_vendor_t * const p_vend,IN osm_ca_info_t * const p_ca_info,IN const ib_net64_t ca_guid)396 __osm_ca_info_init(IN osm_vendor_t * const p_vend,
397 IN osm_ca_info_t * const p_ca_info,
398 IN const ib_net64_t ca_guid)
399 {
400 ib_api_status_t status;
401
402 OSM_LOG_ENTER(p_vend->p_log);
403
404 p_ca_info->guid = ca_guid;
405
406 if (osm_log_is_active(p_vend->p_log, OSM_LOG_VERBOSE)) {
407 osm_log(p_vend->p_log, OSM_LOG_VERBOSE,
408 "__osm_ca_info_init: "
409 "Querying CA 0x%" PRIx64 ".\n", cl_ntoh64(ca_guid));
410 }
411
412 status = ib_query_ca_by_guid(p_vend->h_al, ca_guid, NULL,
413 &p_ca_info->attr_size);
414 if ((status != IB_INSUFFICIENT_MEMORY) && (status != IB_SUCCESS)) {
415 osm_log(p_vend->p_log, OSM_LOG_ERROR,
416 "__osm_ca_info_init: ERR 3B05: "
417 "Unexpected status getting CA attributes (%s).\n",
418 ib_get_err_str(status));
419 goto Exit;
420 }
421
422 CL_ASSERT(p_ca_info->attr_size);
423
424 p_ca_info->p_attr = malloc(p_ca_info->attr_size);
425 if (p_ca_info->p_attr == NULL) {
426 osm_log(p_vend->p_log, OSM_LOG_ERROR,
427 "__osm_ca_info_init: ERR 3B06: "
428 "Unable to allocate attribute storage.\n");
429 goto Exit;
430 }
431
432 status = ib_query_ca_by_guid(p_vend->h_al, ca_guid, p_ca_info->p_attr,
433 &p_ca_info->attr_size);
434 if (status != IB_SUCCESS) {
435 osm_log(p_vend->p_log, OSM_LOG_ERROR,
436 "__osm_ca_info_init: ERR 3B07: "
437 "Unexpected status getting CA attributes (%s).\n",
438 ib_get_err_str(status));
439 goto Exit;
440 }
441
442 Exit:
443 OSM_LOG_EXIT(p_vend->p_log);
444 return (status);
445 }
446
447 void
osm_ca_info_destroy(IN osm_vendor_t * const p_vend,IN osm_ca_info_t * const p_ca_info)448 osm_ca_info_destroy(IN osm_vendor_t * const p_vend,
449 IN osm_ca_info_t * const p_ca_info)
450 {
451 OSM_LOG_ENTER(p_vend->p_log);
452
453 if (p_ca_info->p_attr)
454 free(p_ca_info->p_attr);
455
456 free(p_ca_info);
457
458 OSM_LOG_EXIT(p_vend->p_log);
459 }
460
osm_ca_info_new(IN osm_vendor_t * const p_vend,IN const ib_net64_t ca_guid)461 osm_ca_info_t *osm_ca_info_new(IN osm_vendor_t * const p_vend,
462 IN const ib_net64_t ca_guid)
463 {
464 ib_api_status_t status;
465 osm_ca_info_t *p_ca_info;
466
467 OSM_LOG_ENTER(p_vend->p_log);
468
469 CL_ASSERT(ca_guid);
470
471 p_ca_info = malloc(sizeof(*p_ca_info));
472 if (p_ca_info == NULL)
473 goto Exit;
474
475 memset(p_ca_info, 0, sizeof(*p_ca_info));
476
477 status = __osm_ca_info_init(p_vend, p_ca_info, ca_guid);
478 if (status != IB_SUCCESS) {
479 osm_ca_info_destroy(p_vend, p_ca_info);
480 p_ca_info = NULL;
481 goto Exit;
482 }
483
484 Exit:
485 OSM_LOG_EXIT(p_vend->p_log);
486 return (p_ca_info);
487 }
488
489 static ib_api_status_t
__osm_vendor_get_ca_guids(IN osm_vendor_t * const p_vend,IN ib_net64_t ** const p_guids,IN unsigned * const p_num_guids)490 __osm_vendor_get_ca_guids(IN osm_vendor_t * const p_vend,
491 IN ib_net64_t ** const p_guids,
492 IN unsigned * const p_num_guids)
493 {
494 ib_api_status_t status;
495
496 OSM_LOG_ENTER(p_vend->p_log);
497
498 CL_ASSERT(p_guids);
499 CL_ASSERT(p_num_guids);
500
501 status = ib_get_ca_guids(p_vend->h_al, NULL, p_num_guids);
502 if ((status != IB_INSUFFICIENT_MEMORY) && (status != IB_SUCCESS)) {
503 osm_log(p_vend->p_log, OSM_LOG_ERROR,
504 "__osm_vendor_get_ca_guids: ERR 3B08: "
505 "Unexpected status getting CA GUID array (%s).\n",
506 ib_get_err_str(status));
507 goto Exit;
508 }
509
510 if (*p_num_guids == 0) {
511 osm_log(p_vend->p_log, OSM_LOG_ERROR,
512 "__osm_vendor_get_ca_guids: ERR 3B09: "
513 "No available channel adapters.\n");
514 status = IB_INSUFFICIENT_RESOURCES;
515 goto Exit;
516 }
517
518 *p_guids = malloc(*p_num_guids * sizeof(**p_guids));
519 if (*p_guids == NULL) {
520 osm_log(p_vend->p_log, OSM_LOG_ERROR,
521 "__osm_vendor_get_ca_guids: ERR 3B10: "
522 "Unable to allocate CA GUID array.\n");
523 goto Exit;
524 }
525
526 status = ib_get_ca_guids(p_vend->h_al, *p_guids, p_num_guids);
527 CL_ASSERT(*p_num_guids);
528
529 if (osm_log_is_active(p_vend->p_log, OSM_LOG_VERBOSE)) {
530 osm_log(p_vend->p_log, OSM_LOG_VERBOSE,
531 "__osm_vendor_get_ca_guids: "
532 "Detected %u local channel adapters.\n", *p_num_guids);
533 }
534
535 Exit:
536 OSM_LOG_EXIT(p_vend->p_log);
537 return (status);
538 }
539
540 /****f* OpenSM: CA Info/osm_ca_info_get_pi_ptr
541 * NAME
542 * osm_ca_info_get_pi_ptr
543 *
544 * DESCRIPTION
545 * Returns a pointer to the port attribute of the specified port
546 * owned by this CA.
547 *
548 * SYNOPSIS
549 */
__osm_ca_info_get_port_attr_ptr(IN const osm_ca_info_t * const p_ca_info,IN const uint8_t index)550 static ib_port_attr_t *__osm_ca_info_get_port_attr_ptr(IN const osm_ca_info_t *
551 const p_ca_info,
552 IN const uint8_t index)
553 {
554 return (&p_ca_info->p_attr->p_port_attr[index]);
555 }
556
557 /*
558 * PARAMETERS
559 * p_ca_info
560 * [in] Pointer to a CA Info object.
561 *
562 * index
563 * [in] Port "index" for which to retrieve the port attribute.
564 * The index is the offset into the ca's internal array
565 * of port attributes.
566 *
567 * RETURN VALUE
568 * Returns a pointer to the port attribute of the specified port
569 * owned by this CA.
570 *
571 * NOTES
572 *
573 * SEE ALSO
574 *********/
575
576 ib_api_status_t
osm_vendor_get_all_port_attr(IN osm_vendor_t * const p_vend,IN ib_port_attr_t * const p_attr_array,IN uint32_t * const p_num_ports)577 osm_vendor_get_all_port_attr(IN osm_vendor_t * const p_vend,
578 IN ib_port_attr_t * const p_attr_array,
579 IN uint32_t * const p_num_ports)
580 {
581 ib_api_status_t status;
582
583 uint32_t ca;
584 unsigned ca_count;
585 uint32_t port_count = 0;
586 uint8_t port_num;
587 uint32_t total_ports = 0;
588 ib_net64_t *p_ca_guid = NULL;
589 osm_ca_info_t *p_ca_info;
590
591 OSM_LOG_ENTER(p_vend->p_log);
592
593 CL_ASSERT(p_vend);
594 CL_ASSERT(p_vend->p_ca_info == NULL);
595
596 /*
597 1) Determine the number of CA's
598 2) Allocate an array big enough to hold the ca info objects.
599 3) Call again to retrieve the guids.
600 */
601 status = __osm_vendor_get_ca_guids(p_vend, &p_ca_guid, &ca_count);
602
603 p_vend->p_ca_info = malloc(ca_count * sizeof(*p_vend->p_ca_info));
604 if (p_vend->p_ca_info == NULL) {
605 osm_log(p_vend->p_log, OSM_LOG_ERROR,
606 "osm_vendor_get_all_port_attr: ERR 3B11: "
607 "Unable to allocate CA information array.\n");
608 goto Exit;
609 }
610
611 memset(p_vend->p_ca_info, 0, ca_count * sizeof(*p_vend->p_ca_info));
612 p_vend->ca_count = ca_count;
613
614 /*
615 For each CA, retrieve the port info attributes
616 */
617 for (ca = 0; ca < ca_count; ca++) {
618 p_ca_info = &p_vend->p_ca_info[ca];
619
620 status = __osm_ca_info_init(p_vend, p_ca_info, p_ca_guid[ca]);
621
622 if (status != IB_SUCCESS) {
623 osm_log(p_vend->p_log, OSM_LOG_ERROR,
624 "osm_vendor_get_all_port_attr: ERR 3B12: "
625 "Unable to initialize CA Info object (%s).\n",
626 ib_get_err_str(status));
627 }
628
629 total_ports += osm_ca_info_get_num_ports(p_ca_info);
630 }
631
632 /*
633 If the user supplied enough storage, return the port guids,
634 otherwise, return the appropriate error.
635 */
636 if (*p_num_ports >= total_ports) {
637 for (ca = 0; ca < ca_count; ca++) {
638 uint32_t num_ports;
639
640 p_ca_info = &p_vend->p_ca_info[ca];
641
642 num_ports = osm_ca_info_get_num_ports(p_ca_info);
643
644 for (port_num = 0; port_num < num_ports; port_num++) {
645 p_attr_array[port_count] =
646 *__osm_ca_info_get_port_attr_ptr(p_ca_info,
647 port_num);
648 port_count++;
649 }
650 }
651 } else {
652 status = IB_INSUFFICIENT_MEMORY;
653 }
654
655 *p_num_ports = total_ports;
656
657 Exit:
658 if (p_ca_guid)
659 free(p_ca_guid);
660
661 OSM_LOG_EXIT(p_vend->p_log);
662 return (status);
663 }
664
665 ib_net64_t
osm_vendor_get_ca_guid(IN osm_vendor_t * const p_vend,IN const ib_net64_t port_guid)666 osm_vendor_get_ca_guid(IN osm_vendor_t * const p_vend,
667 IN const ib_net64_t port_guid)
668 {
669 uint8_t index;
670 uint8_t num_ports;
671 uint32_t num_guids = 0;
672 osm_ca_info_t *p_ca_info;
673 uint32_t ca;
674
675 OSM_LOG_ENTER(p_vend->p_log);
676
677 CL_ASSERT(port_guid);
678 /*
679 First, locate the HCA that owns this port.
680 */
681 if (p_vend->p_ca_info == NULL) {
682 /*
683 Initialize the osm_ca_info_t array which allows
684 us to match port GUID to CA.
685 */
686 osm_vendor_get_all_port_attr(p_vend, NULL, &num_guids);
687 }
688
689 CL_ASSERT(p_vend->p_ca_info);
690 CL_ASSERT(p_vend->ca_count);
691
692 for (ca = 0; ca < p_vend->ca_count; ca++) {
693 p_ca_info = &p_vend->p_ca_info[ca];
694
695 num_ports = osm_ca_info_get_num_ports(p_ca_info);
696 CL_ASSERT(num_ports);
697
698 for (index = 0; index < num_ports; index++) {
699 if (port_guid ==
700 osm_ca_info_get_port_guid(p_ca_info, index)) {
701 OSM_LOG_EXIT(p_vend->p_log);
702 return (osm_ca_info_get_ca_guid(p_ca_info));
703 }
704 }
705 }
706
707 /*
708 No local CA owns this guid!
709 */
710 osm_log(p_vend->p_log, OSM_LOG_ERROR,
711 "osm_vendor_get_ca_guid: ERR 3B13: "
712 "Unable to determine CA guid.\n");
713
714 OSM_LOG_EXIT(p_vend->p_log);
715 return (0);
716 }
717
718 uint8_t
osm_vendor_get_port_num(IN osm_vendor_t * const p_vend,IN const ib_net64_t port_guid)719 osm_vendor_get_port_num(IN osm_vendor_t * const p_vend,
720 IN const ib_net64_t port_guid)
721 {
722 uint8_t index;
723 uint8_t num_ports;
724 uint32_t num_guids = 0;
725 osm_ca_info_t *p_ca_info;
726 uint32_t ca;
727
728 OSM_LOG_ENTER(p_vend->p_log);
729
730 CL_ASSERT(port_guid);
731 /*
732 First, locate the HCA that owns this port.
733 */
734 if (p_vend->p_ca_info == NULL) {
735 /*
736 Initialize the osm_ca_info_t array which allows
737 us to match port GUID to CA.
738 */
739 osm_vendor_get_all_port_attr(p_vend, NULL, &num_guids);
740 }
741
742 CL_ASSERT(p_vend->p_ca_info);
743 CL_ASSERT(p_vend->ca_count);
744
745 for (ca = 0; ca < p_vend->ca_count; ca++) {
746 p_ca_info = &p_vend->p_ca_info[ca];
747
748 num_ports = osm_ca_info_get_num_ports(p_ca_info);
749 CL_ASSERT(num_ports);
750
751 for (index = 0; index < num_ports; index++) {
752 if (port_guid ==
753 osm_ca_info_get_port_guid(p_ca_info, index)) {
754 OSM_LOG_EXIT(p_vend->p_log);
755 return (osm_ca_info_get_port_num
756 (p_ca_info, index));
757 }
758 }
759 }
760
761 /*
762 No local CA owns this guid!
763 */
764 osm_log(p_vend->p_log, OSM_LOG_ERROR,
765 "osm_vendor_get_port_num: ERR 3B30: "
766 "Unable to determine CA guid.\n");
767
768 OSM_LOG_EXIT(p_vend->p_log);
769 return (0);
770 }
771
772 static ib_api_status_t
__osm_vendor_open_ca(IN osm_vendor_t * const p_vend,IN const ib_net64_t port_guid)773 __osm_vendor_open_ca(IN osm_vendor_t * const p_vend,
774 IN const ib_net64_t port_guid)
775 {
776 ib_net64_t ca_guid;
777 ib_api_status_t status;
778
779 OSM_LOG_ENTER(p_vend->p_log);
780
781 ca_guid = osm_vendor_get_ca_guid(p_vend, port_guid);
782 if (ca_guid == 0) {
783 osm_log(p_vend->p_log, OSM_LOG_ERROR,
784 "__osm_vendor_open_ca: ERR 3B31: "
785 "Bad port GUID value 0x%" PRIx64 ".\n",
786 cl_ntoh64(port_guid));
787 status = IB_ERROR;
788 goto Exit;
789 }
790
791 osm_log(p_vend->p_log, OSM_LOG_VERBOSE,
792 "__osm_vendor_open_ca: "
793 "Opening HCA 0x%" PRIx64 ".\n", cl_ntoh64(ca_guid));
794
795 status = ib_open_ca(p_vend->h_al,
796 ca_guid,
797 __osm_al_ca_err_callback, p_vend, &p_vend->h_ca);
798
799 if (status != IB_SUCCESS) {
800 osm_log(p_vend->p_log, OSM_LOG_ERROR,
801 "__osm_vendor_open_ca: ERR 3B15: "
802 "Unable to open CA (%s).\n", ib_get_err_str(status));
803 goto Exit;
804 }
805
806 CL_ASSERT(p_vend->h_ca);
807
808 status = ib_alloc_pd(p_vend->h_ca, IB_PDT_ALIAS, p_vend, &p_vend->h_pd);
809
810 if (status != IB_SUCCESS) {
811 ib_close_ca(p_vend->h_ca, __osm_al_ca_destroy_callback);
812 osm_log(p_vend->p_log, OSM_LOG_ERROR,
813 "__osm_vendor_open_ca: ERR 3B16: "
814 "Unable to allocate protection domain (%s).\n",
815 ib_get_err_str(status));
816 goto Exit;
817 }
818
819 CL_ASSERT(p_vend->h_pd);
820
821 Exit:
822 OSM_LOG_EXIT(p_vend->p_log);
823 return (status);
824 }
825
826 static void
__osm_vendor_init_av(IN const osm_al_bind_info_t * p_bind,IN ib_av_attr_t * p_av)827 __osm_vendor_init_av(IN const osm_al_bind_info_t * p_bind,
828 IN ib_av_attr_t * p_av)
829 {
830 memset(p_av, 0, sizeof(*p_av));
831 p_av->port_num = p_bind->port_num;
832 p_av->dlid = IB_LID_PERMISSIVE;
833 }
834
835 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)836 osm_vendor_bind(IN osm_vendor_t * const p_vend,
837 IN osm_bind_info_t * const p_user_bind,
838 IN osm_mad_pool_t * const p_mad_pool,
839 IN osm_vend_mad_recv_callback_t mad_recv_callback,
840 IN osm_vend_mad_send_err_callback_t send_err_callback,
841 IN void *context)
842 {
843 ib_net64_t port_guid;
844 osm_al_bind_info_t *p_bind = 0;
845 ib_api_status_t status;
846 ib_qp_create_t qp_create;
847 ib_mad_svc_t mad_svc;
848 ib_av_attr_t av;
849
850 OSM_LOG_ENTER(p_vend->p_log);
851
852 CL_ASSERT(p_user_bind);
853 CL_ASSERT(p_mad_pool);
854 CL_ASSERT(mad_recv_callback);
855 CL_ASSERT(send_err_callback);
856
857 port_guid = p_user_bind->port_guid;
858
859 osm_log(p_vend->p_log, OSM_LOG_INFO,
860 "osm_vendor_bind: "
861 "Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid));
862
863 if (p_vend->h_ca == 0) {
864 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
865 "osm_vendor_bind: "
866 "Opening CA that owns port 0x%" PRIx64 ".\n",
867 port_guid);
868
869 status = __osm_vendor_open_ca(p_vend, port_guid);
870 if (status != IB_SUCCESS) {
871 osm_log(p_vend->p_log, OSM_LOG_ERROR,
872 "osm_vendor_bind: ERR 3B17: "
873 "Unable to Open CA (%s).\n",
874 ib_get_err_str(status));
875 goto Exit;
876 }
877 }
878
879 p_bind = malloc(sizeof(*p_bind));
880 if (p_bind == NULL) {
881 osm_log(p_vend->p_log, OSM_LOG_ERROR,
882 "osm_vendor_bind: ERR 3B18: "
883 "Unable to allocate internal bind object.\n");
884 goto Exit;
885 }
886
887 memset(p_bind, 0, sizeof(*p_bind));
888 p_bind->p_vend = p_vend;
889 p_bind->client_context = context;
890 p_bind->port_num = osm_vendor_get_port_num(p_vend, port_guid);
891 p_bind->rcv_callback = mad_recv_callback;
892 p_bind->send_err_callback = send_err_callback;
893 p_bind->p_osm_pool = p_mad_pool;
894
895 CL_ASSERT(p_bind->port_num);
896
897 /*
898 Get the proper QP.
899 */
900 memset(&qp_create, 0, sizeof(qp_create));
901
902 switch (p_user_bind->mad_class) {
903 case IB_MCLASS_SUBN_LID:
904 case IB_MCLASS_SUBN_DIR:
905 qp_create.qp_type = IB_QPT_QP0_ALIAS;
906 break;
907
908 case IB_MCLASS_SUBN_ADM:
909 default:
910 qp_create.qp_type = IB_QPT_QP1_ALIAS;
911 break;
912 }
913
914 qp_create.sq_depth = p_user_bind->send_q_size;
915 qp_create.rq_depth = p_user_bind->recv_q_size;
916 qp_create.sq_sge = OSM_AL_SQ_SGE;
917 qp_create.rq_sge = OSM_AL_RQ_SGE;
918
919 status = ib_get_spl_qp(p_vend->h_pd,
920 port_guid,
921 &qp_create,
922 p_bind,
923 __osm_al_err_callback,
924 &p_bind->pool_key, &p_bind->h_qp);
925
926 if (status != IB_SUCCESS) {
927 free(p_bind);
928 osm_log(p_vend->p_log, OSM_LOG_ERROR,
929 "osm_vendor_bind: ERR 3B19: "
930 "Unable to get QP handle (%s).\n",
931 ib_get_err_str(status));
932 goto Exit;
933 }
934
935 CL_ASSERT(p_bind->h_qp);
936 CL_ASSERT(p_bind->pool_key);
937
938 memset(&mad_svc, 0, sizeof(mad_svc));
939
940 mad_svc.mad_svc_context = p_bind;
941 mad_svc.pfn_mad_send_cb = __osm_al_send_callback;
942 mad_svc.pfn_mad_recv_cb = __osm_al_rcv_callback;
943 mad_svc.mgmt_class = p_user_bind->mad_class;
944 mad_svc.mgmt_version = p_user_bind->class_version;
945 mad_svc.support_unsol = p_user_bind->is_responder;
946 mad_svc.method_array[IB_MAD_METHOD_GET] = TRUE;
947 mad_svc.method_array[IB_MAD_METHOD_SET] = TRUE;
948 mad_svc.method_array[IB_MAD_METHOD_DELETE] = TRUE;
949 mad_svc.method_array[IB_MAD_METHOD_TRAP] = TRUE;
950 mad_svc.method_array[IB_MAD_METHOD_GETTABLE] = TRUE;
951
952 status = ib_reg_mad_svc(p_bind->h_qp, &mad_svc, &p_bind->h_svc);
953
954 if (status != IB_SUCCESS) {
955 free(p_bind);
956 osm_log(p_vend->p_log, OSM_LOG_ERROR,
957 "osm_vendor_bind: ERR 3B21: "
958 "Unable to register QP0 MAD service (%s).\n",
959 ib_get_err_str(status));
960 goto Exit;
961 }
962
963 __osm_vendor_init_av(p_bind, &av);
964
965 status = ib_create_av(p_vend->h_pd, &av, &p_bind->h_dr_av);
966 if (status != IB_SUCCESS) {
967 osm_log(p_vend->p_log, OSM_LOG_ERROR,
968 "osm_vendor_bind: ERR 3B22: "
969 "Unable to create address vector (%s).\n",
970 ib_get_err_str(status));
971
972 goto Exit;
973 }
974
975 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
976 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
977 "osm_vendor_bind: "
978 "Allocating av handle %p.\n", p_bind->h_dr_av);
979 }
980
981 Exit:
982 OSM_LOG_EXIT(p_vend->p_log);
983 return ((osm_bind_handle_t) p_bind);
984 }
985
osm_vendor_get(IN osm_bind_handle_t h_bind,IN const uint32_t mad_size,IN osm_vend_wrap_t * const p_vw)986 ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
987 IN const uint32_t mad_size,
988 IN osm_vend_wrap_t * const p_vw)
989 {
990 ib_mad_t *p_mad;
991 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind;
992 osm_vendor_t *p_vend = p_bind->p_vend;
993 ib_api_status_t status;
994
995 OSM_LOG_ENTER(p_vend->p_log);
996
997 CL_ASSERT(p_vw);
998
999 p_vw->size = mad_size;
1000 p_vw->h_bind = h_bind;
1001
1002 /*
1003 Retrieve a MAD element from the pool and give the user direct
1004 access to its buffer.
1005 */
1006 status = ib_get_mad(p_bind->pool_key, mad_size, &p_vw->p_elem);
1007 if (status != IB_SUCCESS) {
1008 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1009 "osm_vendor_get: ERR 3B25: "
1010 "Unable to acquire MAD (%s).\n",
1011 ib_get_err_str(status));
1012
1013 p_mad = NULL;
1014 goto Exit;
1015 }
1016
1017 CL_ASSERT(p_vw->p_elem);
1018 p_mad = ib_get_mad_buf(p_vw->p_elem);
1019
1020 if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
1021 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1022 "osm_vendor_get: "
1023 "Acquired MAD %p, size = %u.\n", p_mad, mad_size);
1024 }
1025
1026 Exit:
1027 OSM_LOG_EXIT(p_vend->p_log);
1028 return (p_mad);
1029 }
1030
1031 void
osm_vendor_put(IN osm_bind_handle_t h_bind,IN osm_vend_wrap_t * const p_vw)1032 osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw)
1033 {
1034 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind;
1035 osm_vendor_t *p_vend = p_bind->p_vend;
1036 ib_api_status_t status;
1037
1038 OSM_LOG_ENTER(p_vend->p_log);
1039
1040 CL_ASSERT(p_vw);
1041 CL_ASSERT(p_vw->p_elem);
1042 CL_ASSERT(p_vw->h_bind == h_bind);
1043
1044 if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
1045 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1046 "osm_vendor_put: "
1047 "Retiring MAD %p.\n", ib_get_mad_buf(p_vw->p_elem));
1048 }
1049
1050 status = ib_put_mad(p_vw->p_elem);
1051 if (status != IB_SUCCESS) {
1052 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1053 "osm_vendor_put: ERR 3B26: "
1054 "Unable to retire MAD (%s).\n", ib_get_err_str(status));
1055 }
1056
1057 OSM_LOG_EXIT(p_vend->p_log);
1058 }
1059
1060 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)1061 osm_vendor_send(IN osm_bind_handle_t h_bind,
1062 IN osm_madw_t * const p_madw, IN boolean_t const resp_expected)
1063 {
1064 osm_al_bind_info_t *const p_bind = h_bind;
1065 osm_vendor_t *const p_vend = p_bind->p_vend;
1066 osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
1067 osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
1068 ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw);
1069 ib_api_status_t status;
1070 ib_mad_element_t *p_elem;
1071 ib_av_attr_t av;
1072
1073 OSM_LOG_ENTER(p_vend->p_log);
1074
1075 CL_ASSERT(p_vw->h_bind == h_bind);
1076 CL_ASSERT(p_vw->p_elem);
1077
1078 p_elem = p_vw->p_elem;
1079
1080 /*
1081 If a response is expected to this MAD, then preallocate
1082 a mad wrapper to contain the wire MAD received in the
1083 response. Allocating a wrapper here allows for easier
1084 failure paths than after we already received the wire mad.
1085 */
1086 if (resp_expected) {
1087 p_vw->p_resp_madw =
1088 osm_mad_pool_get_wrapper_raw(p_bind->p_osm_pool);
1089 if (p_vw->p_resp_madw == NULL) {
1090 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1091 "osm_vendor_send: ERR 3B27: "
1092 "Unable to allocate MAD wrapper.\n");
1093 status = IB_INSUFFICIENT_RESOURCES;
1094 goto Exit;
1095 }
1096 } else
1097 p_vw->p_resp_madw = NULL;
1098
1099 /*
1100 For all sends other than directed route SM MADs,
1101 acquire an address vector for the destination.
1102 */
1103 if (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) {
1104 memset(&av, 0, sizeof(av));
1105 av.port_num = p_bind->port_num;
1106 av.dlid = p_mad_addr->dest_lid;
1107 av.static_rate = p_mad_addr->static_rate;
1108 av.path_bits = p_mad_addr->path_bits;
1109
1110 if ((p_mad->mgmt_class != IB_MCLASS_SUBN_LID) &&
1111 (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR)) {
1112 av.sl = p_mad_addr->addr_type.gsi.service_level;
1113
1114 if (p_mad_addr->addr_type.gsi.global_route) {
1115 av.grh_valid = TRUE;
1116 /* ANIL */
1117 /* av.grh = p_mad_addr->addr_type.gsi.grh_info; */
1118 }
1119 }
1120
1121 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
1122 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1123 "osm_vendor_send: "
1124 "av.port_num 0x%X, "
1125 "av.dlid 0x%X, "
1126 "av.static_rate %d, "
1127 "av.path_bits %d.\n",
1128 av.port_num, cl_ntoh16(av.dlid),
1129 av.static_rate, av.path_bits);
1130 }
1131
1132 status = ib_create_av(p_vend->h_pd, &av, &p_vw->h_av);
1133 if (status != IB_SUCCESS) {
1134 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1135 "osm_vendor_send: ERR 3B28: "
1136 "Unable to create address vector (%s).\n",
1137 ib_get_err_str(status));
1138
1139 if (p_vw->p_resp_madw)
1140 osm_mad_pool_put(p_bind->p_osm_pool,
1141 p_vw->p_resp_madw);
1142 goto Exit;
1143 }
1144
1145 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
1146 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1147 "osm_vendor_send: "
1148 "Allocating av handle %p.\n", p_vw->h_av);
1149 }
1150 } else {
1151 p_vw->h_av = p_bind->h_dr_av;
1152 }
1153
1154 p_elem->h_av = p_vw->h_av;
1155
1156 p_elem->context1 = p_madw;
1157 p_elem->context2 = NULL;
1158
1159 p_elem->immediate_data = 0;
1160 p_elem->p_grh = NULL;
1161 p_elem->resp_expected = resp_expected;
1162 p_elem->retry_cnt = OSM_DEFAULT_RETRY_COUNT;
1163
1164 p_elem->send_opt = IB_SEND_OPT_SIGNALED;
1165 p_elem->timeout_ms = p_vend->timeout;
1166
1167 /* Completion information. */
1168 p_elem->status = 0; /* Not trusting AL */
1169
1170 if ((p_mad->mgmt_class == IB_MCLASS_SUBN_LID) ||
1171 (p_mad->mgmt_class == IB_MCLASS_SUBN_DIR)) {
1172 p_elem->remote_qp = 0;
1173 p_elem->remote_qkey = 0;
1174 } else {
1175 p_elem->remote_qp = p_mad_addr->addr_type.gsi.remote_qp;
1176 p_elem->remote_qkey = p_mad_addr->addr_type.gsi.remote_qkey;
1177 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1178 "osm_vendor_send: "
1179 "remote qp = 0x%X, remote qkey = 0x%X.\n",
1180 cl_ntoh32(p_elem->remote_qp),
1181 cl_ntoh32(p_elem->remote_qkey));
1182 }
1183
1184 status = ib_send_mad(p_bind->h_svc, p_elem, NULL);
1185 if (status != IB_SUCCESS) {
1186 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1187 "osm_vendor_send: ERR 3B29: "
1188 "Send failed (%s).\n", ib_get_err_str(status));
1189 if (p_vw->p_resp_madw)
1190 osm_mad_pool_put(p_bind->p_osm_pool, p_vw->p_resp_madw);
1191 goto Exit;
1192 }
1193
1194 Exit:
1195 OSM_LOG_EXIT(p_vend->p_log);
1196 return (status);
1197 }
1198
osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)1199 ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)
1200 {
1201 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind;
1202 osm_vendor_t *p_vend = p_bind->p_vend;
1203 ib_av_attr_t av;
1204 ib_api_status_t status;
1205
1206 OSM_LOG_ENTER(p_vend->p_log);
1207
1208 /*
1209 The only thing we need to do is refresh the directed
1210 route address vector.
1211 */
1212 __osm_vendor_init_av(p_bind, &av);
1213
1214 status = ib_destroy_av(p_bind->h_dr_av);
1215 if (status != IB_SUCCESS) {
1216 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1217 "osm_vendor_local_lid_change: ERR 3B32: "
1218 "Unable to destroy address vector (%s).\n",
1219 ib_get_err_str(status));
1220
1221 goto Exit;
1222 }
1223
1224 status = ib_create_av(p_vend->h_pd, &av, &p_bind->h_dr_av);
1225 if (status != IB_SUCCESS) {
1226 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1227 "osm_vendor_local_lid_change: ERR 3B33: "
1228 "Unable to create address vector (%s).\n",
1229 ib_get_err_str(status));
1230
1231 goto Exit;
1232 }
1233
1234 Exit:
1235 OSM_LOG_EXIT(p_vend->p_log);
1236 return (status);
1237 }
1238
osm_vendor_set_sm(IN osm_bind_handle_t h_bind,IN boolean_t is_sm_val)1239 void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
1240 {
1241 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind;
1242 osm_vendor_t *p_vend = p_bind->p_vend;
1243 ib_api_status_t status;
1244 ib_port_attr_mod_t attr_mod;
1245
1246 OSM_LOG_ENTER(p_vend->p_log);
1247
1248 memset(&attr_mod, 0, sizeof(attr_mod));
1249
1250 attr_mod.cap.sm = is_sm_val;
1251
1252 status = ib_modify_ca(p_vend->h_ca, p_bind->port_num,
1253 IB_CA_MOD_IS_SM, &attr_mod);
1254
1255 if (status != IB_SUCCESS) {
1256 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1257 "osm_vendor_set_sm: ERR 3B34: "
1258 "Unable set 'IS_SM' bit to:%u in port attributes (%s).\n",
1259 is_sm_val, ib_get_err_str(status));
1260 }
1261
1262 OSM_LOG_EXIT(p_vend->p_log);
1263 }
1264
osm_vendor_set_debug(IN osm_vendor_t * const p_vend,IN int32_t level)1265 void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level)
1266 {
1267
1268 }
1269
1270 #endif /* OSM_VENDOR_INTF_AL */
1271