1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff * 34219820Sjeff */ 35219820Sjeff 36219820Sjeff#if HAVE_CONFIG_H 37219820Sjeff# include <config.h> 38219820Sjeff#endif /* HAVE_CONFIG_H */ 39219820Sjeff 40219820Sjeff#if defined(OSM_VENDOR_INTF_MTL) | defined(OSM_VENDOR_INTF_TS) 41219820Sjeff#undef IN 42219820Sjeff#undef OUT 43219820Sjeff#include <stdlib.h> 44219820Sjeff#include <vapi_types.h> 45219820Sjeff#include <evapi.h> 46219820Sjeff#include <vendor/osm_vendor_api.h> 47219820Sjeff#include <opensm/osm_log.h> 48219820Sjeff#include <stdio.h> 49219820Sjeff 50219820Sjeff/******************************************************************************** 51219820Sjeff * 52219820Sjeff * Provide the functionality for selecting an HCA Port and Obtaining it's guid. 53219820Sjeff * 54219820Sjeff ********************************************************************************/ 55219820Sjeff 56219820Sjeff/********************************************************************** 57219820Sjeff * Convert the given GID to GUID by copy of it's upper 8 bytes 58219820Sjeff * 59219820Sjeff * 60219820Sjeff **********************************************************************/ 61219820Sjeff 62219820Sjeffib_api_status_t 63219820Sjeff__osm_vendor_gid_to_guid(IN u_int8_t * gid, OUT VAPI_gid_t * guid) 64219820Sjeff{ 65219820Sjeff memcpy(guid, gid + 8, 8); 66219820Sjeff return (IB_SUCCESS); 67219820Sjeff} 68219820Sjeff 69219820Sjeff/****f* OpenSM: CA Info/osm_ca_info_get_pi_ptr 70219820Sjeff * NAME 71219820Sjeff * osm_ca_info_get_pi_ptr 72219820Sjeff * 73219820Sjeff * DESCRIPTION 74219820Sjeff * Returns a pointer to the port attribute of the specified port 75219820Sjeff * owned by this CA. 76219820Sjeff * 77219820Sjeff * SYNOPSIS 78219820Sjeff */ 79219820Sjeffstatic ib_port_attr_t *__osm_ca_info_get_port_attr_ptr(IN const osm_ca_info_t * 80219820Sjeff const p_ca_info, 81219820Sjeff IN const uint8_t index) 82219820Sjeff{ 83219820Sjeff return (&p_ca_info->p_attr->p_port_attr[index]); 84219820Sjeff} 85219820Sjeff 86219820Sjeff/* 87219820Sjeff * PARAMETERS 88219820Sjeff * p_ca_info 89219820Sjeff * [in] Pointer to a CA Info object. 90219820Sjeff * 91219820Sjeff * index 92219820Sjeff * [in] Port "index" for which to retrieve the port attribute. 93219820Sjeff * The index is the offset into the ca's internal array 94219820Sjeff * of port attributes. 95219820Sjeff * 96219820Sjeff * RETURN VALUE 97219820Sjeff * Returns a pointer to the port attribute of the specified port 98219820Sjeff * owned by this CA. 99219820Sjeff * 100219820Sjeff * NOTES 101219820Sjeff * 102219820Sjeff * SEE ALSO 103219820Sjeff *********/ 104219820Sjeff 105219820Sjeff/******************************************************************************** 106219820Sjeff * get the CA names ava`ilable on the system 107219820Sjeff * NOTE: user of this function needs to deallocate p_hca_ids after usage. 108219820Sjeff ********************************************************************************/ 109219820Sjeffstatic ib_api_status_t 110219820Sjeff__osm_vendor_get_ca_ids(IN osm_vendor_t * const p_vend, 111219820Sjeff IN VAPI_hca_id_t ** const p_hca_ids, 112219820Sjeff IN uint32_t * const p_num_guids) 113219820Sjeff{ 114219820Sjeff ib_api_status_t status; 115219820Sjeff VAPI_ret_t vapi_res; 116219820Sjeff 117219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 118219820Sjeff 119219820Sjeff CL_ASSERT(p_hca_ids); 120219820Sjeff CL_ASSERT(p_num_guids); 121219820Sjeff 122219820Sjeff /* first call is just to get the number */ 123219820Sjeff vapi_res = EVAPI_list_hcas(0, p_num_guids, NULL); 124219820Sjeff 125219820Sjeff /* fail ? */ 126219820Sjeff if (vapi_res == VAPI_EINVAL_PARAM) { 127219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 128219820Sjeff "__osm_vendor_get_ca_ids: ERR 7101: " 129219820Sjeff "Bad parameter in calling: EVAPI_list_hcas. (%d)\n", 130219820Sjeff vapi_res); 131219820Sjeff status = IB_ERROR; 132219820Sjeff goto Exit; 133219820Sjeff } 134219820Sjeff 135219820Sjeff /* NO HCA ? */ 136219820Sjeff if (*p_num_guids == 0) { 137219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 138219820Sjeff "__osm_vendor_get_ca_ids: ERR 7102: " 139219820Sjeff "No available channel adapters.\n"); 140219820Sjeff status = IB_INSUFFICIENT_RESOURCES; 141219820Sjeff goto Exit; 142219820Sjeff } 143219820Sjeff 144219820Sjeff /* allocate and really call - user of this function needs to deallocate it */ 145219820Sjeff *p_hca_ids = 146219820Sjeff (VAPI_hca_id_t *) malloc(*p_num_guids * sizeof(VAPI_hca_id_t)); 147219820Sjeff 148219820Sjeff /* now call it really */ 149219820Sjeff vapi_res = EVAPI_list_hcas(*p_num_guids, p_num_guids, *p_hca_ids); 150219820Sjeff 151219820Sjeff /* too many ? */ 152219820Sjeff if (vapi_res == VAPI_EAGAIN) { 153219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 154219820Sjeff "__osm_vendor_get_ca_ids: ERR 7103: " 155219820Sjeff "More CA GUIDs than allocated array (%d).\n", 156219820Sjeff *p_num_guids); 157219820Sjeff status = IB_ERROR; 158219820Sjeff goto Exit; 159219820Sjeff } 160219820Sjeff 161219820Sjeff /* fail ? */ 162219820Sjeff if (vapi_res != VAPI_OK) { 163219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 164219820Sjeff "__osm_vendor_get_ca_ids: ERR 7104: " 165219820Sjeff "Bad parameter in calling: EVAPI_list_hcas.\n"); 166219820Sjeff status = IB_ERROR; 167219820Sjeff goto Exit; 168219820Sjeff } 169219820Sjeff 170219820Sjeff if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) { 171219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 172219820Sjeff "__osm_vendor_get_ca_ids: " 173219820Sjeff "Detected %u local channel adapters.\n", *p_num_guids); 174219820Sjeff } 175219820Sjeff 176219820Sjeff status = IB_SUCCESS; 177219820Sjeff 178219820SjeffExit: 179219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 180219820Sjeff return (status); 181219820Sjeff} 182219820Sjeff 183219820Sjeff/********************************************************************** 184219820Sjeff * Initialize an Info Struct for the Given HCA by its Id 185219820Sjeff **********************************************************************/ 186219820Sjeffstatic ib_api_status_t 187219820Sjeff__osm_ca_info_init(IN osm_vendor_t * const p_vend, 188219820Sjeff IN VAPI_hca_id_t ca_id, OUT osm_ca_info_t * const p_ca_info) 189219820Sjeff{ 190219820Sjeff ib_api_status_t status = IB_ERROR; 191219820Sjeff VAPI_ret_t vapi_res; 192219820Sjeff VAPI_hca_hndl_t hca_hndl; 193219820Sjeff VAPI_hca_vendor_t hca_vendor; 194219820Sjeff VAPI_hca_cap_t hca_cap; 195219820Sjeff VAPI_hca_port_t hca_port; 196219820Sjeff uint8_t port_num; 197219820Sjeff IB_gid_t *p_port_gid; 198219820Sjeff uint16_t maxNumGids; 199219820Sjeff 200219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 201219820Sjeff 202219820Sjeff /* get the HCA handle */ 203219820Sjeff vapi_res = EVAPI_get_hca_hndl(ca_id, &hca_hndl); 204219820Sjeff if (vapi_res != VAPI_OK) { 205219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 206219820Sjeff "__osm_ca_info_init: ERR 7105: " 207219820Sjeff "Fail to get HCA handle (%u).\n", vapi_res); 208219820Sjeff goto Exit; 209219820Sjeff } 210219820Sjeff 211219820Sjeff if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) { 212219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 213219820Sjeff "__osm_ca_info_init: " "Querying CA %s.\n", ca_id); 214219820Sjeff } 215219820Sjeff 216219820Sjeff /* query and get the HCA capability */ 217219820Sjeff vapi_res = VAPI_query_hca_cap(hca_hndl, &hca_vendor, &hca_cap); 218219820Sjeff if (vapi_res != VAPI_OK) { 219219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 220219820Sjeff "__osm_ca_info_init: ERR 7106: " 221219820Sjeff "Fail to get HCA Capabilities (%u).\n", vapi_res); 222219820Sjeff goto Exit; 223219820Sjeff } 224219820Sjeff 225219820Sjeff /* get the guid of the HCA */ 226219820Sjeff memcpy(&(p_ca_info->guid), hca_cap.node_guid, 8 * sizeof(u_int8_t)); 227219820Sjeff p_ca_info->attr_size = 1; 228219820Sjeff p_ca_info->p_attr = (ib_ca_attr_t *) malloc(sizeof(ib_ca_attr_t)); 229219820Sjeff memcpy(&(p_ca_info->p_attr->ca_guid), hca_cap.node_guid, 230219820Sjeff 8 * sizeof(u_int8_t)); 231219820Sjeff 232219820Sjeff /* now obtain the attributes of the ports */ 233219820Sjeff p_ca_info->p_attr->num_ports = hca_cap.phys_port_num; 234219820Sjeff p_ca_info->p_attr->p_port_attr = 235219820Sjeff (ib_port_attr_t *) malloc(hca_cap.phys_port_num * 236219820Sjeff sizeof(ib_port_attr_t)); 237219820Sjeff 238219820Sjeff for (port_num = 0; port_num < p_ca_info->p_attr->num_ports; port_num++) { 239219820Sjeff 240219820Sjeff /* query the port attributes */ 241219820Sjeff vapi_res = 242219820Sjeff VAPI_query_hca_port_prop(hca_hndl, port_num + 1, &hca_port); 243219820Sjeff if (vapi_res != VAPI_OK) { 244219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 245219820Sjeff "__osm_ca_info_init: ERR 7107: " 246219820Sjeff "Fail to get HCA Port Attributes (%d).\n", 247219820Sjeff vapi_res); 248219820Sjeff goto Exit; 249219820Sjeff } 250219820Sjeff 251219820Sjeff /* first call to know the size of the gid table */ 252219820Sjeff vapi_res = 253219820Sjeff VAPI_query_hca_gid_tbl(hca_hndl, port_num + 1, 0, 254219820Sjeff &maxNumGids, NULL); 255219820Sjeff p_port_gid = (IB_gid_t *) malloc(maxNumGids * sizeof(IB_gid_t)); 256219820Sjeff 257219820Sjeff vapi_res = 258219820Sjeff VAPI_query_hca_gid_tbl(hca_hndl, port_num + 1, maxNumGids, 259219820Sjeff &maxNumGids, p_port_gid); 260219820Sjeff if (vapi_res != VAPI_OK) { 261219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 262219820Sjeff "__osm_ca_info_init: ERR 7108: " 263219820Sjeff "Fail to get HCA Port GID (%d).\n", vapi_res); 264219820Sjeff goto Exit; 265219820Sjeff } 266219820Sjeff 267219820Sjeff __osm_vendor_gid_to_guid(p_port_gid[0], 268219820Sjeff (IB_gid_t *) & p_ca_info->p_attr-> 269219820Sjeff p_port_attr[port_num].port_guid); 270219820Sjeff p_ca_info->p_attr->p_port_attr[port_num].lid = hca_port.lid; 271219820Sjeff p_ca_info->p_attr->p_port_attr[port_num].link_state = 272219820Sjeff hca_port.state; 273219820Sjeff p_ca_info->p_attr->p_port_attr[port_num].sm_lid = 274219820Sjeff hca_port.sm_lid; 275219820Sjeff 276219820Sjeff free(p_port_gid); 277219820Sjeff } 278219820Sjeff 279219820Sjeff status = IB_SUCCESS; 280219820SjeffExit: 281219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 282219820Sjeff return (status); 283219820Sjeff} 284219820Sjeff 285219820Sjeff/********************************************************************** 286219820Sjeff **********************************************************************/ 287219820Sjeffvoid 288219820Sjeffosm_ca_info_destroy(IN osm_vendor_t * const p_vend, 289219820Sjeff IN osm_ca_info_t * const p_ca_info) 290219820Sjeff{ 291219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 292219820Sjeff 293219820Sjeff if (p_ca_info->p_attr) { 294219820Sjeff if (p_ca_info->p_attr->num_ports) { 295219820Sjeff free(p_ca_info->p_attr->p_port_attr); 296219820Sjeff } 297219820Sjeff free(p_ca_info->p_attr); 298219820Sjeff } 299219820Sjeff 300219820Sjeff free(p_ca_info); 301219820Sjeff 302219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 303219820Sjeff} 304219820Sjeff 305219820Sjeff/********************************************************************** 306219820Sjeff * Fill in the array of port_attr with all available ports on ALL the 307219820Sjeff * avilable CAs on this machine. 308219820Sjeff * ALSO - 309219820Sjeff * UPDATE THE VENDOR OBJECT LIST OF CA_INFO STRUCTS 310219820Sjeff **********************************************************************/ 311219820Sjeffib_api_status_t 312219820Sjeffosm_vendor_get_all_port_attr(IN osm_vendor_t * const p_vend, 313219820Sjeff IN ib_port_attr_t * const p_attr_array, 314219820Sjeff IN uint32_t * const p_num_ports) 315219820Sjeff{ 316219820Sjeff ib_api_status_t status; 317219820Sjeff 318219820Sjeff uint32_t ca; 319219820Sjeff uint32_t ca_count; 320219820Sjeff uint32_t port_count = 0; 321219820Sjeff uint8_t port_num; 322219820Sjeff uint32_t total_ports = 0; 323219820Sjeff VAPI_hca_id_t *p_ca_ids = NULL; 324219820Sjeff osm_ca_info_t *p_ca_info; 325219820Sjeff 326219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 327219820Sjeff 328219820Sjeff CL_ASSERT(p_vend); 329219820Sjeff 330219820Sjeff /* 331219820Sjeff * 1) Determine the number of CA's 332219820Sjeff * 2) Allocate an array big enough to hold the ca info objects. 333219820Sjeff * 3) Call again to retrieve the guids. 334219820Sjeff */ 335219820Sjeff status = __osm_vendor_get_ca_ids(p_vend, &p_ca_ids, &ca_count); 336219820Sjeff if (status != IB_SUCCESS) { 337219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 338219820Sjeff "osm_vendor_get_all_port_attr: ERR 7109: " 339219820Sjeff "Fail to get CA Ids.\n"); 340219820Sjeff goto Exit; 341219820Sjeff } 342219820Sjeff 343219820Sjeff /* we keep track of all the CAs in this info array */ 344219820Sjeff p_vend->p_ca_info = malloc(ca_count * sizeof(*p_vend->p_ca_info)); 345219820Sjeff if (p_vend->p_ca_info == NULL) { 346219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 347219820Sjeff "osm_vendor_get_all_port_attr: ERR 7110: " 348219820Sjeff "Unable to allocate CA information array.\n"); 349219820Sjeff goto Exit; 350219820Sjeff } 351219820Sjeff 352219820Sjeff memset(p_vend->p_ca_info, 0, ca_count * sizeof(*p_vend->p_ca_info)); 353219820Sjeff p_vend->ca_count = ca_count; 354219820Sjeff 355219820Sjeff /* 356219820Sjeff * For each CA, retrieve the CA info attributes 357219820Sjeff */ 358219820Sjeff for (ca = 0; ca < ca_count; ca++) { 359219820Sjeff p_ca_info = &p_vend->p_ca_info[ca]; 360219820Sjeff 361219820Sjeff status = __osm_ca_info_init(p_vend, p_ca_ids[ca], p_ca_info); 362219820Sjeff 363219820Sjeff if (status != IB_SUCCESS) { 364219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 365219820Sjeff "osm_vendor_get_all_port_attr: ERR 7111: " 366219820Sjeff "Unable to initialize CA Info object (%s).\n", 367219820Sjeff ib_get_err_str(status)); 368219820Sjeff } 369219820Sjeff 370219820Sjeff total_ports += osm_ca_info_get_num_ports(p_ca_info); 371219820Sjeff 372219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 373219820Sjeff "osm_vendor_get_all_port_attr: " 374219820Sjeff "osm_vendor_get_all_port_attr: %u got %u ports total:%u\n", 375219820Sjeff ca, osm_ca_info_get_num_ports(p_ca_info), total_ports); 376219820Sjeff 377219820Sjeff } 378219820Sjeff 379219820Sjeff /* 380219820Sjeff * If the user supplied enough storage, return the port guids, 381219820Sjeff * otherwise, return the appropriate error. 382219820Sjeff */ 383219820Sjeff if (*p_num_ports >= total_ports) { 384219820Sjeff for (ca = 0; ca < ca_count; ca++) { 385219820Sjeff uint32_t num_ports; 386219820Sjeff 387219820Sjeff p_ca_info = &p_vend->p_ca_info[ca]; 388219820Sjeff 389219820Sjeff num_ports = osm_ca_info_get_num_ports(p_ca_info); 390219820Sjeff 391219820Sjeff for (port_num = 0; port_num < num_ports; port_num++) { 392219820Sjeff p_attr_array[port_count] = 393219820Sjeff *__osm_ca_info_get_port_attr_ptr(p_ca_info, 394219820Sjeff port_num); 395219820Sjeff port_count++; 396219820Sjeff } 397219820Sjeff } 398219820Sjeff } else { 399219820Sjeff status = IB_INSUFFICIENT_MEMORY; 400219820Sjeff goto Exit; 401219820Sjeff } 402219820Sjeff 403219820Sjeff status = IB_SUCCESS; 404219820Sjeff 405219820SjeffExit: 406219820Sjeff *p_num_ports = total_ports; 407219820Sjeff 408219820Sjeff if (p_ca_ids) 409219820Sjeff free(p_ca_ids); 410219820Sjeff 411219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 412219820Sjeff return (status); 413219820Sjeff} 414219820Sjeff 415219820Sjeff/********************************************************************** 416219820Sjeff * Given the vendor obj and a guid 417219820Sjeff * return the ca id and port number that have that guid 418219820Sjeff **********************************************************************/ 419219820Sjeff 420219820Sjeffib_api_status_t 421219820Sjeffosm_vendor_get_guid_ca_and_port(IN osm_vendor_t * const p_vend, 422219820Sjeff IN ib_net64_t const guid, 423219820Sjeff OUT VAPI_hca_hndl_t * p_hca_hndl, 424219820Sjeff OUT VAPI_hca_id_t * p_hca_id, 425219820Sjeff OUT uint32_t * p_port_num) 426219820Sjeff{ 427219820Sjeff 428219820Sjeff ib_api_status_t status; 429219820Sjeff VAPI_hca_id_t *p_ca_ids = NULL; 430219820Sjeff VAPI_ret_t vapi_res; 431219820Sjeff VAPI_hca_hndl_t hca_hndl; 432219820Sjeff VAPI_hca_vendor_t hca_vendor; 433219820Sjeff VAPI_hca_cap_t hca_cap; 434219820Sjeff IB_gid_t *p_port_gid = NULL; 435219820Sjeff uint16_t maxNumGids; 436219820Sjeff ib_net64_t port_guid; 437219820Sjeff uint32_t ca, portIdx, ca_count; 438219820Sjeff 439219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 440219820Sjeff 441219820Sjeff CL_ASSERT(p_vend); 442219820Sjeff 443219820Sjeff /* 444219820Sjeff * 1) Determine the number of CA's 445219820Sjeff * 2) Allocate an array big enough to hold the ca info objects. 446219820Sjeff * 3) Call again to retrieve the guids. 447219820Sjeff */ 448219820Sjeff status = __osm_vendor_get_ca_ids(p_vend, &p_ca_ids, &ca_count); 449219820Sjeff if (status != IB_SUCCESS) { 450219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 451219820Sjeff "osm_vendor_get_guid_ca_and_port: ERR 7112: " 452219820Sjeff "Fail to get CA Ids.\n"); 453219820Sjeff goto Exit; 454219820Sjeff } 455219820Sjeff 456219820Sjeff /* 457219820Sjeff * For each CA, retrieve the CA info attributes 458219820Sjeff */ 459219820Sjeff for (ca = 0; ca < ca_count; ca++) { 460219820Sjeff /* get the HCA handle */ 461219820Sjeff vapi_res = EVAPI_get_hca_hndl(p_ca_ids[ca], &hca_hndl); 462219820Sjeff if (vapi_res != VAPI_OK) { 463219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 464219820Sjeff "osm_vendor_get_guid_ca_and_port: ERR 7113: " 465219820Sjeff "Fail to get HCA handle (%u).\n", vapi_res); 466219820Sjeff goto Exit; 467219820Sjeff } 468219820Sjeff 469219820Sjeff /* get the CA attributes - to know how many ports it has: */ 470219820Sjeff if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) { 471219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 472219820Sjeff "osm_vendor_get_guid_ca_and_port: " 473219820Sjeff "Querying CA %s.\n", p_ca_ids[ca]); 474219820Sjeff } 475219820Sjeff 476219820Sjeff /* query and get the HCA capability */ 477219820Sjeff vapi_res = VAPI_query_hca_cap(hca_hndl, &hca_vendor, &hca_cap); 478219820Sjeff if (vapi_res != VAPI_OK) { 479219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 480219820Sjeff "osm_vendor_get_guid_ca_and_port: ERR 7114: " 481219820Sjeff "Fail to get HCA Capabilities (%u).\n", 482219820Sjeff vapi_res); 483219820Sjeff goto Exit; 484219820Sjeff } 485219820Sjeff 486219820Sjeff /* go over all ports - to obtail their guids */ 487219820Sjeff for (portIdx = 0; portIdx < hca_cap.phys_port_num; portIdx++) { 488219820Sjeff vapi_res = 489219820Sjeff VAPI_query_hca_gid_tbl(hca_hndl, portIdx + 1, 0, 490219820Sjeff &maxNumGids, NULL); 491219820Sjeff p_port_gid = 492219820Sjeff (IB_gid_t *) malloc(maxNumGids * sizeof(IB_gid_t)); 493219820Sjeff 494219820Sjeff /* get the port guid */ 495219820Sjeff vapi_res = 496219820Sjeff VAPI_query_hca_gid_tbl(hca_hndl, portIdx + 1, 497219820Sjeff maxNumGids, &maxNumGids, 498219820Sjeff p_port_gid); 499219820Sjeff if (vapi_res != VAPI_OK) { 500219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 501219820Sjeff "osm_vendor_get_guid_ca_and_port: ERR 7115: " 502219820Sjeff "Fail to get HCA Port GID (%d).\n", 503219820Sjeff vapi_res); 504219820Sjeff goto Exit; 505219820Sjeff } 506219820Sjeff 507219820Sjeff /* convert to SF style */ 508219820Sjeff __osm_vendor_gid_to_guid(p_port_gid[0], 509219820Sjeff (VAPI_gid_t *) & port_guid); 510219820Sjeff 511219820Sjeff /* finally did we find it ? */ 512219820Sjeff if (port_guid == guid) { 513219820Sjeff *p_hca_hndl = hca_hndl; 514219820Sjeff memcpy(p_hca_id, p_ca_ids[ca], 515219820Sjeff sizeof(VAPI_hca_id_t)); 516219820Sjeff *p_port_num = portIdx + 1; 517219820Sjeff status = IB_SUCCESS; 518219820Sjeff goto Exit; 519219820Sjeff } 520219820Sjeff 521219820Sjeff free(p_port_gid); 522219820Sjeff p_port_gid = NULL; 523219820Sjeff } /* ALL PORTS */ 524219820Sjeff } /* all HCAs */ 525219820Sjeff 526219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 527219820Sjeff "osm_vendor_get_guid_ca_and_port: ERR 7116: " 528219820Sjeff "Fail to find HCA and Port for Port Guid 0x%" PRIx64 "\n", 529219820Sjeff cl_ntoh64(guid)); 530219820Sjeff status = IB_INVALID_GUID; 531219820Sjeff 532219820SjeffExit: 533219820Sjeff if (p_ca_ids != NULL) 534219820Sjeff free(p_ca_ids); 535219820Sjeff if (p_port_gid != NULL) 536219820Sjeff free(p_port_gid); 537219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 538219820Sjeff return (status); 539219820Sjeff} 540219820Sjeff 541219820Sjeff#ifdef __TEST_HCA_GUID__ 542219820Sjeff 543219820Sjeff#define GUID_ARRAY_SIZE 64 544219820Sjeff 545219820Sjeff#include <stdio.h> 546219820Sjeff 547219820Sjeff/********************************************************************** 548219820Sjeff **********************************************************************/ 549219820Sjeffib_net64_t get_port_guid() 550219820Sjeff{ 551219820Sjeff uint32_t i; 552219820Sjeff uint32_t choice = 0; 553219820Sjeff boolean_t done_flag = FALSE; 554219820Sjeff ib_api_status_t status; 555219820Sjeff uint32_t num_ports = GUID_ARRAY_SIZE; 556219820Sjeff ib_port_attr_t attr_array[GUID_ARRAY_SIZE]; 557219820Sjeff VAPI_hca_id_t ca_id; 558219820Sjeff uint32_t portNum; 559219820Sjeff osm_vendor_t vend; 560219820Sjeff osm_vendor_t *p_vend; 561219820Sjeff osm_log_t *p_osm_log, tlog; 562219820Sjeff 563219820Sjeff p_osm_log = &tlog; 564219820Sjeff 565219820Sjeff status = osm_log_init(p_osm_log, FALSE); 566219820Sjeff if (status != IB_SUCCESS) 567219820Sjeff return (status); 568219820Sjeff 569219820Sjeff osm_log(p_osm_log, OSM_LOG_FUNCS, "get_port_guid: [\n"); 570219820Sjeff 571219820Sjeff p_vend = &vend; 572219820Sjeff p_vend->p_log = p_osm_log; 573219820Sjeff 574219820Sjeff /* 575219820Sjeff * Call the transport layer for a list of local port 576219820Sjeff * GUID values. 577219820Sjeff */ 578219820Sjeff status = osm_vendor_get_all_port_attr(p_vend, attr_array, &num_ports); 579219820Sjeff if (status != IB_SUCCESS) { 580219820Sjeff printf("\nError from osm_opensm_init (%x)\n", status); 581219820Sjeff return (0); 582219820Sjeff } 583219820Sjeff 584219820Sjeff if (num_ports == 0) { 585219820Sjeff printf("\nNo local ports detected!\n"); 586219820Sjeff return (0); 587219820Sjeff } 588219820Sjeff 589219820Sjeff while (done_flag == FALSE) { 590219820Sjeff printf("\nChoose a local port number with which to bind:\n\n"); 591219820Sjeff for (i = 0; i < num_ports; i++) { 592219820Sjeff /* 593219820Sjeff * Print the index + 1 since by convention, port numbers 594219820Sjeff * start with 1 on host channel adapters. 595219820Sjeff */ 596219820Sjeff 597219820Sjeff printf("\t%u: GUID = 0x%8" PRIx64 598219820Sjeff ", lid = 0x%04X, state = %s\n", i + 1, 599219820Sjeff cl_ntoh64(attr_array[i].port_guid), 600219820Sjeff cl_ntoh16(attr_array[i].lid), 601219820Sjeff ib_get_port_state_str(attr_array[i].link_state)); 602219820Sjeff } 603219820Sjeff 604219820Sjeff printf("\nEnter choice (1-%u): ", i); 605219820Sjeff fflush(stdout); 606219820Sjeff scanf("%u", &choice); 607219820Sjeff if (choice > num_ports) 608219820Sjeff printf("\nError: Lame choice!\n"); 609219820Sjeff else 610219820Sjeff done_flag = TRUE; 611219820Sjeff } 612219820Sjeff 613219820Sjeff status = 614219820Sjeff osm_vendor_get_guid_ca_and_port(p_vend, 615219820Sjeff attr_array[choice - 1].port_guid, 616219820Sjeff &ca_id, &portNum); 617219820Sjeff if (status != IB_SUCCESS) { 618219820Sjeff printf("Error obtaining back the HCA and Port\n"); 619219820Sjeff return (0); 620219820Sjeff } 621219820Sjeff 622219820Sjeff printf("Selected: CA:%s Port:%d\n", ca_id, portNum); 623219820Sjeff 624219820Sjeff return (attr_array[choice - 1].port_guid); 625219820Sjeff} 626219820Sjeff 627219820Sjeffint main(int argc, char **argv) 628219820Sjeff{ 629219820Sjeff get_port_guid(); 630219820Sjeff return (0); 631219820Sjeff} 632219820Sjeff 633219820Sjeff#endif 634219820Sjeff 635219820Sjeff#endif 636