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