|
Packit |
db064d |
/*
|
|
Packit |
db064d |
* Copyright (c) 2006-2007 The Regents of the University of California.
|
|
Packit |
db064d |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit |
db064d |
* Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
db064d |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
db064d |
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
|
Packit |
db064d |
* Copyright (c) 2011 Lawrence Livermore National Security. All rights reserved.
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* This software is available to you under a choice of one of two
|
|
Packit |
db064d |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
db064d |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
db064d |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
db064d |
* OpenIB.org BSD license below:
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
db064d |
* without modification, are permitted provided that the following
|
|
Packit |
db064d |
* conditions are met:
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* - Redistributions of source code must retain the above
|
|
Packit |
db064d |
* copyright notice, this list of conditions and the following
|
|
Packit |
db064d |
* disclaimer.
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
db064d |
* copyright notice, this list of conditions and the following
|
|
Packit |
db064d |
* disclaimer in the documentation and/or other materials
|
|
Packit |
db064d |
* provided with the distribution.
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
db064d |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
db064d |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
db064d |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
db064d |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
db064d |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
db064d |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
db064d |
* SOFTWARE.
|
|
Packit |
db064d |
*
|
|
Packit |
db064d |
*/
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/**
|
|
Packit |
db064d |
* Define common functions which can be included in the various C based diags.
|
|
Packit |
db064d |
*/
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#define _GNU_SOURCE
|
|
Packit |
db064d |
#include <stdio.h>
|
|
Packit |
db064d |
#include <errno.h>
|
|
Packit |
db064d |
#include <string.h>
|
|
Packit |
db064d |
#include <stdlib.h>
|
|
Packit |
db064d |
#include <stdarg.h>
|
|
Packit |
db064d |
#include <sys/types.h>
|
|
Packit |
db064d |
#include <unistd.h>
|
|
Packit |
db064d |
#include <ctype.h>
|
|
Packit |
db064d |
#include <config.h>
|
|
Packit |
db064d |
#include <getopt.h>
|
|
Packit |
db064d |
#include <limits.h>
|
|
Packit |
db064d |
#include <sys/stat.h>
|
|
Packit |
db064d |
#include <stdarg.h>
|
|
Packit |
db064d |
|
|
Packit |
db064d |
#include <infiniband/umad.h>
|
|
Packit |
db064d |
#include <infiniband/mad.h>
|
|
Packit |
db064d |
#include <ibdiag_common.h>
|
|
Packit |
db064d |
#include <ibdiag_version.h>
|
|
Packit |
db064d |
|
|
Packit |
db064d |
int ibverbose;
|
|
Packit |
db064d |
enum MAD_DEST ibd_dest_type = IB_DEST_LID;
|
|
Packit |
db064d |
ib_portid_t *ibd_sm_id;
|
|
Packit |
db064d |
static ib_portid_t sm_portid = { 0 };
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* general config options */
|
|
Packit |
db064d |
#define IBDIAG_CONFIG_GENERAL IBDIAG_CONFIG_PATH"/ibdiag.conf"
|
|
Packit |
db064d |
char *ibd_ca = NULL;
|
|
Packit |
db064d |
int ibd_ca_port = 0;
|
|
Packit |
db064d |
int ibd_timeout = 0;
|
|
Packit |
db064d |
uint32_t ibd_ibnetdisc_flags = IBND_CONFIG_MLX_EPI;
|
|
Packit |
db064d |
uint64_t ibd_mkey;
|
|
Packit |
db064d |
uint64_t ibd_sakey = 0;
|
|
Packit |
db064d |
int show_keys = 0;
|
|
Packit |
db064d |
char *ibd_nd_format = NULL;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static const char *prog_name;
|
|
Packit |
db064d |
static const char *prog_args;
|
|
Packit |
db064d |
static const char **prog_examples;
|
|
Packit |
db064d |
static struct option *long_opts = NULL;
|
|
Packit |
db064d |
static const struct ibdiag_opt *opts_map[256];
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static const char *get_build_version(void)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
return "BUILD VERSION: " IBDIAG_VERSION " Build date: " __DATE__ " "
|
|
Packit |
db064d |
__TIME__;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static void pretty_print(int start, int width, const char *str)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
int len = width - start;
|
|
Packit |
db064d |
const char *p, *e;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
while (1) {
|
|
Packit |
db064d |
while (isspace(*str))
|
|
Packit |
db064d |
str++;
|
|
Packit |
db064d |
p = str;
|
|
Packit |
db064d |
do {
|
|
Packit |
db064d |
e = p + 1;
|
|
Packit |
db064d |
p = strchr(e, ' ');
|
|
Packit |
db064d |
} while (p && p - str < len);
|
|
Packit |
db064d |
if (!p) {
|
|
Packit |
db064d |
fprintf(stderr, "%s", str);
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
if (e - str == 1)
|
|
Packit |
db064d |
e = p;
|
|
Packit |
db064d |
fprintf(stderr, "%.*s\n%*s", (int)(e - str), str, start, "");
|
|
Packit |
db064d |
str = e;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static inline int val_str_true(const char *val_str)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
return ((strncmp(val_str, "TRUE", strlen("TRUE")) == 0) ||
|
|
Packit |
db064d |
(strncmp(val_str, "true", strlen("true")) == 0));
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static void read_ibdiag_config(const char *file)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
char buf[1024];
|
|
Packit |
db064d |
FILE *config_fd = NULL;
|
|
Packit |
db064d |
char *p_prefix, *p_last;
|
|
Packit |
db064d |
char *name;
|
|
Packit |
db064d |
char *val_str;
|
|
Packit |
db064d |
struct stat statbuf;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* silently ignore missing config file */
|
|
Packit |
db064d |
if (stat(file, &statbuf))
|
|
Packit |
db064d |
return;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
config_fd = fopen(file, "r");
|
|
Packit |
db064d |
if (!config_fd)
|
|
Packit |
db064d |
return;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
while (fgets(buf, sizeof buf, config_fd) != NULL) {
|
|
Packit |
db064d |
p_prefix = strtok_r(buf, "\n", &p_last);
|
|
Packit |
db064d |
if (!p_prefix)
|
|
Packit |
db064d |
continue; /* ignore blank lines */
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (*p_prefix == '#')
|
|
Packit |
db064d |
continue; /* ignore comment lines */
|
|
Packit |
db064d |
|
|
Packit |
db064d |
name = strtok_r(p_prefix, "=", &p_last);
|
|
Packit |
db064d |
val_str = strtok_r(NULL, "\n", &p_last);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (strncmp(name, "CA", strlen("CA")) == 0) {
|
|
Packit |
db064d |
free(ibd_ca);
|
|
Packit |
db064d |
ibd_ca = strdup(val_str);
|
|
Packit |
db064d |
} else if (strncmp(name, "Port", strlen("Port")) == 0) {
|
|
Packit |
db064d |
ibd_ca_port = strtoul(val_str, NULL, 0);
|
|
Packit |
db064d |
} else if (strncmp(name, "timeout", strlen("timeout")) == 0) {
|
|
Packit |
db064d |
ibd_timeout = strtoul(val_str, NULL, 0);
|
|
Packit |
db064d |
} else if (strncmp(name, "MLX_EPI", strlen("MLX_EPI")) == 0) {
|
|
Packit |
db064d |
if (val_str_true(val_str)) {
|
|
Packit |
db064d |
ibd_ibnetdisc_flags |= IBND_CONFIG_MLX_EPI;
|
|
Packit |
db064d |
} else {
|
|
Packit |
db064d |
ibd_ibnetdisc_flags &= ~IBND_CONFIG_MLX_EPI;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
} else if (strncmp(name, "m_key", strlen("m_key")) == 0) {
|
|
Packit |
db064d |
ibd_mkey = strtoull(val_str, NULL, 0);
|
|
Packit |
db064d |
} else if (strncmp(name, "sa_key",
|
|
Packit |
db064d |
strlen("sa_key")) == 0) {
|
|
Packit |
db064d |
ibd_sakey = strtoull(val_str, NULL, 0);
|
|
Packit |
db064d |
} else if (strncmp(name, "nd_format",
|
|
Packit |
db064d |
strlen("nd_format")) == 0) {
|
|
Packit |
db064d |
ibd_nd_format = strdup(val_str);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
fclose(config_fd);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
|
|
Packit |
db064d |
void ibdiag_show_usage(void)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
struct option *o = long_opts;
|
|
Packit |
db064d |
int n;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
fprintf(stderr, "\nUsage: %s [options] %s\n\n", prog_name,
|
|
Packit |
db064d |
prog_args ? prog_args : "");
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (long_opts[0].name)
|
|
Packit |
db064d |
fprintf(stderr, "Options:\n");
|
|
Packit |
db064d |
for (o = long_opts; o->name; o++) {
|
|
Packit |
db064d |
const struct ibdiag_opt *io = opts_map[o->val];
|
|
Packit |
db064d |
n = fprintf(stderr, " --%s", io->name);
|
|
Packit |
db064d |
if (isprint(io->letter))
|
|
Packit |
db064d |
n += fprintf(stderr, ", -%c", io->letter);
|
|
Packit |
db064d |
if (io->has_arg)
|
|
Packit |
db064d |
n += fprintf(stderr, " %s",
|
|
Packit |
db064d |
io->arg_tmpl ? io->arg_tmpl : "<val>");
|
|
Packit |
db064d |
if (io->description && *io->description) {
|
|
Packit |
db064d |
n += fprintf(stderr, "%*s ", 24 - n > 0 ? 24 - n : 0,
|
|
Packit |
db064d |
"");
|
|
Packit |
db064d |
pretty_print(n, 74, io->description);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
fprintf(stderr, "\n");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (prog_examples) {
|
|
Packit |
db064d |
const char **p;
|
|
Packit |
db064d |
fprintf(stderr, "\nExamples:\n");
|
|
Packit |
db064d |
for (p = prog_examples; *p && **p; p++)
|
|
Packit |
db064d |
fprintf(stderr, " %s %s\n", prog_name, *p);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
fprintf(stderr, "\n");
|
|
Packit |
db064d |
|
|
Packit |
db064d |
exit(2);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int process_opt(int ch)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
char *endp;
|
|
Packit |
db064d |
long val;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
switch (ch) {
|
|
Packit |
db064d |
case 'z':
|
|
Packit |
db064d |
read_ibdiag_config(optarg);
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'h':
|
|
Packit |
db064d |
ibdiag_show_usage();
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'V':
|
|
Packit |
db064d |
fprintf(stderr, "%s %s\n", prog_name, get_build_version());
|
|
Packit |
db064d |
exit(0);
|
|
Packit |
db064d |
case 'e':
|
|
Packit |
db064d |
madrpc_show_errors(1);
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'v':
|
|
Packit |
db064d |
ibverbose++;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'd':
|
|
Packit |
db064d |
ibdebug++;
|
|
Packit |
db064d |
madrpc_show_errors(1);
|
|
Packit |
db064d |
umad_debug(ibdebug - 1);
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'C':
|
|
Packit |
db064d |
ibd_ca = optarg;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'P':
|
|
Packit |
db064d |
ibd_ca_port = strtoul(optarg, NULL, 0);
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'D':
|
|
Packit |
db064d |
ibd_dest_type = IB_DEST_DRPATH;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'L':
|
|
Packit |
db064d |
ibd_dest_type = IB_DEST_LID;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'G':
|
|
Packit |
db064d |
ibd_dest_type = IB_DEST_GUID;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 't':
|
|
Packit |
db064d |
errno = 0;
|
|
Packit |
db064d |
val = strtol(optarg, &endp, 0);
|
|
Packit |
db064d |
if (errno || (endp && *endp != '\0') || val <= 0 ||
|
|
Packit |
db064d |
val > INT_MAX)
|
|
Packit |
db064d |
IBEXIT("Invalid timeout \"%s\". Timeout requires a "
|
|
Packit |
db064d |
"positive integer value < %d.", optarg, INT_MAX);
|
|
Packit |
db064d |
else {
|
|
Packit |
db064d |
madrpc_set_timeout((int)val);
|
|
Packit |
db064d |
ibd_timeout = (int)val;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 's':
|
|
Packit |
db064d |
/* srcport is not required when resolving via IB_DEST_LID */
|
|
Packit |
db064d |
if (resolve_portid_str(ibd_ca, ibd_ca_port, &sm_portid, optarg,
|
|
Packit |
db064d |
IB_DEST_LID, NULL, NULL) < 0)
|
|
Packit |
db064d |
IBEXIT("cannot resolve SM destination port %s",
|
|
Packit |
db064d |
optarg);
|
|
Packit |
db064d |
ibd_sm_id = &sm_portid;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'K':
|
|
Packit |
db064d |
show_keys = 1;
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
case 'y':
|
|
Packit |
db064d |
errno = 0;
|
|
Packit |
db064d |
ibd_mkey = strtoull(optarg, &endp, 0);
|
|
Packit |
db064d |
if (errno || *endp != '\0') {
|
|
Packit |
db064d |
errno = 0;
|
|
Packit |
db064d |
ibd_mkey = strtoull(getpass("M_Key: "), &endp, 0);
|
|
Packit |
db064d |
if (errno || *endp != '\0') {
|
|
Packit |
db064d |
IBEXIT("Bad M_Key");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
default:
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static const struct ibdiag_opt common_opts[] = {
|
|
Packit |
db064d |
{"config", 'z', 1, "<config>", "use config file, default: " IBDIAG_CONFIG_GENERAL},
|
|
Packit |
db064d |
{"Ca", 'C', 1, "<ca>", "Ca name to use"},
|
|
Packit |
db064d |
{"Port", 'P', 1, "<port>", "Ca port number to use"},
|
|
Packit |
db064d |
{"Direct", 'D', 0, NULL, "use Direct address argument"},
|
|
Packit |
db064d |
{"Lid", 'L', 0, NULL, "use LID address argument"},
|
|
Packit |
db064d |
{"Guid", 'G', 0, NULL, "use GUID address argument"},
|
|
Packit |
db064d |
{"timeout", 't', 1, "<ms>", "timeout in ms"},
|
|
Packit |
db064d |
{"sm_port", 's', 1, "<lid>", "SM port lid"},
|
|
Packit |
db064d |
{"show_keys", 'K', 0, NULL, "display security keys in output"},
|
|
Packit |
db064d |
{"m_key", 'y', 1, "<key>", "M_Key to use in request"},
|
|
Packit |
db064d |
{"errors", 'e', 0, NULL, "show send and receive errors"},
|
|
Packit |
db064d |
{"verbose", 'v', 0, NULL, "increase verbosity level"},
|
|
Packit |
db064d |
{"debug", 'd', 0, NULL, "raise debug level"},
|
|
Packit |
db064d |
{"help", 'h', 0, NULL, "help message"},
|
|
Packit |
db064d |
{"version", 'V', 0, NULL, "show version"},
|
|
Packit |
db064d |
{}
|
|
Packit |
db064d |
};
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static void make_opt(struct option *l, const struct ibdiag_opt *o,
|
|
Packit |
db064d |
const struct ibdiag_opt *map[])
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
l->name = o->name;
|
|
Packit |
db064d |
l->has_arg = o->has_arg;
|
|
Packit |
db064d |
l->flag = NULL;
|
|
Packit |
db064d |
l->val = o->letter;
|
|
Packit |
db064d |
if (!map[l->val])
|
|
Packit |
db064d |
map[l->val] = o;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static struct option *make_long_opts(const char *exclude_str,
|
|
Packit |
db064d |
const struct ibdiag_opt *custom_opts,
|
|
Packit |
db064d |
const struct ibdiag_opt *map[])
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
struct option *res, *l;
|
|
Packit |
db064d |
const struct ibdiag_opt *o;
|
|
Packit |
db064d |
unsigned n = 0;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (custom_opts)
|
|
Packit |
db064d |
for (o = custom_opts; o->name; o++)
|
|
Packit |
db064d |
n++;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
res = malloc((sizeof(common_opts) / sizeof(common_opts[0]) + n) *
|
|
Packit |
db064d |
sizeof(*res));
|
|
Packit |
db064d |
if (!res)
|
|
Packit |
db064d |
return NULL;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
l = res;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (custom_opts)
|
|
Packit |
db064d |
for (o = custom_opts; o->name; o++)
|
|
Packit |
db064d |
make_opt(l++, o, map);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
for (o = common_opts; o->name; o++) {
|
|
Packit |
db064d |
if (exclude_str && strchr(exclude_str, o->letter))
|
|
Packit |
db064d |
continue;
|
|
Packit |
db064d |
make_opt(l++, o, map);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
memset(l, 0, sizeof(*l));
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return res;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static void make_str_opts(const struct option *o, char *p, unsigned size)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
unsigned i, n = 0;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
for (n = 0; o->name && n + 2 + o->has_arg < size; o++) {
|
|
Packit |
db064d |
p[n++] = (char)o->val;
|
|
Packit |
db064d |
for (i = 0; i < (unsigned)o->has_arg; i++)
|
|
Packit |
db064d |
p[n++] = ':';
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
p[n] = '\0';
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
int ibdiag_process_opts(int argc, char *const argv[], void *cxt,
|
|
Packit |
db064d |
const char *exclude_common_str,
|
|
Packit |
db064d |
const struct ibdiag_opt custom_opts[],
|
|
Packit |
db064d |
int (*custom_handler) (void *cxt, int val),
|
|
Packit |
db064d |
const char *usage_args, const char *usage_examples[])
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
char str_opts[1024];
|
|
Packit |
db064d |
const struct ibdiag_opt *o;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
prog_name = argv[0];
|
|
Packit |
db064d |
prog_args = usage_args;
|
|
Packit |
db064d |
prog_examples = usage_examples;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (long_opts)
|
|
Packit |
db064d |
free(long_opts);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
long_opts = make_long_opts(exclude_common_str, custom_opts, opts_map);
|
|
Packit |
db064d |
if (!long_opts)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
read_ibdiag_config(IBDIAG_CONFIG_GENERAL);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
make_str_opts(long_opts, str_opts, sizeof(str_opts));
|
|
Packit |
db064d |
|
|
Packit |
db064d |
while (1) {
|
|
Packit |
db064d |
int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);
|
|
Packit |
db064d |
if (ch == -1)
|
|
Packit |
db064d |
break;
|
|
Packit |
db064d |
o = opts_map[ch];
|
|
Packit |
db064d |
if (!o)
|
|
Packit |
db064d |
ibdiag_show_usage();
|
|
Packit |
db064d |
if (custom_handler) {
|
|
Packit |
db064d |
if (custom_handler(cxt, ch) &&
|
|
Packit |
db064d |
process_opt(ch))
|
|
Packit |
db064d |
ibdiag_show_usage();
|
|
Packit |
db064d |
} else if (process_opt(ch))
|
|
Packit |
db064d |
ibdiag_show_usage();
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
void ibexit(const char *fn, const char *msg, ...)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
char buf[512];
|
|
Packit |
db064d |
va_list va;
|
|
Packit |
db064d |
int n;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
va_start(va, msg);
|
|
Packit |
db064d |
n = vsprintf(buf, msg, va);
|
|
Packit |
db064d |
va_end(va);
|
|
Packit |
db064d |
buf[n] = 0;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (ibdebug)
|
|
Packit |
db064d |
printf("%s: iberror: [pid %d] %s: failed: %s\n",
|
|
Packit |
db064d |
prog_name ? prog_name : "", getpid(), fn, buf);
|
|
Packit |
db064d |
else
|
|
Packit |
db064d |
printf("%s: iberror: failed: %s\n",
|
|
Packit |
db064d |
prog_name ? prog_name : "", buf);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
exit(-1);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
const char *conv_cnt_human_readable(uint64_t val64, float *val, int data)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
uint64_t tmp = val64;
|
|
Packit |
db064d |
int ui = 0;
|
|
Packit |
db064d |
uint64_t div = 1;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
tmp /= 1024;
|
|
Packit |
db064d |
while (tmp) {
|
|
Packit |
db064d |
ui++;
|
|
Packit |
db064d |
tmp /= 1024;
|
|
Packit |
db064d |
div *= 1024;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
*val = (float)(val64);
|
|
Packit |
db064d |
if (data) {
|
|
Packit |
db064d |
*val *= 4;
|
|
Packit |
db064d |
if (*val/div > 1024) {
|
|
Packit |
db064d |
ui++;
|
|
Packit |
db064d |
div *= 1024;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
*val /= div;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (data) {
|
|
Packit |
db064d |
switch (ui) {
|
|
Packit |
db064d |
case 0:
|
|
Packit |
db064d |
return ("B");
|
|
Packit |
db064d |
case 1:
|
|
Packit |
db064d |
return ("KB");
|
|
Packit |
db064d |
case 2:
|
|
Packit |
db064d |
return ("MB");
|
|
Packit |
db064d |
case 3:
|
|
Packit |
db064d |
return ("GB");
|
|
Packit |
db064d |
case 4:
|
|
Packit |
db064d |
return ("TB");
|
|
Packit |
db064d |
case 5:
|
|
Packit |
db064d |
return ("PB");
|
|
Packit |
db064d |
case 6:
|
|
Packit |
db064d |
return ("EB");
|
|
Packit |
db064d |
default:
|
|
Packit |
db064d |
return ("");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
} else {
|
|
Packit |
db064d |
switch (ui) {
|
|
Packit |
db064d |
case 0:
|
|
Packit |
db064d |
return ("");
|
|
Packit |
db064d |
case 1:
|
|
Packit |
db064d |
return ("K");
|
|
Packit |
db064d |
case 2:
|
|
Packit |
db064d |
return ("M");
|
|
Packit |
db064d |
case 3:
|
|
Packit |
db064d |
return ("G");
|
|
Packit |
db064d |
case 4:
|
|
Packit |
db064d |
return ("T");
|
|
Packit |
db064d |
case 5:
|
|
Packit |
db064d |
return ("P");
|
|
Packit |
db064d |
case 6:
|
|
Packit |
db064d |
return ("E");
|
|
Packit |
db064d |
default:
|
|
Packit |
db064d |
return ("");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
return ("");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
int is_port_info_extended_supported(ib_portid_t * dest, int port,
|
|
Packit |
db064d |
struct ibmad_port *srcport)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
|
Packit |
db064d |
uint32_t cap_mask;
|
|
Packit |
db064d |
uint16_t cap_mask2;
|
|
Packit |
db064d |
int type, portnum;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
|
Packit |
db064d |
IBEXIT("node info query failed");
|
|
Packit |
db064d |
|
|
Packit |
db064d |
mad_decode_field(data, IB_NODE_TYPE_F, &type);
|
|
Packit |
db064d |
if (type == IB_NODE_SWITCH)
|
|
Packit |
db064d |
portnum = 0;
|
|
Packit |
db064d |
else
|
|
Packit |
db064d |
portnum = port;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
|
|
Packit |
db064d |
IBEXIT("port info query failed");
|
|
Packit |
db064d |
|
|
Packit |
db064d |
mad_decode_field(data, IB_PORT_CAPMASK_F, &cap_mask);
|
|
Packit |
db064d |
if (cap_mask & be32toh(IB_PORT_CAP_HAS_CAP_MASK2)) {
|
|
Packit |
db064d |
mad_decode_field(data, IB_PORT_CAPMASK2_F, &cap_mask2);
|
|
Packit |
db064d |
if (!(cap_mask2 &
|
|
Packit |
db064d |
be16toh(IB_PORT_CAP2_IS_PORT_INFO_EXT_SUPPORTED))) {
|
|
Packit |
db064d |
IBWARN("port info capability mask2 = 0x%x doesn't"
|
|
Packit |
db064d |
" indicate PortInfoExtended support", cap_mask2);
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
} else {
|
|
Packit |
db064d |
IBWARN("port info capability mask2 not supported");
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return 1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
int is_mlnx_ext_port_info_supported(uint32_t vendorid,
|
|
Packit |
db064d |
uint16_t devid)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
if (ibd_ibnetdisc_flags & IBND_CONFIG_MLX_EPI) {
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ((devid >= 0xc738 && devid <= 0xc73b) ||
|
|
Packit |
db064d |
devid == 0xc839 || devid == 0xcb20 || devid == 0xcf08 ||
|
|
Packit |
db064d |
devid == 0xcf09 || devid == 0xd2f0 ||
|
|
Packit |
db064d |
((vendorid == 0x119f) &&
|
|
Packit |
db064d |
/* Bull SwitchX */
|
|
Packit |
db064d |
(devid == 0x1b02 || devid == 0x1b50 ||
|
|
Packit |
db064d |
/* Bull SwitchIB and SwitchIB2 */
|
|
Packit |
db064d |
devid == 0x1ba0 ||
|
|
Packit |
db064d |
(devid >= 0x1bd0 && devid <= 0x1bd5) ||
|
|
Packit |
db064d |
/* Bull Quantum */
|
|
Packit |
db064d |
devid == 0x1bf0)))
|
|
Packit |
db064d |
return 1;
|
|
Packit |
db064d |
if ((devid >= 0x1003 && devid <= 0x101b) ||
|
|
Packit |
db064d |
(devid == 0xa2d2) ||
|
|
Packit |
db064d |
((vendorid == 0x119f) &&
|
|
Packit |
db064d |
/* Bull ConnectX3 */
|
|
Packit |
db064d |
(devid == 0x1b33 || devid == 0x1b73 ||
|
|
Packit |
db064d |
devid == 0x1b40 || devid == 0x1b41 ||
|
|
Packit |
db064d |
devid == 0x1b60 || devid == 0x1b61 ||
|
|
Packit |
db064d |
/* Bull ConnectIB */
|
|
Packit |
db064d |
devid == 0x1b83 ||
|
|
Packit |
db064d |
devid == 0x1b93 || devid == 0x1b94 ||
|
|
Packit |
db064d |
/* Bull ConnectX4, Sequana HDR and HDR100 */
|
|
Packit |
db064d |
devid == 0x1bb4 || devid == 0x1bb5 ||
|
|
Packit |
db064d |
(devid >= 0x1bc4 && devid <= 0x1bc6))))
|
|
Packit |
db064d |
return 1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/** =========================================================================
|
|
Packit |
db064d |
* Resolve the SM portid using the umad layer rather than using
|
|
Packit |
db064d |
* ib_resolve_smlid_via which requires a PortInfo query on the local port.
|
|
Packit |
db064d |
*/
|
|
Packit |
db064d |
int resolve_sm_portid(char *ca_name, uint8_t portnum, ib_portid_t *sm_id)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
umad_port_t port;
|
|
Packit |
db064d |
int rc;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (!sm_id)
|
|
Packit |
db064d |
return (-1);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ((rc = umad_get_port(ca_name, portnum, &port)) < 0)
|
|
Packit |
db064d |
return rc;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
memset(sm_id, 0, sizeof(*sm_id));
|
|
Packit |
db064d |
sm_id->lid = port.sm_lid;
|
|
Packit |
db064d |
sm_id->sl = port.sm_sl;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
umad_release_port(&port);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/** =========================================================================
|
|
Packit |
db064d |
* Resolve local CA characteristics using the umad layer rather than using
|
|
Packit |
db064d |
* ib_resolve_self_via which requires SMP queries on the local port.
|
|
Packit |
db064d |
*/
|
|
Packit |
db064d |
int resolve_self(char *ca_name, uint8_t ca_port, ib_portid_t *portid,
|
|
Packit |
db064d |
int *portnum, ibmad_gid_t *gid)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
umad_port_t port;
|
|
Packit |
db064d |
uint64_t prefix, guid;
|
|
Packit |
db064d |
int rc;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (!(portid || portnum || gid))
|
|
Packit |
db064d |
return (-1);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ((rc = umad_get_port(ca_name, ca_port, &port)) < 0)
|
|
Packit |
db064d |
return rc;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (portid) {
|
|
Packit |
db064d |
memset(portid, 0, sizeof(*portid));
|
|
Packit |
db064d |
portid->lid = port.base_lid;
|
|
Packit |
db064d |
portid->sl = port.sm_sl;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
if (portnum)
|
|
Packit |
db064d |
*portnum = port.portnum;
|
|
Packit |
db064d |
if (gid) {
|
|
Packit |
db064d |
memset(gid, 0, sizeof(*gid));
|
|
Packit |
db064d |
prefix = be64toh(port.gid_prefix);
|
|
Packit |
db064d |
guid = be64toh(port.port_guid);
|
|
Packit |
db064d |
mad_encode_field(*gid, IB_GID_PREFIX_F, &prefix);
|
|
Packit |
db064d |
mad_encode_field(*gid, IB_GID_GUID_F, &guid);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
umad_release_port(&port);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int resolve_gid(char *ca_name, uint8_t ca_port, ib_portid_t *portid,
|
|
Packit |
db064d |
ibmad_gid_t gid, ib_portid_t *sm_id,
|
|
Packit |
db064d |
const struct ibmad_port *srcport)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
ib_portid_t tmp;
|
|
Packit |
db064d |
char buf[IB_SA_DATA_SIZE] = { 0 };
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (!sm_id) {
|
|
Packit |
db064d |
sm_id = &tm;;
|
|
Packit |
db064d |
if (resolve_sm_portid(ca_name, ca_port, sm_id) < 0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ((portid->lid =
|
|
Packit |
db064d |
ib_path_query_via(srcport, gid, gid, sm_id, buf)) < 0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static int resolve_guid(char *ca_name, uint8_t ca_port, ib_portid_t *portid,
|
|
Packit |
db064d |
uint64_t *guid, ib_portid_t *sm_id,
|
|
Packit |
db064d |
const struct ibmad_port *srcport)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
ib_portid_t tmp;
|
|
Packit |
db064d |
uint8_t buf[IB_SA_DATA_SIZE] = { 0 };
|
|
Packit |
db064d |
uint64_t prefix;
|
|
Packit |
db064d |
ibmad_gid_t selfgid;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (!sm_id) {
|
|
Packit |
db064d |
sm_id = &tm;;
|
|
Packit |
db064d |
if (resolve_sm_portid(ca_name, ca_port, sm_id) < 0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (resolve_self(ca_name, ca_port, NULL, NULL, &selfgid) < 0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
memcpy(&prefix, portid->gid, sizeof(prefix));
|
|
Packit |
db064d |
if (!prefix)
|
|
Packit |
db064d |
mad_set_field64(portid->gid, 0, IB_GID_PREFIX_F,
|
|
Packit |
db064d |
IB_DEFAULT_SUBN_PREFIX);
|
|
Packit |
db064d |
if (guid)
|
|
Packit |
db064d |
mad_set_field64(portid->gid, 0, IB_GID_GUID_F, *guid);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ((portid->lid =
|
|
Packit |
db064d |
ib_path_query_via(srcport, selfgid, portid->gid, sm_id, buf)) < 0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
mad_decode_field(buf, IB_SA_PR_SL_F, &portid->sl);
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/*
|
|
Packit |
db064d |
* Callers of this function should ensure their ibmad_port has been opened with
|
|
Packit |
db064d |
* IB_SA_CLASS as this function may require the SA to resolve addresses.
|
|
Packit |
db064d |
*/
|
|
Packit |
db064d |
int resolve_portid_str(char *ca_name, uint8_t ca_port, ib_portid_t * portid,
|
|
Packit |
db064d |
char *addr_str, enum MAD_DEST dest_type,
|
|
Packit |
db064d |
ib_portid_t *sm_id, const struct ibmad_port *srcport)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
ibmad_gid_t gid;
|
|
Packit |
db064d |
uint64_t guid;
|
|
Packit |
db064d |
int lid;
|
|
Packit |
db064d |
char *routepath;
|
|
Packit |
db064d |
ib_portid_t selfportid = { 0 };
|
|
Packit |
db064d |
int selfport = 0;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
memset(portid, 0, sizeof *portid);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
switch (dest_type) {
|
|
Packit |
db064d |
case IB_DEST_LID:
|
|
Packit |
db064d |
lid = strtol(addr_str, NULL, 0);
|
|
Packit |
db064d |
if (!IB_LID_VALID(lid))
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
return ib_portid_set(portid, lid, 0, 0);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
case IB_DEST_DRPATH:
|
|
Packit |
db064d |
if (str2drpath(&portid->drpath, addr_str, 0, 0) < 0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
case IB_DEST_GUID:
|
|
Packit |
db064d |
if (!(guid = strtoull(addr_str, NULL, 0)))
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* keep guid in portid? */
|
|
Packit |
db064d |
return resolve_guid(ca_name, ca_port, portid, &guid, sm_id,
|
|
Packit |
db064d |
srcport);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
case IB_DEST_DRSLID:
|
|
Packit |
db064d |
lid = strtol(addr_str, &routepath, 0);
|
|
Packit |
db064d |
routepath++;
|
|
Packit |
db064d |
if (!IB_LID_VALID(lid))
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
ib_portid_set(portid, lid, 0, 0);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
/* handle DR parsing and set DrSLID to local lid */
|
|
Packit |
db064d |
if (resolve_self(ca_name, ca_port, &selfportid, &selfport,
|
|
Packit |
db064d |
NULL) < 0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
if (str2drpath(&portid->drpath, routepath, selfportid.lid, 0) <
|
|
Packit |
db064d |
0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
case IB_DEST_GID:
|
|
Packit |
db064d |
if (inet_pton(AF_INET6, addr_str, &gid) <= 0)
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
return resolve_gid(ca_name, ca_port, portid, gid, sm_id,
|
|
Packit |
db064d |
srcport);
|
|
Packit |
db064d |
default:
|
|
Packit |
db064d |
IBWARN("bad dest_type %d", dest_type);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return -1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static unsigned int get_max_width(unsigned int num)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
unsigned r = 0; /* 1x */
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (num & 8)
|
|
Packit |
db064d |
r = 3; /* 12x */
|
|
Packit |
db064d |
else {
|
|
Packit |
db064d |
if (num & 4)
|
|
Packit |
db064d |
r = 2; /* 8x */
|
|
Packit |
db064d |
else if (num & 2)
|
|
Packit |
db064d |
r = 1; /* 4x */
|
|
Packit |
db064d |
else if (num & 0x10)
|
|
Packit |
db064d |
r = 4; /* 2x */
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return (1 << r);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
static unsigned int get_max(unsigned int num)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
unsigned r = 0; // r will be lg(num)
|
|
Packit |
db064d |
|
|
Packit |
db064d |
while (num >>= 1) // unroll for more speed...
|
|
Packit |
db064d |
r++;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return (1 << r);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
void get_max_msg(char *width_msg, char *speed_msg, int msg_size, ibnd_port_t * port)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
char buf[64];
|
|
Packit |
db064d |
uint32_t max_speed = 0;
|
|
Packit |
db064d |
uint32_t cap_mask, rem_cap_mask, fdr10;
|
|
Packit |
db064d |
uint8_t *info = NULL;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
uint32_t max_width = get_max_width(mad_get_field(port->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_WIDTH_SUPPORTED_F)
|
|
Packit |
db064d |
& mad_get_field(port->remoteport->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_WIDTH_SUPPORTED_F));
|
|
Packit |
db064d |
if ((max_width & mad_get_field(port->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_WIDTH_ACTIVE_F)) == 0)
|
|
Packit |
db064d |
// we are not at the max supported width
|
|
Packit |
db064d |
// print what we could be at.
|
|
Packit |
db064d |
snprintf(width_msg, msg_size, "Could be %s",
|
|
Packit |
db064d |
mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F,
|
|
Packit |
db064d |
buf, 64, &max_width));
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (port->node->type == IB_NODE_SWITCH) {
|
|
Packit |
db064d |
if (port->node->ports[0])
|
|
Packit |
db064d |
info = (uint8_t *)&port->node->ports[0]->info;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
else
|
|
Packit |
db064d |
info = (uint8_t *)&port->info;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (info)
|
|
Packit |
db064d |
cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F);
|
|
Packit |
db064d |
else
|
|
Packit |
db064d |
cap_mask = 0;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
info = NULL;
|
|
Packit |
db064d |
if (port->remoteport->node->type == IB_NODE_SWITCH) {
|
|
Packit |
db064d |
if (port->remoteport->node->ports[0])
|
|
Packit |
db064d |
info = (uint8_t *)&port->remoteport->node->ports[0]->info;
|
|
Packit |
db064d |
} else
|
|
Packit |
db064d |
info = (uint8_t *)&port->remoteport->info;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if (info)
|
|
Packit |
db064d |
rem_cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F);
|
|
Packit |
db064d |
else
|
|
Packit |
db064d |
rem_cap_mask = 0;
|
|
Packit |
db064d |
if (cap_mask & be32toh(IB_PORT_CAP_HAS_EXT_SPEEDS) &&
|
|
Packit |
db064d |
rem_cap_mask & be32toh(IB_PORT_CAP_HAS_EXT_SPEEDS))
|
|
Packit |
db064d |
goto check_ext_speed;
|
|
Packit |
db064d |
check_fdr10_supp:
|
|
Packit |
db064d |
fdr10 = (mad_get_field(port->ext_info, 0,
|
|
Packit |
db064d |
IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F) & FDR10)
|
|
Packit |
db064d |
&& (mad_get_field(port->remoteport->ext_info, 0,
|
|
Packit |
db064d |
IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F) & FDR10);
|
|
Packit |
db064d |
if (fdr10)
|
|
Packit |
db064d |
goto check_fdr10_active;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
max_speed = get_max(mad_get_field(port->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_SPEED_SUPPORTED_F)
|
|
Packit |
db064d |
& mad_get_field(port->remoteport->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_SPEED_SUPPORTED_F));
|
|
Packit |
db064d |
if ((max_speed & mad_get_field(port->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_SPEED_ACTIVE_F)) == 0)
|
|
Packit |
db064d |
// we are not at the max supported speed
|
|
Packit |
db064d |
// print what we could be at.
|
|
Packit |
db064d |
snprintf(speed_msg, msg_size, "Could be %s",
|
|
Packit |
db064d |
mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F,
|
|
Packit |
db064d |
buf, 64, &max_speed));
|
|
Packit |
db064d |
return;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
check_ext_speed:
|
|
Packit |
db064d |
if (mad_get_field(port->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F) == 0 ||
|
|
Packit |
db064d |
mad_get_field(port->remoteport->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F) == 0)
|
|
Packit |
db064d |
goto check_fdr10_supp;
|
|
Packit |
db064d |
max_speed = get_max(mad_get_field(port->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F)
|
|
Packit |
db064d |
& mad_get_field(port->remoteport->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F));
|
|
Packit |
db064d |
if ((max_speed & mad_get_field(port->info, 0,
|
|
Packit |
db064d |
IB_PORT_LINK_SPEED_EXT_ACTIVE_F)) == 0)
|
|
Packit |
db064d |
// we are not at the max supported extended speed
|
|
Packit |
db064d |
// print what we could be at.
|
|
Packit |
db064d |
snprintf(speed_msg, msg_size, "Could be %s",
|
|
Packit |
db064d |
mad_dump_val(IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
|
|
Packit |
db064d |
buf, 64, &max_speed));
|
|
Packit |
db064d |
return;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
check_fdr10_active:
|
|
Packit |
db064d |
if ((mad_get_field(port->ext_info, 0,
|
|
Packit |
db064d |
IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F) & FDR10) == 0) {
|
|
Packit |
db064d |
/* Special case QDR to try to avoid confusion with FDR10 */
|
|
Packit |
db064d |
if (mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F) == 4) /* QDR (10.0 Gbps) */
|
|
Packit |
db064d |
snprintf(speed_msg, msg_size,
|
|
Packit |
db064d |
"Could be FDR10 (Found link at QDR but expected speed is FDR10)");
|
|
Packit |
db064d |
else
|
|
Packit |
db064d |
snprintf(speed_msg, msg_size, "Could be FDR10");
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
int vsnprint_field(char *buf, size_t n, enum MAD_FIELDS f, int spacing,
|
|
Packit |
db064d |
const char *format, va_list va_args)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
int len, i, ret;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
len = strlen(mad_field_name(f));
|
|
Packit |
db064d |
if (len + 2 > n || spacing + 1 > n)
|
|
Packit |
db064d |
return 0;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
strncpy(buf, mad_field_name(f), n);
|
|
Packit |
db064d |
buf[len] = ':';
|
|
Packit |
db064d |
for (i = len+1; i < spacing+1; i++) {
|
|
Packit |
db064d |
buf[i] = '.';
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
ret = vsnprintf(&buf[spacing+1], n - spacing, format, va_args);
|
|
Packit |
db064d |
if (ret >= n - spacing)
|
|
Packit |
db064d |
buf[n] = '\0';
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return ret + spacing;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
int snprint_field(char *buf, size_t n, enum MAD_FIELDS f, int spacing,
|
|
Packit |
db064d |
const char *format, ...)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
va_list val;
|
|
Packit |
db064d |
int ret;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
va_start(val, format);
|
|
Packit |
db064d |
ret = vsnprint_field(buf, n, f, spacing, format, val);
|
|
Packit |
db064d |
va_end(val);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return ret;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
void dump_portinfo(void *pi, int tabs)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
int field, i;
|
|
Packit |
db064d |
char val[64];
|
|
Packit |
db064d |
char buf[1024];
|
|
Packit |
db064d |
|
|
Packit |
db064d |
for (field = IB_PORT_FIRST_F; field < IB_PORT_LAST_F; field++) {
|
|
Packit |
db064d |
for (i=0;i
|
|
Packit |
db064d |
printf("\t");
|
|
Packit |
db064d |
if (field == IB_PORT_MKEY_F && show_keys == 0) {
|
|
Packit |
db064d |
snprint_field(buf, 1024, field, 32, NOT_DISPLAYED_STR);
|
|
Packit |
db064d |
} else {
|
|
Packit |
db064d |
mad_decode_field(pi, field, val);
|
|
Packit |
db064d |
if (!mad_dump_field(field, buf, 1024, val))
|
|
Packit |
db064d |
return;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
printf("%s\n", buf);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
for (field = IB_PORT_CAPMASK2_F;
|
|
Packit |
db064d |
field < IB_PORT_LINK_SPEED_EXT_LAST_F; field++) {
|
|
Packit |
db064d |
for (i=0;i
|
|
Packit |
db064d |
printf("\t");
|
|
Packit |
db064d |
mad_decode_field(pi, field, val);
|
|
Packit |
db064d |
if (!mad_dump_field(field, buf, 1024, val))
|
|
Packit |
db064d |
return;
|
|
Packit |
db064d |
printf("%s\n", buf);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
op_fn_t *match_op(const match_rec_t match_tbl[], char *name)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
const match_rec_t *r;
|
|
Packit |
db064d |
for (r = match_tbl; r->name; r++)
|
|
Packit |
db064d |
if (!strcasecmp(r->name, name) ||
|
|
Packit |
db064d |
(r->alias && !strcasecmp(r->alias, name)))
|
|
Packit |
db064d |
return r->fn;
|
|
Packit |
db064d |
return NULL;
|
|
Packit |
db064d |
}
|