1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2007 Xsigo Systems Inc. All rights reserved. 4219820Sjeff * 5219820Sjeff * This software is available to you under a choice of one of two 6219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 7219820Sjeff * General Public License (GPL) Version 2, available from the file 8219820Sjeff * COPYING in the main directory of this source tree, or the 9219820Sjeff * OpenIB.org BSD license below: 10219820Sjeff * 11219820Sjeff * Redistribution and use in source and binary forms, with or 12219820Sjeff * without modification, are permitted provided that the following 13219820Sjeff * conditions are met: 14219820Sjeff * 15219820Sjeff * - Redistributions of source code must retain the above 16219820Sjeff * copyright notice, this list of conditions and the following 17219820Sjeff * disclaimer. 18219820Sjeff * 19219820Sjeff * - Redistributions in binary form must reproduce the above 20219820Sjeff * copyright notice, this list of conditions and the following 21219820Sjeff * disclaimer in the documentation and/or other materials 22219820Sjeff * provided with the distribution. 23219820Sjeff * 24219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31219820Sjeff * SOFTWARE. 32219820Sjeff * 33219820Sjeff */ 34219820Sjeff 35219820Sjeff#if HAVE_CONFIG_H 36219820Sjeff# include <config.h> 37219820Sjeff#endif /* HAVE_CONFIG_H */ 38219820Sjeff 39219820Sjeff#include <stdio.h> 40219820Sjeff#include <stdlib.h> 41219820Sjeff#include <unistd.h> 42219820Sjeff#include <stdarg.h> 43219820Sjeff#include <getopt.h> 44219820Sjeff#include <netinet/in.h> 45219820Sjeff 46219820Sjeff#include <infiniband/common.h> 47219820Sjeff#include <infiniband/umad.h> 48219820Sjeff#include <infiniband/mad.h> 49219820Sjeff 50219820Sjeff#include "ibdiag_common.h" 51219820Sjeff 52219820Sjeffstruct perf_count { 53219820Sjeff uint32_t portselect; 54219820Sjeff uint32_t counterselect; 55219820Sjeff uint32_t symbolerrors; 56219820Sjeff uint32_t linkrecovers; 57219820Sjeff uint32_t linkdowned; 58219820Sjeff uint32_t rcverrors; 59219820Sjeff uint32_t rcvremotephyerrors; 60219820Sjeff uint32_t rcvswrelayerrors; 61219820Sjeff uint32_t xmtdiscards; 62219820Sjeff uint32_t xmtconstrainterrors; 63219820Sjeff uint32_t rcvconstrainterrors; 64219820Sjeff uint32_t linkintegrityerrors; 65219820Sjeff uint32_t excbufoverrunerrors; 66219820Sjeff uint32_t vl15dropped; 67219820Sjeff uint32_t xmtdata; 68219820Sjeff uint32_t rcvdata; 69219820Sjeff uint32_t xmtpkts; 70219820Sjeff uint32_t rcvpkts; 71219820Sjeff}; 72219820Sjeff 73219820Sjeffstruct perf_count_ext { 74219820Sjeff uint32_t portselect; 75219820Sjeff uint32_t counterselect; 76219820Sjeff uint64_t portxmitdata; 77219820Sjeff uint64_t portrcvdata; 78219820Sjeff uint64_t portxmitpkts; 79219820Sjeff uint64_t portrcvpkts; 80219820Sjeff uint64_t portunicastxmitpkts; 81219820Sjeff uint64_t portunicastrcvpkts; 82219820Sjeff uint64_t portmulticastxmitpkits; 83219820Sjeff uint64_t portmulticastrcvpkts; 84219820Sjeff}; 85219820Sjeff 86219820Sjeffstatic uint8_t pc[1024]; 87219820Sjeff 88219820Sjeffstruct perf_count perf_count = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 89219820Sjeffstruct perf_count_ext perf_count_ext = {0,0,0,0,0,0,0,0,0,0}; 90219820Sjeff 91219820Sjeffchar *argv0 = "perfquery"; 92219820Sjeff 93219820Sjeff#define ALL_PORTS 0xFF 94219820Sjeff 95219820Sjeffstatic void 96219820Sjeffusage(void) 97219820Sjeff{ 98219820Sjeff char *basename; 99219820Sjeff 100219820Sjeff if (!(basename = strrchr(argv0, '/'))) 101219820Sjeff basename = argv0; 102219820Sjeff else 103219820Sjeff basename++; 104219820Sjeff 105219820Sjeff fprintf(stderr, "Usage: %s [-d(ebug) -G(uid) -a(ll_ports) -l(oop_ports) -r(eset_after_read) -C ca_name -P ca_port " 106219820Sjeff "-R(eset_only) -t(imeout) timeout_ms -V(ersion) -h(elp)] [<lid|guid> [[port] [reset_mask]]]\n", 107219820Sjeff basename); 108219820Sjeff fprintf(stderr, "\tExamples:\n"); 109219820Sjeff fprintf(stderr, "\t\t%s\t\t# read local port's performance counters\n", basename); 110219820Sjeff fprintf(stderr, "\t\t%s 32 1\t\t# read performance counters from lid 32, port 1\n", basename); 111219820Sjeff fprintf(stderr, "\t\t%s -e 32 1\t# read extended performance counters from lid 32, port 1\n", basename); 112219820Sjeff fprintf(stderr, "\t\t%s -a 32\t\t# read performance counters from lid 32, all ports\n", basename); 113219820Sjeff fprintf(stderr, "\t\t%s -r 32 1\t# read performance counters and reset\n", basename); 114219820Sjeff fprintf(stderr, "\t\t%s -e -r 32 1\t# read extended performance counters and reset\n", basename); 115219820Sjeff fprintf(stderr, "\t\t%s -R 0x20 1\t# reset performance counters of port 1 only\n", basename); 116219820Sjeff fprintf(stderr, "\t\t%s -e -R 0x20 1\t# reset extended performance counters of port 1 only\n", basename); 117219820Sjeff fprintf(stderr, "\t\t%s -R -a 32\t# reset performance counters of all ports\n", basename); 118219820Sjeff fprintf(stderr, "\t\t%s -R 32 2 0x0fff\t# reset only error counters of port 2\n", basename); 119219820Sjeff fprintf(stderr, "\t\t%s -R 32 2 0xf000\t# reset only non-error counters of port 2\n", basename); 120219820Sjeff exit(-1); 121219820Sjeff} 122219820Sjeff 123219820Sjeff/* Notes: IB semantics is to cap counters if count has exceeded limits. 124219820Sjeff * Therefore we must check for overflows and cap the counters if necessary. 125219820Sjeff * 126219820Sjeff * mad_decode_field and mad_encode_field assume 32 bit integers passed in 127219820Sjeff * for fields < 32 bits in length. 128219820Sjeff */ 129219820Sjeff 130219820Sjeffstatic void aggregate_4bit(uint32_t *dest, uint32_t val) 131219820Sjeff{ 132219820Sjeff if ((((*dest) + val) < (*dest)) 133219820Sjeff || ((*dest) + val) > 0xf) 134219820Sjeff (*dest) = 0xf; 135219820Sjeff else 136219820Sjeff (*dest) = (*dest) + val; 137219820Sjeff} 138219820Sjeff 139219820Sjeffstatic void aggregate_8bit(uint32_t *dest, uint32_t val) 140219820Sjeff{ 141219820Sjeff if ((((*dest) + val) < (*dest)) 142219820Sjeff || ((*dest) + val) > 0xff) 143219820Sjeff (*dest) = 0xff; 144219820Sjeff else 145219820Sjeff (*dest) = (*dest) + val; 146219820Sjeff} 147219820Sjeff 148219820Sjeffstatic void aggregate_16bit(uint32_t *dest, uint32_t val) 149219820Sjeff{ 150219820Sjeff if ((((*dest) + val) < (*dest)) 151219820Sjeff || ((*dest) + val) > 0xffff) 152219820Sjeff (*dest) = 0xffff; 153219820Sjeff else 154219820Sjeff (*dest) = (*dest) + val; 155219820Sjeff} 156219820Sjeff 157219820Sjeffstatic void aggregate_32bit(uint32_t *dest, uint32_t val) 158219820Sjeff{ 159219820Sjeff if (((*dest) + val) < (*dest)) 160219820Sjeff (*dest) = 0xffffffff; 161219820Sjeff else 162219820Sjeff (*dest) = (*dest) + val; 163219820Sjeff} 164219820Sjeff 165219820Sjeffstatic void aggregate_64bit(uint64_t *dest, uint64_t val) 166219820Sjeff{ 167219820Sjeff if (((*dest) + val) < (*dest)) 168219820Sjeff (*dest) = 0xffffffffffffffffULL; 169219820Sjeff else 170219820Sjeff (*dest) = (*dest) + val; 171219820Sjeff} 172219820Sjeff 173219820Sjeffstatic void aggregate_perfcounters(void) 174219820Sjeff{ 175219820Sjeff uint32_t val; 176219820Sjeff 177219820Sjeff mad_decode_field(pc, IB_PC_PORT_SELECT_F, &val); 178219820Sjeff perf_count.portselect = val; 179219820Sjeff mad_decode_field(pc, IB_PC_COUNTER_SELECT_F, &val); 180219820Sjeff perf_count.counterselect = val; 181219820Sjeff mad_decode_field(pc, IB_PC_ERR_SYM_F, &val); 182219820Sjeff aggregate_16bit(&perf_count.symbolerrors, val); 183219820Sjeff mad_decode_field(pc, IB_PC_LINK_RECOVERS_F, &val); 184219820Sjeff aggregate_8bit(&perf_count.linkrecovers, val); 185219820Sjeff mad_decode_field(pc, IB_PC_LINK_DOWNED_F, &val); 186219820Sjeff aggregate_8bit(&perf_count.linkdowned, val); 187219820Sjeff mad_decode_field(pc, IB_PC_ERR_RCV_F, &val); 188219820Sjeff aggregate_16bit(&perf_count.rcverrors, val); 189219820Sjeff mad_decode_field(pc, IB_PC_ERR_PHYSRCV_F, &val); 190219820Sjeff aggregate_16bit(&perf_count.rcvremotephyerrors, val); 191219820Sjeff mad_decode_field(pc, IB_PC_ERR_SWITCH_REL_F, &val); 192219820Sjeff aggregate_16bit(&perf_count.rcvswrelayerrors, val); 193219820Sjeff mad_decode_field(pc, IB_PC_XMT_DISCARDS_F, &val); 194219820Sjeff aggregate_16bit(&perf_count.xmtdiscards, val); 195219820Sjeff mad_decode_field(pc, IB_PC_ERR_XMTCONSTR_F, &val); 196219820Sjeff aggregate_8bit(&perf_count.xmtconstrainterrors, val); 197219820Sjeff mad_decode_field(pc, IB_PC_ERR_RCVCONSTR_F, &val); 198219820Sjeff aggregate_8bit(&perf_count.rcvconstrainterrors, val); 199219820Sjeff mad_decode_field(pc, IB_PC_ERR_LOCALINTEG_F, &val); 200219820Sjeff aggregate_4bit(&perf_count.linkintegrityerrors, val); 201219820Sjeff mad_decode_field(pc, IB_PC_ERR_EXCESS_OVR_F, &val); 202219820Sjeff aggregate_4bit(&perf_count.excbufoverrunerrors, val); 203219820Sjeff mad_decode_field(pc, IB_PC_VL15_DROPPED_F, &val); 204219820Sjeff aggregate_16bit(&perf_count.vl15dropped, val); 205219820Sjeff mad_decode_field(pc, IB_PC_XMT_BYTES_F, &val); 206219820Sjeff aggregate_32bit(&perf_count.xmtdata, val); 207219820Sjeff mad_decode_field(pc, IB_PC_RCV_BYTES_F, &val); 208219820Sjeff aggregate_32bit(&perf_count.rcvdata, val); 209219820Sjeff mad_decode_field(pc, IB_PC_XMT_PKTS_F, &val); 210219820Sjeff aggregate_32bit(&perf_count.xmtpkts, val); 211219820Sjeff mad_decode_field(pc, IB_PC_RCV_PKTS_F, &val); 212219820Sjeff aggregate_32bit(&perf_count.rcvpkts, val); 213219820Sjeff} 214219820Sjeff 215219820Sjeffstatic void output_aggregate_perfcounters(ib_portid_t *portid) 216219820Sjeff{ 217219820Sjeff char buf[1024]; 218219820Sjeff uint32_t val = ALL_PORTS; 219219820Sjeff 220219820Sjeff /* set port_select to 255 to emulate AllPortSelect */ 221219820Sjeff mad_encode_field(pc, IB_PC_PORT_SELECT_F, &val); 222219820Sjeff mad_encode_field(pc, IB_PC_COUNTER_SELECT_F, &perf_count.counterselect); 223219820Sjeff mad_encode_field(pc, IB_PC_ERR_SYM_F, &perf_count.symbolerrors); 224219820Sjeff mad_encode_field(pc, IB_PC_LINK_RECOVERS_F, &perf_count.linkrecovers); 225219820Sjeff mad_encode_field(pc, IB_PC_LINK_DOWNED_F, &perf_count.linkdowned); 226219820Sjeff mad_encode_field(pc, IB_PC_ERR_RCV_F, &perf_count.rcverrors); 227219820Sjeff mad_encode_field(pc, IB_PC_ERR_PHYSRCV_F, &perf_count.rcvremotephyerrors); 228219820Sjeff mad_encode_field(pc, IB_PC_ERR_SWITCH_REL_F, &perf_count.rcvswrelayerrors); 229219820Sjeff mad_encode_field(pc, IB_PC_XMT_DISCARDS_F, &perf_count.xmtdiscards); 230219820Sjeff mad_encode_field(pc, IB_PC_ERR_XMTCONSTR_F, &perf_count.xmtconstrainterrors); 231219820Sjeff mad_encode_field(pc, IB_PC_ERR_RCVCONSTR_F, &perf_count.rcvconstrainterrors); 232219820Sjeff mad_encode_field(pc, IB_PC_ERR_LOCALINTEG_F, &perf_count.linkintegrityerrors); 233219820Sjeff mad_encode_field(pc, IB_PC_ERR_EXCESS_OVR_F, &perf_count.excbufoverrunerrors); 234219820Sjeff mad_encode_field(pc, IB_PC_VL15_DROPPED_F, &perf_count.vl15dropped); 235219820Sjeff mad_encode_field(pc, IB_PC_XMT_BYTES_F, &perf_count.xmtdata); 236219820Sjeff mad_encode_field(pc, IB_PC_RCV_BYTES_F, &perf_count.rcvdata); 237219820Sjeff mad_encode_field(pc, IB_PC_XMT_PKTS_F, &perf_count.xmtpkts); 238219820Sjeff mad_encode_field(pc, IB_PC_RCV_PKTS_F, &perf_count.rcvpkts); 239219820Sjeff 240219820Sjeff mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc); 241219820Sjeff 242219820Sjeff printf("# Port counters: %s port %d\n%s", portid2str(portid), ALL_PORTS, buf); 243219820Sjeff} 244219820Sjeff 245219820Sjeffstatic void aggregate_perfcounters_ext(void) 246219820Sjeff{ 247219820Sjeff uint32_t val; 248219820Sjeff uint64_t val64; 249219820Sjeff 250219820Sjeff mad_decode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val); 251219820Sjeff perf_count_ext.portselect = val; 252219820Sjeff mad_decode_field(pc, IB_PC_EXT_COUNTER_SELECT_F, &val); 253219820Sjeff perf_count_ext.counterselect = val; 254219820Sjeff mad_decode_field(pc, IB_PC_EXT_XMT_BYTES_F, &val64); 255219820Sjeff aggregate_64bit(&perf_count_ext.portxmitdata, val64); 256219820Sjeff mad_decode_field(pc, IB_PC_EXT_RCV_BYTES_F, &val64); 257219820Sjeff aggregate_64bit(&perf_count_ext.portrcvdata, val64); 258219820Sjeff mad_decode_field(pc, IB_PC_EXT_XMT_PKTS_F, &val64); 259219820Sjeff aggregate_64bit(&perf_count_ext.portxmitpkts, val64); 260219820Sjeff mad_decode_field(pc, IB_PC_EXT_RCV_PKTS_F, &val64); 261219820Sjeff aggregate_64bit(&perf_count_ext.portrcvpkts, val64); 262219820Sjeff mad_decode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &val64); 263219820Sjeff aggregate_64bit(&perf_count_ext.portunicastxmitpkts, val64); 264219820Sjeff mad_decode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &val64); 265219820Sjeff aggregate_64bit(&perf_count_ext.portunicastrcvpkts, val64); 266219820Sjeff mad_decode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &val64); 267219820Sjeff aggregate_64bit(&perf_count_ext.portmulticastxmitpkits, val64); 268219820Sjeff mad_decode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &val64); 269219820Sjeff aggregate_64bit(&perf_count_ext.portmulticastrcvpkts, val64); 270219820Sjeff} 271219820Sjeff 272219820Sjeffstatic void output_aggregate_perfcounters_ext(ib_portid_t *portid) 273219820Sjeff{ 274219820Sjeff char buf[1024]; 275219820Sjeff uint32_t val = ALL_PORTS; 276219820Sjeff 277219820Sjeff /* set port_select to 255 to emulate AllPortSelect */ 278219820Sjeff mad_encode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val); 279219820Sjeff mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT_F, &perf_count_ext.counterselect); 280219820Sjeff mad_encode_field(pc, IB_PC_EXT_XMT_BYTES_F, &perf_count_ext.portxmitdata); 281219820Sjeff mad_encode_field(pc, IB_PC_EXT_RCV_BYTES_F, &perf_count_ext.portrcvdata); 282219820Sjeff mad_encode_field(pc, IB_PC_EXT_XMT_PKTS_F, &perf_count_ext.portxmitpkts); 283219820Sjeff mad_encode_field(pc, IB_PC_EXT_RCV_PKTS_F, &perf_count_ext.portrcvpkts); 284219820Sjeff mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &perf_count_ext.portunicastxmitpkts); 285219820Sjeff mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &perf_count_ext.portunicastrcvpkts); 286219820Sjeff mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &perf_count_ext.portmulticastxmitpkits); 287219820Sjeff mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &perf_count_ext.portmulticastrcvpkts); 288219820Sjeff 289219820Sjeff mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc); 290219820Sjeff 291219820Sjeff printf("# Port counters: %s port %d\n%s", portid2str(portid), ALL_PORTS, buf); 292219820Sjeff} 293219820Sjeff 294219820Sjeffstatic void dump_perfcounters(int extended, int timeout, uint16_t cap_mask, ib_portid_t *portid, 295219820Sjeff int port, int aggregate) 296219820Sjeff{ 297219820Sjeff char buf[1024]; 298219820Sjeff 299219820Sjeff if (extended != 1) { 300219820Sjeff if (!port_performance_query(pc, portid, port, timeout)) 301219820Sjeff IBERROR("perfquery"); 302219820Sjeff if (aggregate) 303219820Sjeff aggregate_perfcounters(); 304219820Sjeff else 305219820Sjeff mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc); 306219820Sjeff } else { 307219820Sjeff if (!(cap_mask & 0x200)) /* 1.2 errata: bit 9 is extended counter support */ 308219820Sjeff IBWARN("PerfMgt ClassPortInfo 0x%x extended counters not indicated\n", cap_mask); 309219820Sjeff 310219820Sjeff if (!port_performance_ext_query(pc, portid, port, timeout)) 311219820Sjeff IBERROR("perfextquery"); 312219820Sjeff if (aggregate) 313219820Sjeff aggregate_perfcounters_ext(); 314219820Sjeff else 315219820Sjeff mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc); 316219820Sjeff } 317219820Sjeff 318219820Sjeff if (!aggregate) 319219820Sjeff printf("# Port counters: %s port %d\n%s", portid2str(portid), port, buf); 320219820Sjeff} 321219820Sjeff 322219820Sjeffstatic void reset_counters(int extended, int timeout, int mask, ib_portid_t *portid, int port) 323219820Sjeff{ 324219820Sjeff if (extended != 1) { 325219820Sjeff if (!port_performance_reset(pc, portid, port, mask, timeout)) 326219820Sjeff IBERROR("perf reset"); 327219820Sjeff } else { 328219820Sjeff if (!port_performance_ext_reset(pc, portid, port, mask, timeout)) 329219820Sjeff IBERROR("perf ext reset"); 330219820Sjeff } 331219820Sjeff} 332219820Sjeff 333219820Sjeffint 334219820Sjeffmain(int argc, char **argv) 335219820Sjeff{ 336219820Sjeff int mgmt_classes[4] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS, IB_PERFORMANCE_CLASS}; 337219820Sjeff ib_portid_t *sm_id = 0, sm_portid = {0}; 338219820Sjeff ib_portid_t portid = {0}; 339219820Sjeff extern int ibdebug; 340219820Sjeff int dest_type = IB_DEST_LID; 341219820Sjeff int timeout = 0; /* use default */ 342219820Sjeff int mask = 0xffff, all_ports = 0; 343219820Sjeff int reset = 0, reset_only = 0; 344219820Sjeff int port = 0; 345219820Sjeff int udebug = 0; 346219820Sjeff char *ca = 0; 347219820Sjeff int ca_port = 0; 348219820Sjeff int extended = 0; 349219820Sjeff uint16_t cap_mask; 350219820Sjeff int all_ports_loop = 0; 351219820Sjeff int loop_ports = 0; 352219820Sjeff int node_type, num_ports = 0; 353219820Sjeff uint8_t data[IB_SMP_DATA_SIZE]; 354219820Sjeff int start_port = 1; 355219820Sjeff int enhancedport0; 356219820Sjeff int i; 357219820Sjeff 358219820Sjeff static char const str_opts[] = "C:P:s:t:dGealrRVhu"; 359219820Sjeff static const struct option long_opts[] = { 360219820Sjeff { "C", 1, 0, 'C'}, 361219820Sjeff { "P", 1, 0, 'P'}, 362219820Sjeff { "debug", 0, 0, 'd'}, 363219820Sjeff { "Guid", 0, 0, 'G'}, 364219820Sjeff { "extended", 0, 0, 'e'}, 365219820Sjeff { "all_ports", 0, 0, 'a'}, 366219820Sjeff { "loop_ports", 0, 0, 'l'}, 367219820Sjeff { "reset_after_read", 0, 0, 'r'}, 368219820Sjeff { "Reset_only", 0, 0, 'R'}, 369219820Sjeff { "sm_portid", 1, 0, 's'}, 370219820Sjeff { "timeout", 1, 0, 't'}, 371219820Sjeff { "Version", 0, 0, 'V'}, 372219820Sjeff { "help", 0, 0, 'h'}, 373219820Sjeff { "usage", 0, 0, 'u'}, 374219820Sjeff { } 375219820Sjeff }; 376219820Sjeff 377219820Sjeff argv0 = argv[0]; 378219820Sjeff 379219820Sjeff while (1) { 380219820Sjeff int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); 381219820Sjeff if ( ch == -1 ) 382219820Sjeff break; 383219820Sjeff switch(ch) { 384219820Sjeff case 'C': 385219820Sjeff ca = optarg; 386219820Sjeff break; 387219820Sjeff case 'P': 388219820Sjeff ca_port = strtoul(optarg, 0, 0); 389219820Sjeff break; 390219820Sjeff case 'e': 391219820Sjeff extended = 1; 392219820Sjeff break; 393219820Sjeff case 'a': 394219820Sjeff all_ports++; 395219820Sjeff port = ALL_PORTS; 396219820Sjeff break; 397219820Sjeff case 'l': 398219820Sjeff loop_ports++; 399219820Sjeff break; 400219820Sjeff case 'd': 401219820Sjeff ibdebug++; 402219820Sjeff madrpc_show_errors(1); 403219820Sjeff umad_debug(udebug); 404219820Sjeff udebug++; 405219820Sjeff break; 406219820Sjeff case 'G': 407219820Sjeff dest_type = IB_DEST_GUID; 408219820Sjeff break; 409219820Sjeff case 's': 410219820Sjeff if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0) 411219820Sjeff IBERROR("can't resolve SM destination port %s", optarg); 412219820Sjeff sm_id = &sm_portid; 413219820Sjeff break; 414219820Sjeff case 'r': 415219820Sjeff reset++; 416219820Sjeff break; 417219820Sjeff case 'R': 418219820Sjeff reset_only++; 419219820Sjeff break; 420219820Sjeff case 't': 421219820Sjeff timeout = strtoul(optarg, 0, 0); 422219820Sjeff madrpc_set_timeout(timeout); 423219820Sjeff break; 424219820Sjeff case 'V': 425219820Sjeff fprintf(stderr, "%s %s\n", argv0, get_build_version() ); 426219820Sjeff exit(-1); 427219820Sjeff default: 428219820Sjeff usage(); 429219820Sjeff break; 430219820Sjeff } 431219820Sjeff } 432219820Sjeff argc -= optind; 433219820Sjeff argv += optind; 434219820Sjeff 435219820Sjeff if (argc > 1) 436219820Sjeff port = strtoul(argv[1], 0, 0); 437219820Sjeff if (argc > 2) 438219820Sjeff mask = strtoul(argv[2], 0, 0); 439219820Sjeff 440219820Sjeff madrpc_init(ca, ca_port, mgmt_classes, 4); 441219820Sjeff 442219820Sjeff if (argc) { 443219820Sjeff if (ib_resolve_portid_str(&portid, argv[0], dest_type, sm_id) < 0) 444219820Sjeff IBERROR("can't resolve destination port %s", argv[0]); 445219820Sjeff } else { 446219820Sjeff if (ib_resolve_self(&portid, &port, 0) < 0) 447219820Sjeff IBERROR("can't resolve self port %s", argv[0]); 448219820Sjeff } 449219820Sjeff 450219820Sjeff /* PerfMgt ClassPortInfo is a required attribute */ 451219820Sjeff if (!perf_classportinfo_query(pc, &portid, port, timeout)) 452219820Sjeff IBERROR("classportinfo query"); 453219820Sjeff /* ClassPortInfo should be supported as part of libibmad */ 454219820Sjeff memcpy(&cap_mask, pc+2, sizeof(cap_mask)); /* CapabilityMask */ 455219820Sjeff cap_mask = ntohs(cap_mask); 456219820Sjeff if (!(cap_mask & 0x100)) { /* bit 8 is AllPortSelect */ 457219820Sjeff if (!all_ports && port == ALL_PORTS) 458219820Sjeff IBERROR("AllPortSelect not supported"); 459219820Sjeff if (all_ports) 460219820Sjeff all_ports_loop = 1; 461219820Sjeff } 462219820Sjeff 463219820Sjeff if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) { 464219820Sjeff if (smp_query(data, &portid, IB_ATTR_NODE_INFO, 0, 0) < 0) 465219820Sjeff IBERROR("smp query nodeinfo failed"); 466219820Sjeff node_type = mad_get_field(data, 0, IB_NODE_TYPE_F); 467219820Sjeff mad_decode_field(data, IB_NODE_NPORTS_F, &num_ports); 468219820Sjeff if (!num_ports) 469219820Sjeff IBERROR("smp query nodeinfo: num ports invalid"); 470219820Sjeff 471219820Sjeff if (node_type == IB_NODE_SWITCH) { 472219820Sjeff if (smp_query(data, &portid, IB_ATTR_SWITCH_INFO, 0, 0) < 0) 473219820Sjeff IBERROR("smp query nodeinfo failed"); 474219820Sjeff enhancedport0 = mad_get_field(data, 0, IB_SW_ENHANCED_PORT0_F); 475219820Sjeff if (enhancedport0) 476219820Sjeff start_port = 0; 477219820Sjeff } 478219820Sjeff if (all_ports_loop && !loop_ports) 479219820Sjeff IBWARN("Emulating AllPortSelect by iterating through all ports"); 480219820Sjeff } 481219820Sjeff 482219820Sjeff if (reset_only) 483219820Sjeff goto do_reset; 484219820Sjeff 485219820Sjeff if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) { 486219820Sjeff for (i = start_port; i <= num_ports; i++) 487219820Sjeff dump_perfcounters(extended, timeout, cap_mask, &portid, i, 488219820Sjeff (all_ports_loop && !loop_ports)); 489219820Sjeff if (all_ports_loop && !loop_ports) { 490219820Sjeff if (extended != 1) 491219820Sjeff output_aggregate_perfcounters(&portid); 492219820Sjeff else 493219820Sjeff output_aggregate_perfcounters_ext(&portid); 494219820Sjeff } 495219820Sjeff } 496219820Sjeff else 497219820Sjeff dump_perfcounters(extended, timeout, cap_mask, &portid, port, 0); 498219820Sjeff 499219820Sjeff if (!reset) 500219820Sjeff exit(0); 501219820Sjeff 502219820Sjeffdo_reset: 503219820Sjeff 504219820Sjeff if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) { 505219820Sjeff for (i = start_port; i <= num_ports; i++) 506219820Sjeff reset_counters(extended, timeout, mask, &portid, i); 507219820Sjeff } 508219820Sjeff else 509219820Sjeff reset_counters(extended, timeout, mask, &portid, port); 510219820Sjeff 511219820Sjeff exit(0); 512219820Sjeff} 513