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 */ 49typedef 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*/ 67static void 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 155Exit: 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*/ 173static 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 *****************************************************************************/ 207static 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 219osm_bind_handle_t 220osmv_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 283Exit: 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 */ 298typedef 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 */ 329static ib_api_status_t 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 466Exit: 467 OSM_LOG_EXIT(p_log); 468 return status; 469} 470 471/* 472 * Query the SA based on the user's request. 473 */ 474ib_api_status_t 475osmv_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