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