diff options
author | Roland Dreier <rolandd@cisco.com> | 2005-08-30 17:38:18 +0000 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-11-09 11:35:57 -0800 |
commit | 24b7e9ddd4e4ab0027254665ee6015d77a1f4207 (patch) | |
tree | 54f79ceb5284563854adb07c93ff6a936f27c91b | |
parent | c3e80354b4153374aed3efe11a288f5ae039470d (diff) | |
download | libibverbs-24b7e9ddd4e4ab0027254665ee6015d77a1f4207.tar.gz |
Merge Dotan Barak's vstat tool into ibv_devinfo
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | examples/devinfo.c | 397 |
3 files changed, 353 insertions, 48 deletions
@@ -1 +1,2 @@ Roland Dreier <roland@topspin.com> +Dotan Barak <dotanb@mellanox.co.il> @@ -0,0 +1,3 @@ +2005-08-30 Roland Dreier <roland@cisco.com> + + * examples/devinfo.c: Merge with Dotan Barak's vstat tool. diff --git a/examples/devinfo.c b/examples/devinfo.c index e0a0f66..e6ec4f3 100644 --- a/examples/devinfo.c +++ b/examples/devinfo.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2005 Cisco Systems. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -37,6 +38,11 @@ #endif /* HAVE_CONFIG_H */ #include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <getopt.h> +#include <netinet/in.h> #include <endian.h> #include <byteswap.h> @@ -48,67 +54,362 @@ static inline uint64_t be64_to_cpu(uint64_t x) { return bswap_64(x); } static inline uint64_t be64_to_cpu(uint64_t x) { return x; } #endif -int main(int argc, char *argv[]) +static int verbose = 0; + +static int null_gid(union ibv_gid *gid) { - struct dlist *dev_list; - struct ibv_device *ib_dev; - struct ibv_context *context; - struct ibv_device_attr attr; - struct ibv_port_attr pattr; - int i; + return !(gid->raw[8] | gid->raw[9] | gid->raw[10] | gid->raw[11] | + gid->raw[12] | gid->raw[13] | gid->raw[14] | gid->raw[15]); +} - dev_list = ibv_get_devices(); - if (!dev_list) { - fprintf(stderr, "No IB devices found\n"); - return 1; +static const char *guid_str(uint64_t node_guid, char *str) +{ + node_guid = be64_to_cpu(node_guid); + sprintf(str, "%04x:%04x:%04x:%04x", + (unsigned) (node_guid >> 48) & 0xffff, + (unsigned) (node_guid >> 32) & 0xffff, + (unsigned) (node_guid >> 16) & 0xffff, + (unsigned) (node_guid >> 0) & 0xffff); + return str; +} + +static const char *port_state_str(enum ibv_port_state pstate) +{ + switch (pstate) { + case IBV_PORT_DOWN: return "PORT_DOWN"; + case IBV_PORT_INIT: return "PORT_INIT"; + case IBV_PORT_ARMED: return "PORT_ARMED"; + case IBV_PORT_ACTIVE: return "PORT_ACTIVE"; + default: return "invalid state"; } +} - dlist_start(dev_list); - ib_dev = dlist_next(dev_list); +static const char *port_phy_state_str(uint8_t phys_state) +{ + switch (phys_state) { + case 1: return "SLEEP"; + case 2: return "POLLING"; + case 3: return "DISABLED"; + case 4: return "PORT_CONFIGURATION TRAINNING"; + case 5: return "LINK_UP"; + case 6: return "LINK_ERROR_RECOVERY"; + case 7: return "PHY TEST"; + default: return "invalid physical state"; + } +} + +static const char *atomic_cap_str(enum ibv_atomic_cap atom_cap) +{ + switch (atom_cap) { + case IBV_ATOMIC_NONE: return "ATOMIC_NONE"; + case IBV_ATOMIC_HCA: return "ATOMIC_HCA"; + case IBV_ATOMIC_GLOB: return "ATOMIC_GLOB"; + default: return "invalid atomic capability"; + } +} - if (!ib_dev) { - fprintf(stderr, "No IB devices found\n"); - return 1; +static const char *mtu_str(enum ibv_mtu max_mtu) +{ + switch (max_mtu) { + case IBV_MTU_256: return "256"; + case IBV_MTU_512: return "512"; + case IBV_MTU_1024: return "1024"; + case IBV_MTU_2048: return "2048"; + case IBV_MTU_4096: return "4096"; + default: return "invalid MTU"; } +} - context = ibv_open_device(ib_dev); - if (!context) { - fprintf(stderr, "Couldn't get context for %s\n", - ibv_get_device_name(ib_dev)); - return 1; +static const char *width_str(uint8_t width) +{ + switch (width) { + case 1: return "1"; + case 2: return "4"; + case 4: return "8"; + case 8: return "12"; + default: return "invalid width"; } +} - if (ibv_query_device(context, &attr)) { - fprintf(stderr, "Couldn't query device for %s\n", - ibv_get_device_name(ib_dev)); - return 1; +static const char *speed_str(uint8_t speed) +{ + switch (speed) { + case 1: return "2.5 Gbps"; + case 2: return "5.0 Gbps"; + case 4: return "10.0 Gbps"; + default: return "invalid speed"; } +} + +static int print_all_port_gids(struct ibv_context *ctx, uint8_t port_num, int tbl_len) +{ + union ibv_gid gid; + int rc = 0; + int i; - printf("%s properties:\n", ibv_get_device_name(ib_dev)); - printf("\tNum ports:\t%d\n", attr.phys_port_cnt); - printf("\tNode GUID:\t%016llx\n", be64_to_cpu(attr.node_guid)); - printf("\tMax QPs:\t%d\n", attr.max_qp); - printf("\tMax CQs:\t%d\n", attr.max_cq); - printf("\tMax PDs:\t%d\n", attr.max_pd); - printf("\tMax AHs:\t%d\n", attr.max_ah); - - for (i = 1; i <= attr.phys_port_cnt; i++) { - if(ibv_query_port(context, i, &pattr)) { - fprintf(stderr, "Couldn't query port %d\n", i); - continue; + for (i = 0; i < tbl_len; i++) { + rc = ibv_query_gid(ctx, port_num, i, &gid); + if (rc) { + fprintf(stderr, "Failed to query gid to port %d, index %d\n", + port_num, i); + return rc; } + if (!null_gid(&gid)) + printf("\t\t\tGID[%3d]:\t\t%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + i, + ntohs(*((uint16_t *) gid.raw + 0)), + ntohs(*((uint16_t *) gid.raw + 1)), + ntohs(*((uint16_t *) gid.raw + 2)), + ntohs(*((uint16_t *) gid.raw + 3)), + ntohs(*((uint16_t *) gid.raw + 4)), + ntohs(*((uint16_t *) gid.raw + 5)), + ntohs(*((uint16_t *) gid.raw + 6)), + ntohs(*((uint16_t *) gid.raw + 7))); + } + return rc; +} - printf("\n\tPort %d properties:\n", i); - printf("\t\tState:\t\t\t%d\n", pattr.state); - printf("\t\tLID:\t\t\t%d\n", pattr.lid); - printf("\t\tMax MTU:\t\t%d\n", pattr.max_mtu); - printf("\t\tActive MTU:\t\t%d\n", pattr.active_mtu); - printf("\t\tGID table length:\t%d\n", pattr.gid_tbl_len); - printf("\t\tPort cap flags:\t\t0x%08x\n", pattr.port_cap_flags); - printf("\t\tActive width:\t\t%u\n", pattr.active_width); - printf("\t\tActive speed:\t\t%u\n", pattr.active_speed); - printf("\t\tPhys state:\t\t%u\n", pattr.phys_state); +static const char *fw_ver_str(u_int64_t fw_ver, char *str) +{ + u_int32_t major, minor, sub_minor; + + major = (fw_ver >> 32) & 0xffff; + minor = (fw_ver >> 16) & 0xffff; + sub_minor = fw_ver & 0xffff; + sprintf(str, "%d.%d.%d", major, minor, sub_minor); + return str; +} + +static int print_hca_cap(struct ibv_device *ib_dev, uint8_t ib_port) +{ + struct ibv_context *ctx; + struct ibv_device_attr device_attr; + struct ibv_port_attr port_attr; + int rc = 0; + uint8_t port; + char buf[256]; + + ctx = ibv_open_device(ib_dev); + if (!ctx) { + fprintf(stderr, "Failed to open device\n"); + rc = 1; + goto cleanup; + } + if (ibv_query_device(ctx, &device_attr)) { + fprintf(stderr, "Failed to query device props"); + rc = 2; + goto cleanup; } - return 0; + printf("hca_id:\t%s\n", ibv_get_device_name(ib_dev)); + printf("\tfw_ver:\t\t\t\t%s\n", fw_ver_str(device_attr.fw_ver, buf)); + printf("\tnode_guid:\t\t\t%s\n", guid_str(device_attr.node_guid, buf)); + printf("\tsys_image_guid:\t\t\t%s\n", guid_str(device_attr.sys_image_guid, buf)); + printf("\tmax_mr_size:\t\t\t0x%llx\n", device_attr.max_mr_size); + printf("\tpage_size_cap:\t\t\t0x%llx\n", device_attr.page_size_cap); + printf("\tvendor_id:\t\t\t0x%04x\n", device_attr.vendor_id); + printf("\tvendor_part_id:\t\t\t%d\n", device_attr.vendor_part_id); + printf("\thw_ver:\t\t\t\t0x%X\n", device_attr.hw_ver); + printf("\tphys_port_cnt:\t\t\t%d\n", device_attr.phys_port_cnt); + + if (verbose) { + printf("\tmax_qp:\t\t\t\t%d\n", device_attr.max_qp); + printf("\tmax_qp_wr:\t\t\t%d\n", device_attr.max_qp_wr); + printf("\tdevice_cap_flags:\t\t0x%08x\n", device_attr.device_cap_flags); + printf("\tmax_sge:\t\t\t%d\n", device_attr.max_sge); + printf("\tmax_sge_rd:\t\t\t%d\n", device_attr.max_sge_rd); + printf("\tmax_cq:\t\t\t\t%d\n", device_attr.max_cq); + printf("\tmax_cqe:\t\t\t%d\n", device_attr.max_cqe); + printf("\tmax_mr:\t\t\t\t%d\n", device_attr.max_mr); + printf("\tmax_pd:\t\t\t\t%d\n", device_attr.max_pd); + printf("\tmax_qp_rd_atom:\t\t\t%d\n", device_attr.max_qp_rd_atom); + printf("\tmax_ee_rd_atom:\t\t\t%d\n", device_attr.max_ee_rd_atom); + printf("\tmax_res_rd_atom:\t\t%d\n", device_attr.max_res_rd_atom); + printf("\tmax_qp_init_rd_atom:\t\t%d\n", device_attr.max_qp_init_rd_atom); + printf("\tmax_ee_init_rd_atom:\t\t%d\n", device_attr.max_ee_init_rd_atom); + printf("\tatomic_cap:\t\t\t%s (%d)\n", + atomic_cap_str(device_attr.atomic_cap), device_attr.atomic_cap); + printf("\tmax_ee:\t\t\t\t%d\n", device_attr.max_ee); + printf("\tmax_rdd:\t\t\t%d\n", device_attr.max_rdd); + printf("\tmax_mw:\t\t\t\t%d\n", device_attr.max_mw); + printf("\tmax_raw_ipv6_qp:\t\t%d\n", device_attr.max_raw_ipv6_qp); + printf("\tmax_raw_ethy_qp:\t\t%d\n", device_attr.max_raw_ethy_qp); + printf("\tmax_mcast_grp:\t\t\t%d\n", device_attr.max_mcast_grp); + printf("\tmax_mcast_qp_attach:\t\t%d\n", device_attr.max_mcast_qp_attach); + printf("\tmax_total_mcast_qp_attach:\t%d\n", + device_attr.max_total_mcast_qp_attach); + printf("\tmax_ah:\t\t\t\t%d\n", device_attr.max_ah); + printf("\tmax_fmr:\t\t\t%d\n", device_attr.max_fmr); + if (device_attr.max_fmr) { + printf("\tmax_map_per_fmr:\t\t%d\n", device_attr.max_map_per_fmr); + } + printf("\tmax_srq:\t\t\t%d\n", device_attr.max_srq); + if (device_attr.max_srq) { + printf("\tmax_srq_wr:\t\t\t%d\n", device_attr.max_srq_wr); + printf("\tmax_srq_sge:\t\t\t%d\n", device_attr.max_srq_sge); + } + printf("\tmax_pkeys:\t\t\t%d\n", device_attr.max_pkeys); + printf("\tlocal_ca_ack_delay:\t\t%d\n", device_attr.local_ca_ack_delay); + } + + for (port = 1; port <= device_attr.phys_port_cnt; ++port) { + /* if in the command line the user didn't ask for info about this port */ + if ((ib_port) && (port != ib_port)) + continue; + + rc = ibv_query_port(ctx, port, &port_attr); + if (rc) { + fprintf(stderr, "Failed to query port %u props\n", port); + goto cleanup; + } + printf("\t\tport:\t%d\n", port); + printf("\t\t\tstate:\t\t\t%s (%d)\n", + port_state_str(port_attr.state), port_attr.state); + printf("\t\t\tmax_mtu:\t\t%s (%d)\n", + mtu_str(port_attr.max_mtu), port_attr.max_mtu); + printf("\t\t\tactive_mtu:\t\t%s (%d)\n", + mtu_str(port_attr.active_mtu), port_attr.active_mtu); + printf("\t\t\tsm_lid:\t\t\t%d\n", port_attr.sm_lid); + printf("\t\t\tport_lid:\t\t%d\n", port_attr.lid); + printf("\t\t\tport_lmc:\t\t0x%02x\n", port_attr.lmc); + + if (verbose) { + printf("\t\t\tmax_msg_sz:\t\t0x%x\n", port_attr.max_msg_sz); + printf("\t\t\tport_cap_flags:\t\t0x%08x\n", port_attr.port_cap_flags); + printf("\t\t\tmax_vl_num:\t\t%d\n", port_attr.max_vl_num); + printf("\t\t\tbad_pkey_cntr:\t\t0x%x\n", port_attr.bad_pkey_cntr); + printf("\t\t\tqkey_viol_cntr:\t\t0x%x\n", port_attr.qkey_viol_cntr); + printf("\t\t\tsm_sl:\t\t\t%d\n", port_attr.sm_sl); + printf("\t\t\tpkey_tbl_len:\t\t%d\n", port_attr.pkey_tbl_len); + printf("\t\t\tgid_tbl_len:\t\t%d\n", port_attr.gid_tbl_len); + printf("\t\t\tsubnet_timeout:\t\t%d\n", port_attr.subnet_timeout); + printf("\t\t\tinit_type_reply:\t%d\n", port_attr.init_type_reply); + printf("\t\t\tactive_width:\t\t%sX (%d)\n", + width_str(port_attr.active_width), port_attr.active_width); + printf("\t\t\tactive_speed:\t\t%s (%d)\n", + speed_str(port_attr.active_speed), port_attr.active_speed); + printf("\t\t\tphys_state:\t\t%s (%d)\n", + port_phy_state_str(port_attr.phys_state), port_attr.phys_state); + + if (print_all_port_gids(ctx, port, port_attr.gid_tbl_len)) + goto cleanup; + } + printf("\n"); + } +cleanup: + if (ctx) + if (ibv_close_device(ctx)) { + fprintf(stderr, "Failed to close device"); + rc = 3; + } + return rc; +} + +static void usage(const char *argv0) +{ + printf("Usage: %s print the ca attributes\n", argv0); + printf("\n"); + printf("Options:\n"); + printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n"); + printf(" -i, --ib-port=<port> use port <port> of IB device (default 1)\n"); + printf(" -l, --list print only the IB devices names\n"); + printf(" -v, --verbose print all the attributes of the IB device(s)\n"); +} + +int main(int argc, char *argv[]) +{ + char *ib_devname = NULL; + int ret = 0; + struct dlist *dev_list; + struct ibv_device *ib_dev; + int num_of_hcas; + int ib_port = 0; + + /* parse command line options */ + while (1) { + int c; + static struct option long_options[] = { + { .name = "ib-dev", .has_arg = 1, .val = 'd' }, + { .name = "ib-port", .has_arg = 1, .val = 'i' }, + { .name = "list", .has_arg = 0, .val = 'l' }, + { .name = "verbose", .has_arg = 0, .val = 'v' }, + { 0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "d:i:lv", long_options, NULL); + if (c == -1) + break; + + switch (c) { + case 'd': + ib_devname = strdup(optarg); + break; + + case 'i': + ib_port = strtol(optarg, NULL, 0); + if (ib_port < 0) { + usage(argv[0]); + return 1; + } + break; + + case 'v': + verbose = 1; + break; + + case 'l': + dev_list = ibv_get_devices(); + if (!dev_list) { + fprintf(stderr, "Failed to get IB devices list"); + return -1; + } + + num_of_hcas = 0; + dlist_for_each_data(dev_list, ib_dev, struct ibv_device) + num_of_hcas ++; + + printf("%d HCA%s found:\n", num_of_hcas, + num_of_hcas != 1 ? "s" : ""); + + dlist_start(dev_list); + dlist_for_each_data(dev_list, ib_dev, struct ibv_device) + printf("\t%s\n", ibv_get_device_name(ib_dev)); + + printf("\n"); + return 0; + + default: + usage(argv[0]); + return -1; + } + } + + dev_list = ibv_get_devices(); + if (!dev_list) { + fprintf(stderr, "Failed to get IB device list\n"); + return -1; + } + dlist_start(dev_list); + if (ib_devname) { + dlist_for_each_data(dev_list, ib_dev, struct ibv_device) + if (!strcmp(ibv_get_device_name(ib_dev), ib_devname)) + break; + if (!ib_dev) { + fprintf(stderr, "IB device '%s' wasn't found\n", ib_devname); + return -1; + } + ret |= print_hca_cap(ib_dev, ib_port); + } else { + ib_dev = dlist_next(dev_list); + if (!ib_dev) { + fprintf(stderr, "No IB devices found\n"); + return -1; + } + ret |= print_hca_cap(ib_dev, ib_port); + } + + if (ib_devname) + free(ib_devname); + + return ret; } |