11558Srgrimes/* 21558Srgrimes * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved. 31558Srgrimes * 41558Srgrimes * This software is available to you under a choice of one of two 51558Srgrimes * licenses. You may choose to be licensed under the terms of the GNU 61558Srgrimes * General Public License (GPL) Version 2, available from the file 71558Srgrimes * COPYING in the main directory of this source tree, or the 81558Srgrimes * OpenIB.org BSD license below: 91558Srgrimes * 101558Srgrimes * Redistribution and use in source and binary forms, with or 111558Srgrimes * without modification, are permitted provided that the following 121558Srgrimes * conditions are met: 131558Srgrimes * 141558Srgrimes * - Redistributions of source code must retain the above 151558Srgrimes * copyright notice, this list of conditions and the following 161558Srgrimes * disclaimer. 171558Srgrimes * 181558Srgrimes * - Redistributions in binary form must reproduce the above 191558Srgrimes * copyright notice, this list of conditions and the following 201558Srgrimes * disclaimer in the documentation and/or other materials 211558Srgrimes * provided with the distribution. 221558Srgrimes * 231558Srgrimes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 241558Srgrimes * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 251558Srgrimes * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 261558Srgrimes * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 271558Srgrimes * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 281558Srgrimes * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 291558Srgrimes * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 301558Srgrimes * SOFTWARE. 311558Srgrimes * 321558Srgrimes */ 331558Srgrimes 3437663Scharnier#define _GNU_SOURCE 351558Srgrimes 361558Srgrimes#if HAVE_CONFIG_H 372999Swollman# include <config.h> 381558Srgrimes#endif /* HAVE_CONFIG_H */ 39105267Scharnier 401558Srgrimes#include <inttypes.h> 4137663Scharnier#include <string.h> 42105267Scharnier#include <errno.h> 4337663Scharnier#include <stdio.h> 441558Srgrimes#include <stdlib.h> 45105267Scharnier#include <unistd.h> 46105267Scharnier#include <stdarg.h> 47105267Scharnier#include <sys/types.h> 481558Srgrimes#include <sys/stat.h> 491558Srgrimes#include <fcntl.h> 5074462Salfred#include <sys/ioctl.h> 511558Srgrimes#include <unistd.h> 521558Srgrimes#include <string.h> 5324330Sguido#include <getopt.h> 5496622Siedowse#include <endian.h> 5596622Siedowse#include <byteswap.h> 561558Srgrimes#include <sys/poll.h> 571558Srgrimes#include <syslog.h> 58109363Smbr#include <netinet/in.h> 591558Srgrimes 6074462Salfred#include <infiniband/common.h> 6174462Salfred#include <infiniband/umad.h> 621558Srgrimes#include <infiniband/mad.h> 639336Sdfr 6483653Speter#include <ibdiag_common.h> 6523681Speter 6677162Srustatic int debug; 6777223Sru 6823681Speterchar *argv0 = "ibstat"; 691558Srgrimes 701558Srgrimesstatic char *node_type_str[] = { 711558Srgrimes "???", 721558Srgrimes "CA", 7337663Scharnier "Switch", 741558Srgrimes "Router", 751558Srgrimes "iWARP RNIC" 76103949Smike}; 771558Srgrimes 781558Srgrimesstatic void 791558Srgrimesca_dump(umad_ca_t *ca) 801558Srgrimes{ 811558Srgrimes if (!ca->node_type) 821558Srgrimes return; 831558Srgrimes printf("%s '%s'\n", ((uint)ca->node_type <= IB_NODE_MAX ? node_type_str[ca->node_type] : "???"), ca->ca_name); 841558Srgrimes printf("\t%s type: %s\n", ((uint)ca->node_type <= IB_NODE_MAX ? node_type_str[ca->node_type] : "???"),ca->ca_type); 851558Srgrimes printf("\tNumber of ports: %d\n", ca->numports); 861558Srgrimes printf("\tFirmware version: %s\n", ca->fw_ver); 871558Srgrimes printf("\tHardware version: %s\n", ca->hw_ver); 881558Srgrimes printf("\tNode GUID: 0x%016llx\n", (long long unsigned)ntohll(ca->node_guid)); 891558Srgrimes printf("\tSystem image GUID: 0x%016llx\n", (long long unsigned)ntohll(ca->system_guid)); 9074462Salfred} 9174462Salfred 9274462Salfredstatic char *port_state_str[] = { 9374462Salfred "???", 941558Srgrimes "Down", 951558Srgrimes "Initializing", 961558Srgrimes "Armed", 971558Srgrimes "Active" 981558Srgrimes}; 991558Srgrimes 1001558Srgrimesstatic char *port_phy_state_str[] = { 1011558Srgrimes "No state change", 1021558Srgrimes "Sleep", 1031558Srgrimes "Polling", 1041558Srgrimes "Disabled", 1051558Srgrimes "PortConfigurationTraining", 1061558Srgrimes "LinkUp", 1071558Srgrimes "LinkErrorRecovery", 1081558Srgrimes "PhyTest" 1091558Srgrimes}; 1101558Srgrimes 1111558Srgrimesstatic int 1129336Sdfrport_dump(umad_port_t *port, int alone) 1131558Srgrimes{ 1141558Srgrimes char *pre = ""; 1151558Srgrimes char *hdrpre = ""; 1161558Srgrimes 1171558Srgrimes if (!port) 1181558Srgrimes return -1; 1191558Srgrimes 1201558Srgrimes if (!alone) { 12127447Sdfr pre = " "; 1221558Srgrimes hdrpre = " "; 1231558Srgrimes } 1241558Srgrimes 1251558Srgrimes printf("%sPort %d:\n", hdrpre, port->portnum); 1261558Srgrimes printf("%sState: %s\n", pre, (uint)port->state <= 4 ? port_state_str[port->state] : "???"); 12774462Salfred printf("%sPhysical state: %s\n", pre, (uint)port->state <= 7 ? port_phy_state_str[port->phys_state] : "???"); 12875801Siedowse printf("%sRate: %d\n", pre, port->rate); 12942144Sdfr printf("%sBase lid: %d\n", pre, port->base_lid); 1301558Srgrimes printf("%sLMC: %d\n", pre, port->lmc); 1311558Srgrimes printf("%sSM lid: %d\n", pre, port->sm_lid); 1321558Srgrimes printf("%sCapability mask: 0x%08x\n", pre, (unsigned)ntohl(port->capmask)); 13374462Salfred printf("%sPort GUID: 0x%016llx\n", pre, (long long unsigned)ntohll(port->port_guid)); 1341558Srgrimes return 0; 1351558Srgrimes} 1361558Srgrimes 1371558Srgrimesstatic int 1381558Srgrimesca_stat(char *ca_name, int portnum, int no_ports) 1391558Srgrimes{ 1401558Srgrimes umad_ca_t ca; 1411558Srgrimes int r; 1421558Srgrimes 1431558Srgrimes if ((r = umad_get_ca(ca_name, &ca)) < 0) 1441558Srgrimes return r; 1451558Srgrimes 14675641Siedowse if (!ca.node_type) 1477401Swpaul return 0; 1481558Srgrimes 1491558Srgrimes if (!no_ports && portnum >= 0) { 1509336Sdfr if (portnum > ca.numports || !ca.ports[portnum]) { 1511558Srgrimes IBWARN("%s: '%s' has no port number %d - max (%d)", 1521558Srgrimes ((uint)ca.node_type <= IB_NODE_MAX ? node_type_str[ca.node_type] : "???"), 1531558Srgrimes ca_name, portnum, ca.numports); 1541558Srgrimes return -1; 1559336Sdfr } 1569336Sdfr printf("%s: '%s'\n", ((uint)ca.node_type <= IB_NODE_MAX ? node_type_str[ca.node_type] : "???"), ca.ca_name); 1579336Sdfr port_dump(ca.ports[portnum], 1); 1589336Sdfr return 0; 1599336Sdfr } 1609336Sdfr 1611558Srgrimes /* print ca header */ 16292882Simp ca_dump(&ca); 16392882Simp 16492882Simp if (no_ports) 16592882Simp return 0; 16692882Simp 16792882Simp for (portnum = 0; portnum <= ca.numports; portnum++) 16875801Siedowse port_dump(ca.ports[portnum], 0); 16992882Simp 17075635Siedowse return 0; 17192882Simp} 17292882Simp 17392882Simpstatic int 17492882Simpports_list(char names[][UMAD_CA_NAME_LEN], int n) 17592882Simp{ 17692882Simp uint64_t guids[64]; 17792882Simp int found, ports, i; 17892882Simp 17992882Simp for (i = 0, found = 0; i < n && found < 64; i++) { 18092882Simp if ((ports = umad_get_ca_portguids(names[i], guids + found, 64 - found)) < 0) 18192882Simp return -1; 18292882Simp found += ports; 18392882Simp } 18492882Simp 18592882Simp for (i = 0; i < found; i++) 18692882Simp if (guids[i]) 18792882Simp printf("0x%016llx\n", (long long unsigned)ntohll(guids[i])); 18892882Simp return found; 18992882Simp} 19092882Simp 19192882Simpvoid 19275754Siedowseusage(void) 19375801Siedowse{ 19492882Simp fprintf(stderr, "Usage: %s [-d(ebug) -l(ist_of_cas) -s(hort) -p(ort_list) -V(ersion)] <ca_name> [portnum]\n", argv0); 19592882Simp fprintf(stderr, "\tExamples:\n"); 19692882Simp fprintf(stderr, "\t\t%s -l # list all IB devices\n", argv0); 19792882Simp fprintf(stderr, "\t\t%s mthca0 2 # stat port 2 of 'mthca0'\n", argv0); 198100117Salfred exit(-1); 19975801Siedowse} 20075801Siedowse 20175801Siedowseint 20292882Simpmain(int argc, char *argv[]) 20392882Simp{ 20492882Simp char names[UMAD_MAX_DEVICES][UMAD_CA_NAME_LEN]; 20592882Simp int dev_port = -1; 206100117Salfred int list_only = 0, short_format = 0, list_ports = 0; 20792882Simp int n, i; 20892882Simp 20992882Simp static char const str_opts[] = "dlspVhu"; 2101558Srgrimes static const struct option long_opts[] = { 2111558Srgrimes { "debug", 0, 0, 'd'}, 2121558Srgrimes { "list_of_cas", 0, 0, 'l'}, 2131558Srgrimes { "short", 0, 0, 's'}, 2141558Srgrimes { "port_list", 0, 0, 'p'}, 21572650Sgreen { "Version", 0, 0, 'V'}, 21691354Sdd { "help", 0, 0, 'h'}, 21772650Sgreen { "usage", 0, 0, 'u'}, 2181558Srgrimes { } 21972650Sgreen }; 22072650Sgreen 2211558Srgrimes argv0 = argv[0]; 22225087Sdfr 2239336Sdfr while (1) { 2249336Sdfr int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); 225121767Speter if ( ch == -1 ) 22675754Siedowse break; 22774462Salfred switch(ch) { 2281558Srgrimes case 'd': 22974462Salfred debug++; 23074462Salfred break; 23174462Salfred case 'l': 23274462Salfred list_only++; 23374462Salfred break; 23474462Salfred case 's': 23574462Salfred short_format++; 23674462Salfred break; 23775801Siedowse case 'p': 2381558Srgrimes list_ports++; 2391558Srgrimes break; 24083653Speter case 'V': 2411558Srgrimes fprintf(stderr, "%s %s\n", argv0, get_build_version() ); 2421558Srgrimes exit(-1); 2431558Srgrimes default: 24475801Siedowse usage(); 245100336Sjoerg break; 24674462Salfred } 2471558Srgrimes } 2481558Srgrimes argc -= optind; 2491558Srgrimes argv += optind; 25092882Simp 2511558Srgrimes if (argc > 1) 2521558Srgrimes dev_port = strtol(argv[1], 0, 0); 2531558Srgrimes 2541558Srgrimes if (umad_init() < 0) 2551558Srgrimes IBPANIC("can't init UMAD library"); 2561558Srgrimes 2571558Srgrimes if ((n = umad_get_cas_names(names, UMAD_MAX_DEVICES)) < 0) 2581558Srgrimes IBPANIC("can't list IB device names"); 2591558Srgrimes 2601558Srgrimes if (argc) { 2611558Srgrimes for (i = 0; i < n; i++) 2621558Srgrimes if (!strncmp(names[i], argv[0], sizeof names[i])) 2631558Srgrimes break; 2641558Srgrimes if (i >= n) 2651558Srgrimes IBPANIC("'%s' IB device can't be found", argv[0]); 2661558Srgrimes 2671558Srgrimes strncpy(names[i], argv[0], sizeof names[i]); 26875754Siedowse n = 1; 269126572Sbms } 270126572Sbms 271126572Sbms if (list_ports) { 27274462Salfred if (ports_list(names, n) < 0) 27374462Salfred IBPANIC("can't list ports"); 27474462Salfred return 0; 27574462Salfred } 276109363Smbr 27774462Salfred if (!list_only && argc) { 278126572Sbms if (ca_stat(argv[0], dev_port, short_format) < 0) 279126572Sbms IBPANIC("stat of IB device '%s' failed", argv[0]); 2801558Srgrimes return 0; 28175635Siedowse } 282126643Smarkm 28375635Siedowse for (i = 0; i < n; i++) { 28474462Salfred if (list_only) 28574462Salfred printf("%s\n", names[i]); 28674462Salfred else 28774462Salfred if (ca_stat(names[i], -1, short_format) < 0) 28874462Salfred IBPANIC("stat of IB device '%s' failed", names[i]); 289105267Scharnier } 29074462Salfred 29174462Salfred return 0; 29274462Salfred} 29374462Salfred