1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved. 3219820Sjeff * 4219820Sjeff * This software is available to you under a choice of one of two 5219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 6219820Sjeff * General Public License (GPL) Version 2, available from the file 7219820Sjeff * COPYING in the main directory of this source tree, or the 8219820Sjeff * OpenIB.org BSD license below: 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or 11219820Sjeff * without modification, are permitted provided that the following 12219820Sjeff * conditions are met: 13219820Sjeff * 14219820Sjeff * - Redistributions of source code must retain the above 15219820Sjeff * copyright notice, this list of conditions and the following 16219820Sjeff * disclaimer. 17219820Sjeff * 18219820Sjeff * - Redistributions in binary form must reproduce the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer in the documentation and/or other materials 21219820Sjeff * provided with the distribution. 22219820Sjeff * 23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30219820Sjeff * SOFTWARE. 31219820Sjeff * 32219820Sjeff */ 33219820Sjeff 34219820Sjeff#define _GNU_SOURCE 35219820Sjeff 36219820Sjeff#if HAVE_CONFIG_H 37219820Sjeff# include <config.h> 38219820Sjeff#endif /* HAVE_CONFIG_H */ 39219820Sjeff 40219820Sjeff#include <inttypes.h> 41219820Sjeff#include <string.h> 42219820Sjeff#include <errno.h> 43219820Sjeff#include <stdio.h> 44219820Sjeff#include <stdlib.h> 45219820Sjeff#include <unistd.h> 46219820Sjeff#include <stdarg.h> 47219820Sjeff#include <sys/types.h> 48219820Sjeff#include <sys/stat.h> 49219820Sjeff#include <fcntl.h> 50219820Sjeff#include <sys/ioctl.h> 51219820Sjeff#include <unistd.h> 52219820Sjeff#include <string.h> 53219820Sjeff#include <getopt.h> 54219820Sjeff#include <endian.h> 55219820Sjeff#include <byteswap.h> 56219820Sjeff#include <sys/poll.h> 57219820Sjeff#include <syslog.h> 58219820Sjeff#include <netinet/in.h> 59219820Sjeff 60219820Sjeff#include <infiniband/common.h> 61219820Sjeff#include <infiniband/umad.h> 62219820Sjeff#include <infiniband/mad.h> 63219820Sjeff 64219820Sjeff#include <ibdiag_common.h> 65219820Sjeff 66219820Sjeffstatic int debug; 67219820Sjeff 68219820Sjeffchar *argv0 = "ibstat"; 69219820Sjeff 70219820Sjeffstatic char *node_type_str[] = { 71219820Sjeff "???", 72219820Sjeff "CA", 73219820Sjeff "Switch", 74219820Sjeff "Router", 75219820Sjeff "iWARP RNIC" 76219820Sjeff}; 77219820Sjeff 78219820Sjeffstatic void 79219820Sjeffca_dump(umad_ca_t *ca) 80219820Sjeff{ 81219820Sjeff if (!ca->node_type) 82219820Sjeff return; 83219820Sjeff printf("%s '%s'\n", ((uint)ca->node_type <= IB_NODE_MAX ? node_type_str[ca->node_type] : "???"), ca->ca_name); 84219820Sjeff printf("\t%s type: %s\n", ((uint)ca->node_type <= IB_NODE_MAX ? node_type_str[ca->node_type] : "???"),ca->ca_type); 85219820Sjeff printf("\tNumber of ports: %d\n", ca->numports); 86219820Sjeff printf("\tFirmware version: %s\n", ca->fw_ver); 87219820Sjeff printf("\tHardware version: %s\n", ca->hw_ver); 88219820Sjeff printf("\tNode GUID: 0x%016llx\n", (long long unsigned)ntohll(ca->node_guid)); 89219820Sjeff printf("\tSystem image GUID: 0x%016llx\n", (long long unsigned)ntohll(ca->system_guid)); 90219820Sjeff} 91219820Sjeff 92219820Sjeffstatic char *port_state_str[] = { 93219820Sjeff "???", 94219820Sjeff "Down", 95219820Sjeff "Initializing", 96219820Sjeff "Armed", 97219820Sjeff "Active" 98219820Sjeff}; 99219820Sjeff 100219820Sjeffstatic char *port_phy_state_str[] = { 101219820Sjeff "No state change", 102219820Sjeff "Sleep", 103219820Sjeff "Polling", 104219820Sjeff "Disabled", 105219820Sjeff "PortConfigurationTraining", 106219820Sjeff "LinkUp", 107219820Sjeff "LinkErrorRecovery", 108219820Sjeff "PhyTest" 109219820Sjeff}; 110219820Sjeff 111219820Sjeffstatic int 112219820Sjeffport_dump(umad_port_t *port, int alone) 113219820Sjeff{ 114219820Sjeff char *pre = ""; 115219820Sjeff char *hdrpre = ""; 116219820Sjeff 117219820Sjeff if (!port) 118219820Sjeff return -1; 119219820Sjeff 120219820Sjeff if (!alone) { 121219820Sjeff pre = " "; 122219820Sjeff hdrpre = " "; 123219820Sjeff } 124219820Sjeff 125219820Sjeff printf("%sPort %d:\n", hdrpre, port->portnum); 126219820Sjeff printf("%sState: %s\n", pre, (uint)port->state <= 4 ? port_state_str[port->state] : "???"); 127219820Sjeff printf("%sPhysical state: %s\n", pre, (uint)port->state <= 7 ? port_phy_state_str[port->phys_state] : "???"); 128219820Sjeff printf("%sRate: %d\n", pre, port->rate); 129219820Sjeff printf("%sBase lid: %d\n", pre, port->base_lid); 130219820Sjeff printf("%sLMC: %d\n", pre, port->lmc); 131219820Sjeff printf("%sSM lid: %d\n", pre, port->sm_lid); 132219820Sjeff printf("%sCapability mask: 0x%08x\n", pre, (unsigned)ntohl(port->capmask)); 133219820Sjeff printf("%sPort GUID: 0x%016llx\n", pre, (long long unsigned)ntohll(port->port_guid)); 134219820Sjeff return 0; 135219820Sjeff} 136219820Sjeff 137219820Sjeffstatic int 138219820Sjeffca_stat(char *ca_name, int portnum, int no_ports) 139219820Sjeff{ 140219820Sjeff umad_ca_t ca; 141219820Sjeff int r; 142219820Sjeff 143219820Sjeff if ((r = umad_get_ca(ca_name, &ca)) < 0) 144219820Sjeff return r; 145219820Sjeff 146219820Sjeff if (!ca.node_type) 147219820Sjeff return 0; 148219820Sjeff 149219820Sjeff if (!no_ports && portnum >= 0) { 150219820Sjeff if (portnum > ca.numports || !ca.ports[portnum]) { 151219820Sjeff IBWARN("%s: '%s' has no port number %d - max (%d)", 152219820Sjeff ((uint)ca.node_type <= IB_NODE_MAX ? node_type_str[ca.node_type] : "???"), 153219820Sjeff ca_name, portnum, ca.numports); 154219820Sjeff return -1; 155219820Sjeff } 156219820Sjeff printf("%s: '%s'\n", ((uint)ca.node_type <= IB_NODE_MAX ? node_type_str[ca.node_type] : "???"), ca.ca_name); 157219820Sjeff port_dump(ca.ports[portnum], 1); 158219820Sjeff return 0; 159219820Sjeff } 160219820Sjeff 161219820Sjeff /* print ca header */ 162219820Sjeff ca_dump(&ca); 163219820Sjeff 164219820Sjeff if (no_ports) 165219820Sjeff return 0; 166219820Sjeff 167219820Sjeff for (portnum = 0; portnum <= ca.numports; portnum++) 168219820Sjeff port_dump(ca.ports[portnum], 0); 169219820Sjeff 170219820Sjeff return 0; 171219820Sjeff} 172219820Sjeff 173219820Sjeffstatic int 174219820Sjeffports_list(char names[][UMAD_CA_NAME_LEN], int n) 175219820Sjeff{ 176219820Sjeff uint64_t guids[64]; 177219820Sjeff int found, ports, i; 178219820Sjeff 179219820Sjeff for (i = 0, found = 0; i < n && found < 64; i++) { 180219820Sjeff if ((ports = umad_get_ca_portguids(names[i], guids + found, 64 - found)) < 0) 181219820Sjeff return -1; 182219820Sjeff found += ports; 183219820Sjeff } 184219820Sjeff 185219820Sjeff for (i = 0; i < found; i++) 186219820Sjeff if (guids[i]) 187219820Sjeff printf("0x%016llx\n", (long long unsigned)ntohll(guids[i])); 188219820Sjeff return found; 189219820Sjeff} 190219820Sjeff 191219820Sjeffvoid 192219820Sjeffusage(void) 193219820Sjeff{ 194219820Sjeff fprintf(stderr, "Usage: %s [-d(ebug) -l(ist_of_cas) -s(hort) -p(ort_list) -V(ersion)] <ca_name> [portnum]\n", argv0); 195219820Sjeff fprintf(stderr, "\tExamples:\n"); 196219820Sjeff fprintf(stderr, "\t\t%s -l # list all IB devices\n", argv0); 197219820Sjeff fprintf(stderr, "\t\t%s mthca0 2 # stat port 2 of 'mthca0'\n", argv0); 198219820Sjeff exit(-1); 199219820Sjeff} 200219820Sjeff 201219820Sjeffint 202219820Sjeffmain(int argc, char *argv[]) 203219820Sjeff{ 204219820Sjeff char names[UMAD_MAX_DEVICES][UMAD_CA_NAME_LEN]; 205219820Sjeff int dev_port = -1; 206219820Sjeff int list_only = 0, short_format = 0, list_ports = 0; 207219820Sjeff int n, i; 208219820Sjeff 209219820Sjeff static char const str_opts[] = "dlspVhu"; 210219820Sjeff static const struct option long_opts[] = { 211219820Sjeff { "debug", 0, 0, 'd'}, 212219820Sjeff { "list_of_cas", 0, 0, 'l'}, 213219820Sjeff { "short", 0, 0, 's'}, 214219820Sjeff { "port_list", 0, 0, 'p'}, 215219820Sjeff { "Version", 0, 0, 'V'}, 216219820Sjeff { "help", 0, 0, 'h'}, 217219820Sjeff { "usage", 0, 0, 'u'}, 218219820Sjeff { } 219219820Sjeff }; 220219820Sjeff 221219820Sjeff argv0 = argv[0]; 222219820Sjeff 223219820Sjeff while (1) { 224219820Sjeff int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); 225219820Sjeff if ( ch == -1 ) 226219820Sjeff break; 227219820Sjeff switch(ch) { 228219820Sjeff case 'd': 229219820Sjeff debug++; 230219820Sjeff break; 231219820Sjeff case 'l': 232219820Sjeff list_only++; 233219820Sjeff break; 234219820Sjeff case 's': 235219820Sjeff short_format++; 236219820Sjeff break; 237219820Sjeff case 'p': 238219820Sjeff list_ports++; 239219820Sjeff break; 240219820Sjeff case 'V': 241219820Sjeff fprintf(stderr, "%s %s\n", argv0, get_build_version() ); 242219820Sjeff exit(-1); 243219820Sjeff default: 244219820Sjeff usage(); 245219820Sjeff break; 246219820Sjeff } 247219820Sjeff } 248219820Sjeff argc -= optind; 249219820Sjeff argv += optind; 250219820Sjeff 251219820Sjeff if (argc > 1) 252219820Sjeff dev_port = strtol(argv[1], 0, 0); 253219820Sjeff 254219820Sjeff if (umad_init() < 0) 255219820Sjeff IBPANIC("can't init UMAD library"); 256219820Sjeff 257219820Sjeff if ((n = umad_get_cas_names(names, UMAD_MAX_DEVICES)) < 0) 258219820Sjeff IBPANIC("can't list IB device names"); 259219820Sjeff 260219820Sjeff if (argc) { 261219820Sjeff for (i = 0; i < n; i++) 262219820Sjeff if (!strncmp(names[i], argv[0], sizeof names[i])) 263219820Sjeff break; 264219820Sjeff if (i >= n) 265219820Sjeff IBPANIC("'%s' IB device can't be found", argv[0]); 266219820Sjeff 267219820Sjeff strncpy(names[i], argv[0], sizeof names[i]); 268219820Sjeff n = 1; 269219820Sjeff } 270219820Sjeff 271219820Sjeff if (list_ports) { 272219820Sjeff if (ports_list(names, n) < 0) 273219820Sjeff IBPANIC("can't list ports"); 274219820Sjeff return 0; 275219820Sjeff } 276219820Sjeff 277219820Sjeff if (!list_only && argc) { 278219820Sjeff if (ca_stat(argv[0], dev_port, short_format) < 0) 279219820Sjeff IBPANIC("stat of IB device '%s' failed", argv[0]); 280219820Sjeff return 0; 281219820Sjeff } 282219820Sjeff 283219820Sjeff for (i = 0; i < n; i++) { 284219820Sjeff if (list_only) 285219820Sjeff printf("%s\n", names[i]); 286219820Sjeff else 287219820Sjeff if (ca_stat(names[i], -1, short_format) < 0) 288219820Sjeff IBPANIC("stat of IB device '%s' failed", names[i]); 289219820Sjeff } 290219820Sjeff 291219820Sjeff return 0; 292219820Sjeff} 293