int ib_path_query_via(const struct ibmad_port *srcport, ibmad_gid_t srcgid, ibmad_gid_t destgid, ib_portid_t * sm_id, void *buf) { ib_sa_call_t sa = { 0 }; uint8_t *p; int dlid; memset(&sa, 0, sizeof sa); sa.method = IB_MAD_METHOD_GET; sa.attrid = IB_SA_ATTR_PATHRECORD; sa.mask = IB_PR_DEF_MASK; sa.trid = mad_trid(); memset(buf, 0, IB_SA_PR_RECSZ); mad_encode_field(buf, IB_SA_PR_DGID_F, destgid); mad_encode_field(buf, IB_SA_PR_SGID_F, srcgid); p = sa_rpc_call(srcport, buf, sm_id, &sa, 0); if (!p) { IBWARN("sa call path_query failed"); return -1; } mad_decode_field(p, IB_SA_PR_DLID_F, &dlid); return dlid; }
/** ========================================================================= * Resolve local CA characteristics using the umad layer rather than using * ib_resolve_self_via which requires SMP queries on the local port. */ int resolve_self(char *ca_name, uint8_t ca_port, ib_portid_t *portid, int *portnum, ibmad_gid_t *gid) { umad_port_t port; uint64_t prefix, guid; int rc; if (!(portid || portnum || gid)) return (-1); if ((rc = umad_get_port(ca_name, ca_port, &port)) < 0) return rc; if (portid) { memset(portid, 0, sizeof(*portid)); portid->lid = port.base_lid; portid->sl = port.sm_sl; } if (portnum) *portnum = port.portnum; if (gid) { memset(gid, 0, sizeof(*gid)); prefix = cl_hton64(port.gid_prefix); guid = cl_hton64(port.port_guid); mad_encode_field(*gid, IB_GID_PREFIX_F, &prefix); mad_encode_field(*gid, IB_GID_GUID_F, &guid); } umad_release_port(&port); return 0; }
int ib_resolve_self_via(ib_portid_t *portid, int *portnum, ibmad_gid_t *gid, const void *srcport) { ib_portid_t self = {0}; uint8_t portinfo[64]; uint8_t nodeinfo[64]; uint64_t guid, prefix; if (!smp_query_via(nodeinfo, &self, IB_ATTR_NODE_INFO, 0, 0, srcport)) return -1; if (!smp_query_via(portinfo, &self, IB_ATTR_PORT_INFO, 0, 0, srcport)) return -1; mad_decode_field(portinfo, IB_PORT_LID_F, &portid->lid); mad_decode_field(portinfo, IB_PORT_GID_PREFIX_F, &prefix); mad_decode_field(nodeinfo, IB_NODE_PORT_GUID_F, &guid); if (portnum) mad_decode_field(nodeinfo, IB_NODE_LOCAL_PORT_F, portnum); if (gid) { mad_encode_field(*gid, IB_GID_PREFIX_F, &prefix); mad_encode_field(*gid, IB_GID_GUID_F, &guid); } return 0; }
static char *congestion_key_info(ib_portid_t * dest, char **argv, int argc) { uint8_t rcv[IB_CC_DATA_SZ] = { 0 }; uint8_t payload[IB_CC_DATA_SZ] = { 0 }; uint64_t cc_key; uint32_t cc_keyprotectbit; uint32_t cc_keyleaseperiod; uint32_t cc_keyviolations; char *errstr; if (argc != 4) return "invalid number of parameters for CongestionKeyInfo"; if ((errstr = parselonglongint(argv[0], &cc_key))) return errstr; if ((errstr = parseint(argv[1], &cc_keyprotectbit, 0))) return errstr; if ((errstr = parseint(argv[2], &cc_keyleaseperiod, 0))) return errstr; if ((errstr = parseint(argv[3], &cc_keyviolations, 0))) return errstr; if (cc_keyprotectbit != 0 && cc_keyprotectbit != 1) return "invalid cc_keyprotectbit value"; if (cc_keyleaseperiod > USHRT_MAX) return "invalid cc_keyleaseperiod value"; if (cc_keyviolations > USHRT_MAX) return "invalid cc_keyviolations value"; mad_set_field64(payload, 0, IB_CC_CONGESTION_KEY_INFO_CC_KEY_F, cc_key); mad_encode_field(payload, IB_CC_CONGESTION_KEY_INFO_CC_KEY_PROTECT_BIT_F, &cc_keyprotectbit); mad_encode_field(payload, IB_CC_CONGESTION_KEY_INFO_CC_KEY_LEASE_PERIOD_F, &cc_keyleaseperiod); /* spec says "setting the counter to a value other than zero results * in the counter being left unchanged. So if user wants no change, * they gotta input non-zero */ mad_encode_field(payload, IB_CC_CONGESTION_KEY_INFO_CC_KEY_VIOLATIONS_F, &cc_keyviolations); if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_CONGESTION_KEY_INFO, 0, 0, NULL, srcport, cckey)) return "congestion key info config failed"; return NULL; }
static char *congestion_control_table(ib_portid_t * dest, char **argv, int argc) { uint8_t rcv[IB_CC_DATA_SZ] = { 0 }; uint8_t payload[IB_CC_DATA_SZ] = { 0 }; uint32_t ccti_limit; uint32_t index; uint32_t cctshifts[64]; uint32_t cctmults[64]; char *errstr; int i; if (argc < 2 || argc > 66) return "invalid number of parameters for CongestionControlTable"; if ((errstr = parseint(argv[0], &ccti_limit, 0))) return errstr; if ((errstr = parseint(argv[1], &index, 0))) return errstr; if (ccti_limit && (ccti_limit + 1) != (index * 64 + (argc - 2))) return "invalid number of cct entries input given ccti_limit and index"; for (i = 0; i < (argc - 2); i++) { if ((errstr = parsecct(argv[i + 2], &cctshifts[i], &cctmults[i]))) return errstr; } mad_encode_field(payload, IB_CC_CONGESTION_CONTROL_TABLE_CCTI_LIMIT_F, &ccti_limit); for (i = 0; i < (argc - 2); i++) { mad_encode_field(payload + 4 + i * 2, IB_CC_CONGESTION_CONTROL_TABLE_ENTRY_CCT_SHIFT_F, &cctshifts[i]); mad_encode_field(payload + 4 + i * 2, IB_CC_CONGESTION_CONTROL_TABLE_ENTRY_CCT_MULTIPLIER_F, &cctmults[i]); } if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_CONGESTION_CONTROL_TABLE, index, 0, NULL, srcport, cckey)) return "congestion control table config failed"; return NULL; }
static void output_aggregate_perfcounters_ext(ib_portid_t *portid) { char buf[1024]; uint32_t val = ALL_PORTS; /* set port_select to 255 to emulate AllPortSelect */ mad_encode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val); mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT_F, &perf_count_ext.counterselect); mad_encode_field(pc, IB_PC_EXT_XMT_BYTES_F, &perf_count_ext.portxmitdata); mad_encode_field(pc, IB_PC_EXT_RCV_BYTES_F, &perf_count_ext.portrcvdata); mad_encode_field(pc, IB_PC_EXT_XMT_PKTS_F, &perf_count_ext.portxmitpkts); mad_encode_field(pc, IB_PC_EXT_RCV_PKTS_F, &perf_count_ext.portrcvpkts); mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &perf_count_ext.portunicastxmitpkts); mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &perf_count_ext.portunicastrcvpkts); mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &perf_count_ext.portmulticastxmitpkits); mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &perf_count_ext.portmulticastrcvpkts); mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc); printf("# Port counters: %s port %d\n%s", portid2str(portid), ALL_PORTS, buf); }
static int ib_resolve_addr(ib_portid_t *portid, int portnum, int show_lid, int show_gid) { char gid_str[INET6_ADDRSTRLEN]; uint8_t portinfo[64]; uint8_t nodeinfo[64]; uint64_t guid, prefix; ibmad_gid_t gid; int lmc; if (!smp_query(nodeinfo, portid, IB_ATTR_NODE_INFO, 0, 0)) return -1; if (!smp_query(portinfo, portid, IB_ATTR_PORT_INFO, portnum, 0)) return -1; mad_decode_field(portinfo, IB_PORT_LID_F, &portid->lid); mad_decode_field(portinfo, IB_PORT_GID_PREFIX_F, &prefix); mad_decode_field(portinfo, IB_PORT_LMC_F, &lmc); mad_decode_field(nodeinfo, IB_NODE_PORT_GUID_F, &guid); mad_encode_field(gid, IB_GID_PREFIX_F, &prefix); mad_encode_field(gid, IB_GID_GUID_F, &guid); if (show_gid) { printf("GID %s ", inet_ntop(AF_INET6, gid, gid_str, sizeof gid_str)); } if (show_lid > 0) printf("LID start 0x%x end 0x%x", portid->lid, portid->lid + (1 << lmc) - 1); else if (show_lid < 0) printf("LID start %d end %d", portid->lid, portid->lid + (1 << lmc) - 1); printf("\n"); return 0; }
static void set_thres(char *name, uint32_t val) { int f; int n; char tmp[256]; for (f = IB_PC_FIRST_F; f <= IB_PC_LAST_F; f++) { if (strcmp(name, mad_field_name(f)) == 0) { mad_encode_field(thresholds, f, &val); snprintf(tmp, 255, "[%s = %u]", name, val); threshold_str = realloc(threshold_str, strlen(threshold_str)+strlen(tmp)+1); if (!threshold_str) { fprintf(stderr, "Failed to allocate memory: " "%s\n", strerror(errno)); exit(1); } n = strlen(threshold_str); strcpy(threshold_str+n, tmp); } } }
static int print_errors(ib_portid_t * portid, uint16_t cap_mask, char *node_name, ibnd_node_t * node, int portnum, int *header_printed) { uint8_t pc[1024]; uint8_t pce[1024]; uint8_t *pc_ext = NULL; memset(pc, 0, 1024); memset(pce, 0, 1024); portid->sl = lid2sl_table[portid->lid]; if (!pma_query_via(pc, portid, portnum, ibd_timeout, IB_GSI_PORT_COUNTERS, ibmad_port)) { IBWARN("IB_GSI_PORT_COUNTERS query failed on %s, %s port %d", node_name, portid2str(portid), portnum); summary.pma_query_failures++; return (0); } if (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP)) { if (!pma_query_via(pce, portid, portnum, ibd_timeout, IB_GSI_PORT_COUNTERS_EXT, ibmad_port)) { IBWARN("IB_GSI_PORT_COUNTERS_EXT query failed on %s, %s port %d", node_name, portid2str(portid), portnum); summary.pma_query_failures++; return (0); } pc_ext = pce; } if (!(cap_mask & IB_PM_PC_XMIT_WAIT_SUP)) { /* if PortCounters:PortXmitWait not supported clear this counter */ uint32_t foo = 0; mad_encode_field(pc, IB_PC_XMT_WAIT_F, &foo); } return (print_results(portid, node_name, node, pc, portnum, header_printed, pc_ext, cap_mask)); }
static int path_record_query(ib_gid_t sgid,uint64_t dguid) { ib_path_rec_t pr; ib_net64_t comp_mask = 0; uint8_t reversible = 0; struct sa_handle * h; h = sa_get_handle(); ibd_timeout = DEFAULT_HALF_WORLD_PR_TIMEOUT; memset(&pr, 0, sizeof(pr)); CHECK_AND_SET_GID(sgid, pr.sgid, PR, SGID); if(dguid) { mad_encode_field(sgid.raw, IB_GID_GUID_F, &dguid); CHECK_AND_SET_GID(sgid, pr.dgid, PR, DGID); } CHECK_AND_SET_VAL(1, 8, -1, pr.num_path, PR, NUMBPATH);/*to get only one PathRecord for each source and destination pair*/ CHECK_AND_SET_VAL(1, 8, -1, reversible, PR, REVERSIBLE);/*for a reversible path*/ pr.num_path |= reversible << 7; struct sa_query_result result; int ret = sa_query(h, IB_MAD_METHOD_GET_TABLE, (uint16_t)IB_SA_ATTR_PATHRECORD,0,cl_ntoh64(comp_mask),ibd_sakey, &pr, sizeof(pr), &result); if (ret) { fprintf(stderr, "Query SA failed: %s; sa call path_query failed\n", strerror(ret)); return ret; } if (result.status != IB_SA_MAD_STATUS_SUCCESS) { sa_report_err(result.status); ret = EIO; goto Exit; } insert_lid2sl_table(&result); Exit: sa_free_result_mad(&result); return ret; }
static void fillMAD_Get_PathRecord(UInt8 *umad, SInt64 len, UInt16 smLid, UInt64 guid, UInt64 trId) { UInt8 dgid[16]; memset(umad, 0, len); umad_set_addr(umad, smLid, MAD_QP1, MAD_DEFAULT_SL, IB_DEFAULT_QP1_QKEY); /* Ignore GRH */ mad_set_field (umad_get_mad(umad), 0, IB_MAD_METHOD_F, IB_MAD_METHOD_GET); mad_set_field (umad_get_mad(umad), 0, IB_MAD_CLASSVER_F, MAD_HEADER_CLASS_VERSION_SA); mad_set_field (umad_get_mad(umad), 0, IB_MAD_MGMTCLASS_F, IB_SA_CLASS); mad_set_field (umad_get_mad(umad), 0, IB_MAD_BASEVER_F, 1); mad_set_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F, trId); mad_set_field (umad_get_mad(umad), 0, IB_MAD_ATTRID_F, IB_SA_ATTR_PATHRECORD); mad_set_field64(umad_get_mad(umad), 0, IB_SA_COMPMASK_F, 0x4); mad_set_field64(dgid, 0, IB_GID_PREFIX_F, IB_DEFAULT_SUBN_PREFIX); mad_set_field64(dgid, 0, IB_GID_GUID_F , guid); /* 128 bit data */ mad_encode_field((UInt8 *)umad_get_mad(umad) + IB_SA_DATA_OFFS, IB_SA_PR_DGID_F, dgid); }
int ib_node_query_via(const struct ibmad_port *srcport, uint64_t guid, ib_portid_t * sm_id, void *buf) { ib_sa_call_t sa = { 0 }; uint8_t *p; memset(&sa, 0, sizeof sa); sa.method = IB_MAD_METHOD_GET; sa.attrid = IB_SA_ATTR_NODERECORD; sa.mask = IB_NR_DEF_MASK; sa.trid = mad_trid(); memset(buf, 0, IB_SA_NR_RECSZ); mad_encode_field(buf, IB_SA_NR_PORT_GUID_F, &guid); p = sa_rpc_call(srcport, buf, sm_id, &sa, 0); if (!p) { IBWARN("sa call node_query failed"); return -1; } return 0; }
static char *ca_congestion_setting(ib_portid_t * dest, char **argv, int argc) { uint8_t rcv[IB_CC_DATA_SZ] = { 0 }; uint8_t payload[IB_CC_DATA_SZ] = { 0 }; uint32_t port_control; uint32_t control_map; uint32_t ccti_timer; uint32_t ccti_increase; uint32_t trigger_threshold; uint32_t ccti_min; char *errstr; int i; if (argc != 6) return "invalid number of parameters for CACongestionSetting"; if ((errstr = parseint(argv[0], &port_control, 0))) return errstr; if ((errstr = parseint(argv[1], &control_map, 0))) return errstr; if ((errstr = parseint(argv[2], &ccti_timer, 0))) return errstr; if ((errstr = parseint(argv[3], &ccti_increase, 0))) return errstr; if ((errstr = parseint(argv[4], &trigger_threshold, 0))) return errstr; if ((errstr = parseint(argv[5], &ccti_min, 0))) return errstr; mad_encode_field(payload, IB_CC_CA_CONGESTION_SETTING_PORT_CONTROL_F, &port_control); mad_encode_field(payload, IB_CC_CA_CONGESTION_SETTING_CONTROL_MAP_F, &control_map); for (i = 0; i < 16; i++) { uint8_t *ptr; if (!(control_map & (0x1 << i))) continue; ptr = payload + 2 + 2 + i * 8; mad_encode_field(ptr, IB_CC_CA_CONGESTION_ENTRY_CCTI_TIMER_F, &ccti_timer); mad_encode_field(ptr, IB_CC_CA_CONGESTION_ENTRY_CCTI_INCREASE_F, &ccti_increase); mad_encode_field(ptr, IB_CC_CA_CONGESTION_ENTRY_TRIGGER_THRESHOLD_F, &trigger_threshold); mad_encode_field(ptr, IB_CC_CA_CONGESTION_ENTRY_CCTI_MIN_F, &ccti_min); } if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_CA_CONGESTION_SETTING, 0, 0, NULL, srcport, cckey)) return "ca congestion setting config failed"; return NULL; }
static char *switch_port_congestion_setting(ib_portid_t * dest, char **argv, int argc) { uint8_t rcv[IB_CC_DATA_SZ] = { 0 }; uint8_t payload[IB_CC_DATA_SZ] = { 0 }; uint8_t data[IB_CC_DATA_SZ] = { 0 }; uint32_t portnum; uint32_t valid; uint32_t control_type; uint32_t threshold; uint32_t packet_size; uint32_t cong_parm_marking_rate; uint32_t type; uint32_t numports; uint8_t *ptr; char *errstr; if (argc != 6) return "invalid number of parameters for SwitchPortCongestion"; if ((errstr = parseint(argv[0], &portnum, 0))) return errstr; if ((errstr = parseint(argv[1], &valid, 0))) return errstr; if ((errstr = parseint(argv[2], &control_type, 0))) return errstr; if ((errstr = parseint(argv[3], &threshold, 0))) return errstr; if ((errstr = parseint(argv[4], &packet_size, 0))) return errstr; if ((errstr = parseint(argv[5], &cong_parm_marking_rate, 0))) return errstr; /* Figure out number of ports first */ if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport)) return "node info config failed"; mad_decode_field((uint8_t *)data, IB_NODE_TYPE_F, &type); mad_decode_field((uint8_t *)data, IB_NODE_NPORTS_F, &numports); if (type != IB_NODE_SWITCH) return "destination not a switch"; if (portnum > numports) return "invalid port number specified"; /* We are modifying only 1 port, so get the current config */ if (!cc_query_status_via(payload, dest, IB_CC_ATTR_SWITCH_PORT_CONGESTION_SETTING, portnum / 32, 0, NULL, srcport, cckey)) return "switch port congestion setting query failed"; ptr = payload + (((portnum % 32) * 4)); mad_encode_field(ptr, IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_VALID_F, &valid); mad_encode_field(ptr, IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_CONTROL_TYPE_F, &control_type); mad_encode_field(ptr, IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_THRESHOLD_F, &threshold); mad_encode_field(ptr, IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_PACKET_SIZE_F, &packet_size); mad_encode_field(ptr, IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_CONG_PARM_MARKING_RATE_F, &cong_parm_marking_rate); if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_SWITCH_PORT_CONGESTION_SETTING, portnum / 32, 0, NULL, srcport, cckey)) return "switch port congestion setting config failed"; return NULL; }
static char *switch_congestion_setting(ib_portid_t * dest, char **argv, int argc) { uint8_t rcv[IB_CC_DATA_SZ] = { 0 }; uint8_t payload[IB_CC_DATA_SZ] = { 0 }; uint32_t control_map; uint8_t victim_mask[32] = { 0 }; uint8_t credit_mask[32] = { 0 }; uint32_t threshold; uint32_t packet_size; uint32_t cs_threshold; uint32_t cs_returndelay_s; uint32_t cs_returndelay_m; uint32_t cs_returndelay; uint32_t marking_rate; char *errstr; if (argc != 8) return "invalid number of parameters for SwitchCongestionSetting"; if ((errstr = parseint(argv[0], &control_map, 0))) return errstr; if ((errstr = parse256(argv[1], victim_mask))) return errstr; if ((errstr = parse256(argv[2], credit_mask))) return errstr; if ((errstr = parseint(argv[3], &threshold, 0))) return errstr; if ((errstr = parseint(argv[4], &packet_size, 0))) return errstr; if ((errstr = parseint(argv[5], &cs_threshold, 0))) return errstr; if ((errstr = parsecct(argv[6], &cs_returndelay_s, &cs_returndelay_m))) return errstr; cs_returndelay = cs_returndelay_m; cs_returndelay |= (cs_returndelay_s << 14); if ((errstr = parseint(argv[7], &marking_rate, 0))) return errstr; mad_encode_field(payload, IB_CC_SWITCH_CONGESTION_SETTING_CONTROL_MAP_F, &control_map); mad_set_array(payload, 0, IB_CC_SWITCH_CONGESTION_SETTING_VICTIM_MASK_F, victim_mask); mad_set_array(payload, 0, IB_CC_SWITCH_CONGESTION_SETTING_CREDIT_MASK_F, credit_mask); mad_encode_field(payload, IB_CC_SWITCH_CONGESTION_SETTING_THRESHOLD_F, &threshold); mad_encode_field(payload, IB_CC_SWITCH_CONGESTION_SETTING_PACKET_SIZE_F, &packet_size); mad_encode_field(payload, IB_CC_SWITCH_CONGESTION_SETTING_CS_THRESHOLD_F, &cs_threshold); mad_encode_field(payload, IB_CC_SWITCH_CONGESTION_SETTING_CS_RETURN_DELAY_F, &cs_returndelay); mad_encode_field(payload, IB_CC_SWITCH_CONGESTION_SETTING_MARKING_RATE_F, &marking_rate); if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_SWITCH_CONGESTION_SETTING, 0, 0, NULL, srcport, cckey)) return "switch congestion setting config failed"; return NULL; }
static void output_aggregate_perfcounters(ib_portid_t *portid) { char buf[1024]; uint32_t val = ALL_PORTS; /* set port_select to 255 to emulate AllPortSelect */ mad_encode_field(pc, IB_PC_PORT_SELECT_F, &val); mad_encode_field(pc, IB_PC_COUNTER_SELECT_F, &perf_count.counterselect); mad_encode_field(pc, IB_PC_ERR_SYM_F, &perf_count.symbolerrors); mad_encode_field(pc, IB_PC_LINK_RECOVERS_F, &perf_count.linkrecovers); mad_encode_field(pc, IB_PC_LINK_DOWNED_F, &perf_count.linkdowned); mad_encode_field(pc, IB_PC_ERR_RCV_F, &perf_count.rcverrors); mad_encode_field(pc, IB_PC_ERR_PHYSRCV_F, &perf_count.rcvremotephyerrors); mad_encode_field(pc, IB_PC_ERR_SWITCH_REL_F, &perf_count.rcvswrelayerrors); mad_encode_field(pc, IB_PC_XMT_DISCARDS_F, &perf_count.xmtdiscards); mad_encode_field(pc, IB_PC_ERR_XMTCONSTR_F, &perf_count.xmtconstrainterrors); mad_encode_field(pc, IB_PC_ERR_RCVCONSTR_F, &perf_count.rcvconstrainterrors); mad_encode_field(pc, IB_PC_ERR_LOCALINTEG_F, &perf_count.linkintegrityerrors); mad_encode_field(pc, IB_PC_ERR_EXCESS_OVR_F, &perf_count.excbufoverrunerrors); mad_encode_field(pc, IB_PC_VL15_DROPPED_F, &perf_count.vl15dropped); mad_encode_field(pc, IB_PC_XMT_BYTES_F, &perf_count.xmtdata); mad_encode_field(pc, IB_PC_RCV_BYTES_F, &perf_count.rcvdata); mad_encode_field(pc, IB_PC_XMT_PKTS_F, &perf_count.xmtpkts); mad_encode_field(pc, IB_PC_RCV_PKTS_F, &perf_count.rcvpkts); mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc); printf("# Port counters: %s port %d\n%s", portid2str(portid), ALL_PORTS, buf); }