]> git.openfabrics.org - ~shefty/libibverbs.git/commitdiff
Merge Dotan Barak's vstat tool into ibv_devinfo
authorRoland Dreier <rolandd@cisco.com>
Tue, 30 Aug 2005 17:38:18 +0000 (17:38 +0000)
committerRoland Dreier <rolandd@cisco.com>
Thu, 9 Nov 2006 19:35:57 +0000 (11:35 -0800)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
AUTHORS
ChangeLog
examples/devinfo.c

diff --git a/AUTHORS b/AUTHORS
index 5c53702e187415973df6da9ad9540e62ac35c4a1..360116c3c19202a84e9c1ee80f0b153f8c707811 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,2 @@
 Roland Dreier          <roland@topspin.com>
+Dotan Barak            <dotanb@mellanox.co.il>
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8fb0f81a687b81425744c762c5fa9cc806f729a7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -0,0 +1,3 @@
+2005-08-30  Roland Dreier  <roland@cisco.com>
+
+       * examples/devinfo.c: Merge with Dotan Barak's vstat tool.
index e0a0f660ed150bbc013a95a34b89dfa9cceab51d..e6ec4f307900c0a92645eed7693040022cada9db 100644 (file)
@@ -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
 #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;
 }