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_SIM) 41219820Sjeff#undef IN 42219820Sjeff#undef OUT 43219820Sjeff 44219820Sjeff#include <unistd.h> 45219820Sjeff#include <vendor/osm_vendor_api.h> 46219820Sjeff#include <opensm/osm_log.h> 47219820Sjeff#include <stdlib.h> 48219820Sjeff#include <stdio.h> 49219820Sjeff#include <sys/types.h> 50219820Sjeff#include <dirent.h> 51219820Sjeff#include <stdlib.h> 52219820Sjeff#include <sys/stat.h> 53219820Sjeff#include <stdint.h> 54219820Sjeff#include <fcntl.h> 55219820Sjeff 56219820Sjeff/****************************************************************************** 57219820Sjeff* 58219820Sjeff* Provides the functionality for selecting an HCA Port and Obtaining it's guid. 59219820Sjeff* This version is based on $IBMGTSIM_DIR/$IBMGTSIM_NODE file system. 60219820Sjeff* This is a mimic of the OpenIB gen1 file system 61219820Sjeff* 62219820Sjeff******************************************************************************/ 63219820Sjeff 64219820Sjeffchar *__get_simulator_dir(void) 65219820Sjeff{ 66219820Sjeff static char *ibmgtSimDir = NULL; 67219820Sjeff static char *defaultIbmgtSimDir = "/tmp/ibmgtsim"; 68219820Sjeff static char *ibmgtSimNode = NULL; 69219820Sjeff static char dirName[1024]; 70219820Sjeff 71219820Sjeff /* we use the first pointer to know if we were here */ 72219820Sjeff if (ibmgtSimDir == NULL) { 73219820Sjeff /* obtain the simulator directory */ 74219820Sjeff ibmgtSimDir = getenv("IBMGTSIM_DIR"); 75219820Sjeff if (ibmgtSimDir == NULL) { 76219820Sjeff printf 77219820Sjeff ("-W- Environment variable: IBMGTSIM_DIR does not exist.\n"); 78219820Sjeff printf 79219820Sjeff (" Please create one used by the simulator.\n"); 80219820Sjeff printf(" Using /tmp/ibmgtsim as default.\n"); 81219820Sjeff ibmgtSimDir = defaultIbmgtSimDir; 82219820Sjeff } 83219820Sjeff 84219820Sjeff /* obtain the node name we simulate */ 85219820Sjeff ibmgtSimNode = getenv("IBMGTSIM_NODE"); 86219820Sjeff if (ibmgtSimNode == NULL) { 87219820Sjeff printf 88219820Sjeff ("-W- Environment variable: IBMGTSIM_NODE does not exist.\n"); 89219820Sjeff printf 90219820Sjeff (" This variable should be the name of the node you wish to simulate.\n"); 91219820Sjeff printf(" Using H-1 as default.\n"); 92219820Sjeff ibmgtSimNode = "H-1"; 93219820Sjeff } 94219820Sjeff sprintf(dirName, "%s/%s", ibmgtSimDir, ibmgtSimNode); 95219820Sjeff } 96219820Sjeff 97219820Sjeff return dirName; 98219820Sjeff} 99219820Sjeff 100219820Sjefftypedef struct _osm_ca_info { 101219820Sjeff ib_net64_t guid; 102219820Sjeff size_t attr_size; 103219820Sjeff ib_ca_attr_t *p_attr; 104219820Sjeff 105219820Sjeff} osm_ca_info_t; 106219820Sjeff 107219820Sjeff/********************************************************************** 108219820Sjeff * Returns a pointer to the port attribute of the specified port 109219820Sjeff * owned by this CA. 110219820Sjeff ************************************************************************/ 111219820Sjeffstatic ib_port_attr_t *__osm_ca_info_get_port_attr_ptr(IN const osm_ca_info_t * 112219820Sjeff const p_ca_info, 113219820Sjeff IN const uint8_t index) 114219820Sjeff{ 115219820Sjeff return (&p_ca_info->p_attr->p_port_attr[index]); 116219820Sjeff} 117219820Sjeff 118219820Sjeff/********************************************************************** 119219820Sjeff * Obtain the number of local CAs by scanning /proc/infiniband/core 120219820Sjeff **********************************************************************/ 121219820Sjeffint __hca_sim_get_num_cas(void) 122219820Sjeff{ 123219820Sjeff int num_cas = 0; 124219820Sjeff DIR *dp; 125219820Sjeff struct dirent *ep; 126219820Sjeff 127219820Sjeff dp = opendir(__get_simulator_dir()); 128219820Sjeff 129219820Sjeff if (dp != NULL) { 130219820Sjeff while ((ep = readdir(dp))) { 131219820Sjeff /* CAs are directories with the format ca[1-9][0-9]* */ 132219820Sjeff /* if ((ep->d_type == DT_DIR) && !strncmp(ep->d_name, "ca", 2)) */ 133219820Sjeff if (!strncmp(ep->d_name, "ca", 2)) { 134219820Sjeff num_cas++; 135219820Sjeff } 136219820Sjeff } 137219820Sjeff closedir(dp); 138219820Sjeff } else { 139219820Sjeff printf("__hca_sim_get_num_cas: ERROR : ail to open dir %s\n", 140219820Sjeff __get_simulator_dir()); 141219820Sjeff exit(1); 142219820Sjeff } 143219820Sjeff 144219820Sjeff if (!num_cas) 145219820Sjeff exit(1); 146219820Sjeff return num_cas; 147219820Sjeff} 148219820Sjeff 149219820Sjeff/* 150219820Sjeff name: InfiniHost0 151219820Sjeff provider: tavor 152219820Sjeff node GUID: 0002:c900:0120:3470 153219820Sjeff ports: 2 154219820Sjeff vendor ID: 0x2c9 155219820Sjeff device ID: 0x5a44 156219820Sjeff HW revision: 0xa1 157219820Sjeff FW revision: 0x300020080 158219820Sjeff*/ 159219820Sjefftypedef struct _sim_ca_info { 160219820Sjeff char name[32]; 161219820Sjeff char provider[32]; 162219820Sjeff uint64_t guid; 163219820Sjeff uint8_t num_ports; 164219820Sjeff uint32_t vend_id; 165219820Sjeff uint16_t dev_id; 166219820Sjeff uint16_t rev_id; 167219820Sjeff uint64_t fw_rev; 168219820Sjeff} sim_ca_info_t; 169219820Sjeff 170219820Sjeff/********************************************************************** 171219820Sjeff * Parse the CA Info file available in ibmgtSimDir/caN/info 172219820Sjeff **********************************************************************/ 173219820Sjeffstatic ib_api_status_t 174219820Sjeff__parse_ca_info_file(IN osm_vendor_t * const p_vend, 175219820Sjeff IN uint32_t idx, OUT sim_ca_info_t * sim_ca_info) 176219820Sjeff{ 177219820Sjeff ib_api_status_t status = IB_ERROR; 178219820Sjeff int info_file; 179219820Sjeff char file_name[256]; 180219820Sjeff char file_buffer[3200]; 181219820Sjeff char *p_ch; 182219820Sjeff int g1, g2, g3, g4; 183219820Sjeff int num_ports; 184219820Sjeff uint32_t len; 185219820Sjeff 186219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 187219820Sjeff 188219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 189219820Sjeff "__parse_ca_info_file: " "Querying CA %d.\n", idx); 190219820Sjeff 191219820Sjeff /* we use the proc file system so we must be able to open the info file .. */ 192219820Sjeff sprintf(file_name, "%s/ca%d/info", __get_simulator_dir(), idx); 193219820Sjeff info_file = open(file_name, O_RDONLY); 194219820Sjeff if (!info_file) { 195219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 196219820Sjeff "__parse_ca_info_file: ERR 5105: " 197219820Sjeff "Fail to open HCA:%d info file:(%s).\n", idx, 198219820Sjeff file_name); 199219820Sjeff goto Exit; 200219820Sjeff } 201219820Sjeff 202219820Sjeff /* read in the file */ 203219820Sjeff len = read(info_file, file_buffer, 3200); 204219820Sjeff close(info_file); 205219820Sjeff file_buffer[len] = '\0'; 206219820Sjeff 207219820Sjeff /* 208219820Sjeff parse the file ... 209219820Sjeff name: InfiniHost0 210219820Sjeff provider: tavor 211219820Sjeff node GUID: 0002:c900:0120:3470 212219820Sjeff ports: 2 213219820Sjeff vendor ID: 0x2c9 214219820Sjeff device ID: 0x5a44 215219820Sjeff HW revision: 0xa1 216219820Sjeff FW revision: 0x300020080 217219820Sjeff */ 218219820Sjeff if (!(p_ch = strstr(file_buffer, "name:"))) { 219219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 220219820Sjeff "__parse_ca_info_file: ERR 5106: " 221219820Sjeff "Fail to obtain HCA name. In info file:(%s).\n", 222219820Sjeff file_buffer); 223219820Sjeff goto Exit; 224219820Sjeff } 225219820Sjeff if (sscanf(p_ch, "name: %s", sim_ca_info->name) != 1) { 226219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 227219820Sjeff "__parse_ca_info_file: ERR 5107: " 228219820Sjeff "Fail to parse name in info file:(%s).\n", p_ch); 229219820Sjeff goto Exit; 230219820Sjeff } 231219820Sjeff 232219820Sjeff /* get the guid of the HCA */ 233219820Sjeff if (!(p_ch = strstr(file_buffer, "node GUID:"))) { 234219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 235219820Sjeff "__parse_ca_info_file: ERR 5108: " 236219820Sjeff "Fail to obtain GUID in info file:(%s).\n", 237219820Sjeff file_buffer); 238219820Sjeff goto Exit; 239219820Sjeff } 240219820Sjeff if (sscanf(p_ch, "node GUID: %x:%x:%x:%x", &g1, &g2, &g3, &g4) != 4) { 241219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 242219820Sjeff "__parse_ca_info_file: ERR 5109: " 243219820Sjeff "Fail to parse GUID in info file:(%s).\n", p_ch); 244219820Sjeff goto Exit; 245219820Sjeff } 246219820Sjeff sim_ca_info->guid = (uint64_t) g1 << 48 | (uint64_t) g1 << 32 247219820Sjeff | (uint64_t) g1 << 16 | (uint64_t) g3; 248219820Sjeff 249219820Sjeff /* obtain number of ports */ 250219820Sjeff if (!(p_ch = strstr(file_buffer, "ports:"))) { 251219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 252219820Sjeff "__parse_ca_info_file: ERR 5110: " 253219820Sjeff "Fail to obtain number of ports in info file:(%s).\n", 254219820Sjeff file_buffer); 255219820Sjeff goto Exit; 256219820Sjeff } 257219820Sjeff if (sscanf(p_ch, "ports: %d", &num_ports) != 1) { 258219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 259219820Sjeff "__parse_ca_info_file: ERR 5111: " 260219820Sjeff "Fail to parse num ports in info file:(%s).\n", p_ch); 261219820Sjeff goto Exit; 262219820Sjeff } 263219820Sjeff sim_ca_info->num_ports = num_ports; 264219820Sjeff 265219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 266219820Sjeff "__parse_ca_info_file: " 267219820Sjeff "CA1 = name:%s guid:0x%016llx ports:%d\n", 268219820Sjeff sim_ca_info->name, sim_ca_info->guid, sim_ca_info->num_ports); 269219820Sjeff 270219820Sjeff status = IB_SUCCESS; 271219820SjeffExit: 272219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 273219820Sjeff return status; 274219820Sjeff} 275219820Sjeff 276219820Sjeff/* 277219820Sjeff state: ACTIVE 278219820Sjeff LID: 0x0001 279219820Sjeff LMC: 0x0000 280219820Sjeff SM LID: 0x0001 281219820Sjeff SM SL: 0x0000 282219820Sjeff Capabilities: IsSM 283219820Sjeff IsTrapSupported 284219820Sjeff IsAutomaticMigrationSupported 285219820Sjeff IsSLMappingSupported 286219820Sjeff IsLEDInfoSupported 287219820Sjeff IsSystemImageGUIDSupported 288219820Sjeff IsVendorClassSupported 289219820Sjeff IsCapabilityMaskNoticeSupported 290219820Sjeff*/ 291219820Sjefftypedef struct _sim_port_info { 292219820Sjeff uint8_t state; 293219820Sjeff uint16_t lid; 294219820Sjeff uint8_t lmc; 295219820Sjeff uint16_t sm_lid; 296219820Sjeff uint8_t sm_sl; 297219820Sjeff} sim_port_info_t; 298219820Sjeff 299219820Sjeff/********************************************************************** 300219820Sjeff * Parse the Port Info file available in ibmgtSimDir/caN/portM/info 301219820Sjeff * Port num is 1..N 302219820Sjeff **********************************************************************/ 303219820Sjeffstatic ib_api_status_t 304219820Sjeff__parse_port_info_file(IN osm_vendor_t * const p_vend, 305219820Sjeff IN uint32_t hca_idx, 306219820Sjeff IN uint8_t port_num, OUT sim_port_info_t * sim_port_info) 307219820Sjeff{ 308219820Sjeff ib_api_status_t status = IB_ERROR; 309219820Sjeff int info_file; 310219820Sjeff char file_name[256]; 311219820Sjeff char file_buffer[3200]; 312219820Sjeff char state[12]; 313219820Sjeff char *p_ch; 314219820Sjeff int lid, sm_lid, lmc, sm_sl; 315219820Sjeff uint32_t len; 316219820Sjeff 317219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 318219820Sjeff 319219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 320219820Sjeff "__parse_port_info_file: " 321219820Sjeff "Parsing Proc File System Port Info CA %d Port %d.\n", hca_idx, 322219820Sjeff port_num); 323219820Sjeff 324219820Sjeff /* we use the proc file system so we must be able to open the info file .. */ 325219820Sjeff sprintf(file_name, "%s/ca%d/port%d/info", __get_simulator_dir(), 326219820Sjeff hca_idx, port_num); 327219820Sjeff info_file = open(file_name, O_RDONLY); 328219820Sjeff if (!info_file) { 329219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 330219820Sjeff "__parse_port_info_file: ERR 5112: " 331219820Sjeff "Fail to open HCA:%d Port:%d info file:(%s).\n", 332219820Sjeff hca_idx, port_num, file_name); 333219820Sjeff goto Exit; 334219820Sjeff } 335219820Sjeff 336219820Sjeff /* read in the file */ 337219820Sjeff len = read(info_file, file_buffer, 3200); 338219820Sjeff close(info_file); 339219820Sjeff file_buffer[len] = '\0'; 340219820Sjeff 341219820Sjeff /* 342219820Sjeff parse the file ... 343219820Sjeff state: ACTIVE 344219820Sjeff LID: 0x0001 345219820Sjeff LMC: 0x0000 346219820Sjeff SM LID: 0x0001 347219820Sjeff SM SL: 0x0000 348219820Sjeff ... 349219820Sjeff */ 350219820Sjeff if (!(p_ch = strstr(file_buffer, "state:"))) { 351219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 352219820Sjeff "__parse_port_info_file: ERR 5113: " 353219820Sjeff "Fail to obtain port state. In info file:(%s).\n", 354219820Sjeff file_buffer); 355219820Sjeff goto Exit; 356219820Sjeff } 357219820Sjeff if (sscanf(p_ch, "state: %s", state) != 1) { 358219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 359219820Sjeff "__parse_port_info_file: ERR 5114: " 360219820Sjeff "Fail to parse state from info file:(%s).\n", p_ch); 361219820Sjeff goto Exit; 362219820Sjeff } 363219820Sjeff 364219820Sjeff if (!strcmp(state, "ACTIVE")) 365219820Sjeff sim_port_info->state = IB_LINK_ACTIVE; 366219820Sjeff else if (!strcmp(state, "DOWN")) 367219820Sjeff sim_port_info->state = IB_LINK_DOWN; 368219820Sjeff else if (!strcmp(state, "INIT")) 369219820Sjeff sim_port_info->state = IB_LINK_INIT; 370219820Sjeff else if (!strcmp(state, "ARMED")) 371219820Sjeff sim_port_info->state = IB_LINK_ARMED; 372219820Sjeff else 373219820Sjeff sim_port_info->state = 0; 374219820Sjeff 375219820Sjeff /* get lid */ 376219820Sjeff if (!(p_ch = strstr(file_buffer, "LID:"))) { 377219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 378219820Sjeff "__parse_port_info_file: ERR 5115: " 379219820Sjeff "Fail to obtain port lid. In info file:(%s).\n", 380219820Sjeff file_buffer); 381219820Sjeff goto Exit; 382219820Sjeff } 383219820Sjeff if (sscanf(p_ch, "LID: %x", &lid) != 1) { 384219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 385219820Sjeff "__parse_port_info_file: ERR 5116: " 386219820Sjeff "Fail to parse lid from info file:(%s).\n", p_ch); 387219820Sjeff goto Exit; 388219820Sjeff } 389219820Sjeff sim_port_info->lid = lid; 390219820Sjeff /* get LMC */ 391219820Sjeff if (!(p_ch = strstr(file_buffer, "LMC:"))) { 392219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 393219820Sjeff "__parse_port_info_file: ERR 5117: " 394219820Sjeff "Fail to obtain port LMC. In info file:(%s).\n", 395219820Sjeff file_buffer); 396219820Sjeff goto Exit; 397219820Sjeff } 398219820Sjeff if (sscanf(p_ch, "LMC: %x", &lmc) != 1) { 399219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 400219820Sjeff "__parse_port_info_file: ERR 5118: " 401219820Sjeff "Fail to parse LMC from info file:(%s).\n", p_ch); 402219820Sjeff goto Exit; 403219820Sjeff } 404219820Sjeff sim_port_info->lmc = lmc; 405219820Sjeff 406219820Sjeff /* get SM LID */ 407219820Sjeff if (!(p_ch = strstr(file_buffer, "SM LID:"))) { 408219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 409219820Sjeff "__parse_port_info_file: ERR 5119: " 410219820Sjeff "Fail to obtain port SM LID. In info file:(%s).\n", 411219820Sjeff file_buffer); 412219820Sjeff goto Exit; 413219820Sjeff } 414219820Sjeff if (sscanf(p_ch, "SM LID: %x", &sm_lid) != 1) { 415219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 416219820Sjeff "__parse_port_info_file: ERR 5120: " 417219820Sjeff "Fail to parse SM LID from info file:(%s).\n", p_ch); 418219820Sjeff goto Exit; 419219820Sjeff } 420219820Sjeff sim_port_info->sm_lid = sm_lid; 421219820Sjeff 422219820Sjeff /* get SM LID */ 423219820Sjeff if (!(p_ch = strstr(file_buffer, "SM SL:"))) { 424219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 425219820Sjeff "__parse_port_info_file: ERR 5121: " 426219820Sjeff "Fail to obtain port SM SL. In info file:(%s).\n", 427219820Sjeff file_buffer); 428219820Sjeff goto Exit; 429219820Sjeff } 430219820Sjeff if (sscanf(p_ch, "SM SL: %x", &sm_sl) != 1) { 431219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 432219820Sjeff "__parse_port_info_file: ERR 5122: " 433219820Sjeff "Fail to parse SM SL from info file:(%s).\n", p_ch); 434219820Sjeff goto Exit; 435219820Sjeff } 436219820Sjeff sim_port_info->sm_sl = sm_sl; 437219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 438219820Sjeff "__parse_port_info_file: " 439219820Sjeff "Obtained Port:%d = state:%d, lid:0x%04X, lmc:%d, sm_lid:0x%04X, sm_sl:%d\n", 440219820Sjeff port_num, sim_port_info->state, sim_port_info->lid, 441219820Sjeff sim_port_info->lmc, sim_port_info->sm_lid, 442219820Sjeff sim_port_info->sm_sl); 443219820Sjeff 444219820Sjeff status = IB_SUCCESS; 445219820SjeffExit: 446219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 447219820Sjeff return status; 448219820Sjeff} 449219820Sjeff 450219820Sjeff/********************************************************************** 451219820Sjeff * Parse the port guid_tbl file to obtain the port guid. 452219820Sjeff * File format is: 453219820Sjeff * [ 0] fe80:0000:0000:0000:0002:c900:0120:3472 454219820Sjeff **********************************************************************/ 455219820Sjeffstatic ib_api_status_t 456219820Sjeff__get_port_guid_from_port_gid_tbl(IN osm_vendor_t * const p_vend, 457219820Sjeff IN uint32_t hca_idx, 458219820Sjeff IN uint8_t port_num, OUT uint64_t * port_guid) 459219820Sjeff{ 460219820Sjeff ib_api_status_t status = IB_ERROR; 461219820Sjeff int info_file; 462219820Sjeff char file_name[256]; 463219820Sjeff char file_buffer[3200]; 464219820Sjeff char *p_ch; 465219820Sjeff int g[8]; 466219820Sjeff uint32_t len; 467219820Sjeff 468219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 469219820Sjeff 470219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 471219820Sjeff "__get_port_guid_from_port_gid_tbl: " 472219820Sjeff "Parsing Proc File System Port Guid Table CA %d Port %d.\n", 473219820Sjeff hca_idx, port_num); 474219820Sjeff 475219820Sjeff /* we use the proc file system so we must be able to open the info file .. */ 476219820Sjeff sprintf(file_name, "%s/ca%d/port%d/gid_table", 477219820Sjeff __get_simulator_dir(), hca_idx, port_num); 478219820Sjeff info_file = open(file_name, O_RDONLY); 479219820Sjeff if (!info_file) { 480219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 481219820Sjeff "__get_port_guid_from_port_gid_tbl: ERR 5123: " 482219820Sjeff "Fail to open HCA:%d Port:%d gid_table file:(%s).\n", 483219820Sjeff hca_idx, port_num, file_name); 484219820Sjeff goto Exit; 485219820Sjeff } 486219820Sjeff 487219820Sjeff /* read in the file */ 488219820Sjeff len = read(info_file, file_buffer, 3200); 489219820Sjeff close(info_file); 490219820Sjeff file_buffer[len] = '\0'; 491219820Sjeff 492219820Sjeff /* 493219820Sjeff parse the file ... 494219820Sjeff [ 0] fe80:0000:0000:0000:0002:c900:0120:3472 495219820Sjeff ... 496219820Sjeff */ 497219820Sjeff if (!(p_ch = strstr(file_buffer, "[ 0]"))) { 498219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 499219820Sjeff "__get_port_guid_from_port_gid_tbl: ERR 5124: " 500219820Sjeff "Fail to obtain first gid index. In gid_table file:(%s).\n", 501219820Sjeff file_buffer); 502219820Sjeff goto Exit; 503219820Sjeff } 504219820Sjeff if (sscanf(p_ch + 6, "%x:%x:%x:%x:%x:%x:%x:%x", 505219820Sjeff &g[7], &g[6], &g[5], &g[4], &g[3], &g[2], &g[1], &g[0]) != 8) 506219820Sjeff { 507219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 508219820Sjeff "__get_port_guid_from_port_gid_tbl: ERR 5125: " 509219820Sjeff "Fail to parse gid from gid_table file:(%s).\n", p_ch); 510219820Sjeff goto Exit; 511219820Sjeff } 512219820Sjeff 513219820Sjeff *port_guid = 514219820Sjeff (uint64_t) g[3] << 48 | (uint64_t) g[2] << 32 | (uint64_t) g[1] << 515219820Sjeff 16 | g[0]; 516219820Sjeff status = IB_SUCCESS; 517219820SjeffExit: 518219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 519219820Sjeff return status; 520219820Sjeff} 521219820Sjeff 522219820Sjeff/********************************************************************** 523219820Sjeff * Initialize an Info Struct for the Given HCA by its index 1..N 524219820Sjeff **********************************************************************/ 525219820Sjeffstatic ib_api_status_t 526219820Sjeff__osm_ca_info_init(IN osm_vendor_t * const p_vend, 527219820Sjeff IN uint32_t const idx, OUT osm_ca_info_t * const p_ca_info) 528219820Sjeff{ 529219820Sjeff ib_api_status_t status = IB_ERROR; 530219820Sjeff uint8_t port_num; 531219820Sjeff uint64_t port_guid; 532219820Sjeff 533219820Sjeff sim_ca_info_t sim_ca_info; 534219820Sjeff 535219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 536219820Sjeff 537219820Sjeff /* parse the CA info file */ 538219820Sjeff if (__parse_ca_info_file(p_vend, idx, &sim_ca_info) != IB_SUCCESS) 539219820Sjeff goto Exit; 540219820Sjeff 541219820Sjeff p_ca_info->guid = cl_hton64(sim_ca_info.guid); 542219820Sjeff 543219820Sjeff /* set size of attributes and allocate them */ 544219820Sjeff p_ca_info->attr_size = 1; 545219820Sjeff p_ca_info->p_attr = (ib_ca_attr_t *) malloc(sizeof(ib_ca_attr_t)); 546219820Sjeff 547219820Sjeff p_ca_info->p_attr->ca_guid = p_ca_info->guid; 548219820Sjeff p_ca_info->p_attr->num_ports = sim_ca_info.num_ports; 549219820Sjeff 550219820Sjeff /* now obtain the attributes of the ports */ 551219820Sjeff p_ca_info->p_attr->p_port_attr = 552219820Sjeff (ib_port_attr_t *) malloc(sim_ca_info.num_ports * 553219820Sjeff sizeof(ib_port_attr_t)); 554219820Sjeff 555219820Sjeff /* get all the ports info */ 556219820Sjeff for (port_num = 1; port_num <= sim_ca_info.num_ports; port_num++) { 557219820Sjeff sim_port_info_t sim_port_info; 558219820Sjeff /* query the port attributes */ 559219820Sjeff if (__parse_port_info_file 560219820Sjeff (p_vend, idx, port_num, &sim_port_info)) { 561219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 562219820Sjeff "__osm_ca_info_init: ERR 5126: " 563219820Sjeff "Fail to get HCA:%d Port:%d Attributes.\n", idx, 564219820Sjeff port_num); 565219820Sjeff goto Exit; 566219820Sjeff } 567219820Sjeff 568219820Sjeff /* HACK: the lids should have been converted to network but the rest of the code 569219820Sjeff is wrong and provdes them as is (host order) - so we stick with it. */ 570219820Sjeff p_ca_info->p_attr->p_port_attr[port_num - 1].lid = 571219820Sjeff sim_port_info.lid; 572219820Sjeff p_ca_info->p_attr->p_port_attr[port_num - 1].link_state = 573219820Sjeff sim_port_info.state; 574219820Sjeff p_ca_info->p_attr->p_port_attr[port_num - 1].sm_lid = 575219820Sjeff sim_port_info.sm_lid; 576219820Sjeff 577219820Sjeff /* get the port guid */ 578219820Sjeff if (__get_port_guid_from_port_gid_tbl 579219820Sjeff (p_vend, idx, port_num, &port_guid)) { 580219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 581219820Sjeff "__osm_ca_info_init: ERR 5127: " 582219820Sjeff "Fail to get HCA:%d Port:%d Guid.\n", idx, 583219820Sjeff port_num); 584219820Sjeff goto Exit; 585219820Sjeff } 586219820Sjeff p_ca_info->p_attr->p_port_attr[port_num - 1].port_guid = 587219820Sjeff cl_hton64(port_guid); 588219820Sjeff } 589219820Sjeff 590219820Sjeff status = IB_SUCCESS; 591219820SjeffExit: 592219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 593219820Sjeff return (status); 594219820Sjeff} 595219820Sjeff 596219820Sjeff/********************************************************************** 597219820Sjeff **********************************************************************/ 598219820Sjeffvoid 599219820Sjeffosm_ca_info_destroy(IN osm_vendor_t * const p_vend, 600219820Sjeff IN osm_ca_info_t * const p_ca_info, IN uint8_t num_ca) 601219820Sjeff{ 602219820Sjeff osm_ca_info_t *p_ca; 603219820Sjeff uint8_t i; 604219820Sjeff 605219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 606219820Sjeff 607219820Sjeff for (i = 0; i < num_ca; i++) { 608219820Sjeff p_ca = &p_ca_info[i]; 609219820Sjeff 610219820Sjeff if (NULL != p_ca->p_attr) { 611219820Sjeff if (0 != p_ca->p_attr->num_ports) { 612219820Sjeff free(p_ca->p_attr->p_port_attr); 613219820Sjeff } 614219820Sjeff 615219820Sjeff free(p_ca->p_attr); 616219820Sjeff } 617219820Sjeff } 618219820Sjeff 619219820Sjeff free(p_ca_info); 620219820Sjeff 621219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 622219820Sjeff} 623219820Sjeff 624219820Sjeff/********************************************************************** 625219820Sjeff * Fill in the array of port_attr with all available ports on ALL the 626219820Sjeff * avilable CAs on this machine. 627219820Sjeff **********************************************************************/ 628219820Sjeffib_api_status_t 629219820Sjeffosm_vendor_get_all_port_attr(IN osm_vendor_t * const p_vend, 630219820Sjeff IN ib_port_attr_t * const p_attr_array, 631219820Sjeff IN uint32_t * const p_num_ports) 632219820Sjeff{ 633219820Sjeff ib_api_status_t status = IB_SUCCESS; 634219820Sjeff 635219820Sjeff uint32_t caIdx; 636219820Sjeff uint32_t ca_count = 0; 637219820Sjeff uint32_t port_count = 0; 638219820Sjeff uint8_t port_num; 639219820Sjeff uint32_t total_ports = 0; 640219820Sjeff osm_ca_info_t *p_ca_infos = NULL; 641219820Sjeff uint32_t attr_array_sz = *p_num_ports; 642219820Sjeff 643219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 644219820Sjeff 645219820Sjeff CL_ASSERT(p_vend); 646219820Sjeff 647219820Sjeff /* determine the number of CA's */ 648219820Sjeff ca_count = __hca_sim_get_num_cas(); 649219820Sjeff if (!ca_count) { 650219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 651219820Sjeff "osm_vendor_get_all_port_attr: ERR 5128: " 652219820Sjeff "Fail to get Any CA Ids.\n"); 653219820Sjeff goto Exit; 654219820Sjeff } 655219820Sjeff 656219820Sjeff /* Allocate an array big enough to hold the ca info objects */ 657219820Sjeff p_ca_infos = malloc(ca_count * sizeof(osm_ca_info_t)); 658219820Sjeff if (p_ca_infos == NULL) { 659219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 660219820Sjeff "osm_vendor_get_all_port_attr: ERR 5129: " 661219820Sjeff "Unable to allocate CA information array.\n"); 662219820Sjeff goto Exit; 663219820Sjeff } 664219820Sjeff 665219820Sjeff memset(p_ca_infos, 0, ca_count * sizeof(osm_ca_info_t)); 666219820Sjeff 667219820Sjeff /* 668219820Sjeff * For each CA, retrieve the CA info attributes 669219820Sjeff */ 670219820Sjeff for (caIdx = 1; caIdx <= ca_count; caIdx++) { 671219820Sjeff status = 672219820Sjeff __osm_ca_info_init(p_vend, caIdx, &p_ca_infos[caIdx - 1]); 673219820Sjeff if (status != IB_SUCCESS) { 674219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 675219820Sjeff "osm_vendor_get_all_port_attr: ERR 5130: " 676219820Sjeff "Unable to initialize CA Info object (%s).\n", 677219820Sjeff ib_get_err_str(status)); 678219820Sjeff goto Exit; 679219820Sjeff } 680219820Sjeff total_ports += p_ca_infos[caIdx - 1].p_attr->num_ports; 681219820Sjeff } 682219820Sjeff 683219820Sjeff *p_num_ports = total_ports; 684219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 685219820Sjeff "osm_vendor_get_all_port_attr: total ports:%u \n", total_ports); 686219820Sjeff 687219820Sjeff /* 688219820Sjeff * If the user supplied enough storage, return the port guids, 689219820Sjeff * otherwise, return the appropriate error. 690219820Sjeff */ 691219820Sjeff if (attr_array_sz >= total_ports) { 692219820Sjeff for (caIdx = 1; caIdx <= ca_count; caIdx++) { 693219820Sjeff uint32_t num_ports; 694219820Sjeff 695219820Sjeff num_ports = p_ca_infos[caIdx - 1].p_attr->num_ports; 696219820Sjeff 697219820Sjeff for (port_num = 0; port_num < num_ports; port_num++) { 698219820Sjeff p_attr_array[port_count] = 699219820Sjeff *__osm_ca_info_get_port_attr_ptr(&p_ca_infos 700219820Sjeff [caIdx - 701219820Sjeff 1], 702219820Sjeff port_num); 703219820Sjeff port_count++; 704219820Sjeff } 705219820Sjeff } 706219820Sjeff } else { 707219820Sjeff status = IB_INSUFFICIENT_MEMORY; 708219820Sjeff goto Exit; 709219820Sjeff } 710219820Sjeff 711219820Sjeff status = IB_SUCCESS; 712219820Sjeff 713219820SjeffExit: 714219820Sjeff if (p_ca_infos) { 715219820Sjeff osm_ca_info_destroy(p_vend, p_ca_infos, ca_count); 716219820Sjeff } 717219820Sjeff 718219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 719219820Sjeff return (status); 720219820Sjeff} 721219820Sjeff 722219820Sjeff/********************************************************************** 723219820Sjeff * Given the vendor obj and a port guid 724219820Sjeff * return the ca id and port number that have that guid 725219820Sjeff **********************************************************************/ 726219820Sjeff 727219820Sjeffib_api_status_t 728219820Sjeffosm_vendor_get_guid_ca_and_port(IN osm_vendor_t * const p_vend, 729219820Sjeff IN ib_net64_t const guid, 730219820Sjeff OUT uint32_t * p_hca_hndl, 731219820Sjeff OUT char *p_hca_id, 732219820Sjeff OUT uint8_t * p_hca_idx, 733219820Sjeff OUT uint32_t * p_port_num) 734219820Sjeff{ 735219820Sjeff uint32_t caIdx; 736219820Sjeff uint32_t ca_count = 0; 737219820Sjeff uint8_t port_num; 738219820Sjeff ib_api_status_t status = IB_ERROR; 739219820Sjeff 740219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 741219820Sjeff 742219820Sjeff CL_ASSERT(p_vend); 743219820Sjeff 744219820Sjeff /* determine the number of CA's */ 745219820Sjeff ca_count = __hca_sim_get_num_cas(); 746219820Sjeff if (!ca_count) { 747219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 748219820Sjeff "osm_vendor_get_guid_ca_and_port: ERR 5131: " 749219820Sjeff "Fail to get Any CA Ids.\n"); 750219820Sjeff goto Exit; 751219820Sjeff } 752219820Sjeff 753219820Sjeff /* 754219820Sjeff * For each CA, retrieve the CA info attributes 755219820Sjeff */ 756219820Sjeff for (caIdx = 1; caIdx <= ca_count; caIdx++) { 757219820Sjeff sim_ca_info_t sim_ca_info; 758219820Sjeff if (__parse_ca_info_file(p_vend, caIdx, &sim_ca_info) == 759219820Sjeff IB_SUCCESS) { 760219820Sjeff /* get all the ports info */ 761219820Sjeff for (port_num = 1; port_num <= sim_ca_info.num_ports; 762219820Sjeff port_num++) { 763219820Sjeff uint64_t port_guid; 764219820Sjeff if (!__get_port_guid_from_port_gid_tbl 765219820Sjeff (p_vend, caIdx, port_num, &port_guid)) { 766219820Sjeff if (cl_hton64(port_guid) == guid) { 767219820Sjeff osm_log(p_vend->p_log, 768219820Sjeff OSM_LOG_DEBUG, 769219820Sjeff "osm_vendor_get_guid_ca_and_port: " 770219820Sjeff "Found Matching guid on HCA:%d Port:%d.\n", 771219820Sjeff caIdx, port_num); 772219820Sjeff strcpy(p_hca_id, 773219820Sjeff sim_ca_info.name); 774219820Sjeff *p_port_num = port_num; 775219820Sjeff *p_hca_idx = caIdx - 1; 776219820Sjeff *p_hca_hndl = 0; 777219820Sjeff status = IB_SUCCESS; 778219820Sjeff goto Exit; 779219820Sjeff } 780219820Sjeff } 781219820Sjeff } 782219820Sjeff } 783219820Sjeff } 784219820Sjeff 785219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 786219820Sjeff "osm_vendor_get_guid_ca_and_port: ERR 5132: " 787219820Sjeff "Fail to find HCA and Port for Port Guid 0x%" PRIx64 "\n", 788219820Sjeff cl_ntoh64(guid)); 789219820Sjeff status = IB_INVALID_GUID; 790219820Sjeff 791219820SjeffExit: 792219820Sjeff 793219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 794219820Sjeff return (status); 795219820Sjeff} 796219820Sjeff 797219820Sjeff/********************************************************************** 798219820Sjeff * Given the vendor obj HCA ID and Port Num 799219820Sjeff * update the given port guid if found. Return 0 on success. 800219820Sjeff **********************************************************************/ 801219820Sjeff 802219820Sjeffib_api_status_t 803219820Sjeffosm_vendor_get_guid_by_ca_and_port(IN osm_vendor_t * const p_vend, 804219820Sjeff IN char *hca_id, 805219820Sjeff IN uint32_t port_num, 806219820Sjeff OUT uint64_t * p_port_guid) 807219820Sjeff{ 808219820Sjeff uint32_t caIdx; 809219820Sjeff uint32_t ca_count = 0; 810219820Sjeff ib_api_status_t status = IB_ERROR; 811219820Sjeff 812219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 813219820Sjeff 814219820Sjeff CL_ASSERT(p_vend); 815219820Sjeff 816219820Sjeff /* determine the number of CA's */ 817219820Sjeff ca_count = __hca_sim_get_num_cas(); 818219820Sjeff if (!ca_count) { 819219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 820219820Sjeff "osm_vendor_get_guid_by_ca_and_port: ERR 5133: " 821219820Sjeff "Fail to get Any CA Ids.\n"); 822219820Sjeff goto Exit; 823219820Sjeff } 824219820Sjeff 825219820Sjeff /* 826219820Sjeff * For each CA, retrieve the CA info attributes 827219820Sjeff */ 828219820Sjeff for (caIdx = 1; caIdx <= ca_count; caIdx++) { 829219820Sjeff sim_ca_info_t sim_ca_info; 830219820Sjeff if (__parse_ca_info_file(p_vend, caIdx, &sim_ca_info) == 831219820Sjeff IB_SUCCESS) { 832219820Sjeff /* if not identical by id - go to next one */ 833219820Sjeff if (strcmp(sim_ca_info.name, hca_id)) 834219820Sjeff continue; 835219820Sjeff 836219820Sjeff if ((port_num < 1) 837219820Sjeff || (port_num > sim_ca_info.num_ports)) { 838219820Sjeff return 1; 839219820Sjeff } 840219820Sjeff 841219820Sjeff if (!__get_port_guid_from_port_gid_tbl 842219820Sjeff (p_vend, caIdx, port_num, p_port_guid)) { 843219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 844219820Sjeff "osm_vendor_get_guid_by_ca_and_port: " 845219820Sjeff "Found Matching guid on HCA:%d Port:%d.\n", 846219820Sjeff caIdx, port_num); 847219820Sjeff status = IB_SUCCESS; 848219820Sjeff goto Exit; 849219820Sjeff } 850219820Sjeff } 851219820Sjeff } 852219820Sjeff 853219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 854219820Sjeff "osm_vendor_get_guid_by_ca_and_port: ERR 5134: " 855219820Sjeff "Fail to find HCA:%s\n", hca_id); 856219820Sjeff status = IB_INVALID_GUID; 857219820Sjeff 858219820SjeffExit: 859219820Sjeff 860219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 861219820Sjeff return (status); 862219820Sjeff} 863219820Sjeff 864219820Sjeff#endif 865