From: Ralph Campbell <ralph.campbell-h88ZbnxC6KDQT0dZR+AlfA@public.gmane.org>
To: Sasha Khapyorsky <sashak-smomgflXvOZWk0Htik3J/w@public.gmane.org>
Cc: linux-rdma <linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: [PATCH] infiniband-diags/ibportstate: allow changes to CA portinfo parameters
Date: Thu, 5 Nov 2009 11:56:56 -0800 [thread overview]
Message-ID: <1257451016.992.173.camel@chromite.mv.qlogic.com> (raw)
This patch adds new commands to ibportstate to support initializing
the link for CAs connected back-to-back. It also allows more than
one field to be changed at the same time such as "lid 23 arm" or
"width 1 speed 3 enable".
Signed-off-by: Ralph Campbell <ralph.campbell-h88ZbnxC6KDQT0dZR+AlfA@public.gmane.org>
---
diff --git a/infiniband-diags/src/ibportstate.c b/infiniband-diags/src/ibportstate.c
index e631bfd..192b14e 100644
--- a/infiniband-diags/src/ibportstate.c
+++ b/infiniband-diags/src/ibportstate.c
@@ -46,93 +46,133 @@
#include "ibdiag_common.h"
+enum port_ops {
+ QUERY,
+ ENABLE,
+ RESET,
+ DISABLE,
+ SPEED,
+ WIDTH,
+ DOWN,
+ ARM,
+ ACTIVE,
+ VLS,
+ MTU,
+ LID,
+ SMLID,
+ LMC,
+};
+
struct ibmad_port *srcport;
+int speed = 15;
+int width = 255;
+int lid;
+int smlid;
+int lmc;
+int mtu;
+int vls;
+
+struct {
+ const char *name;
+ int *val;
+ int set;
+} port_args[] = {
+ { "query", NULL, 0 }, /* QUERY */
+ { "enable", NULL, 0 }, /* ENABLE */
+ { "reset", NULL, 0 }, /* RESET */
+ { "disable", NULL, 0 }, /* DISABLE */
+ { "speed", &speed, 0 }, /* SPEED */
+ { "width", &width, 0 }, /* WIDTH */
+ { "down", NULL, 0 }, /* DOWN */
+ { "arm", NULL, 0 }, /* ARM */
+ { "active", NULL, 0 }, /* ACTIVE */
+ { "vls", &vls, 0 }, /* VLS */
+ { "mtu", &mtu, 0 }, /* MTU */
+ { "lid", &lid, 0 }, /* LID */
+ { "smlid", &smlid, 0 }, /* SMLID */
+ { "lmc", &lmc, 0 }, /* LMC */
+};
+
+#define NPORT_ARGS (sizeof(port_args) / sizeof(port_args[0]))
/*******************************************/
+/*
+ * Return 1 if port is a switch, else zero.
+ */
static int get_node_info(ib_portid_t * dest, uint8_t * data)
{
int node_type;
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
- return -1;
+ IBERROR("smp query nodeinfo failed");
node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
if (node_type == IB_NODE_SWITCH) /* Switch NodeType ? */
- return 0;
- else
return 1;
+ else
+ return 0;
}
-static int get_port_info(ib_portid_t * dest, uint8_t * data, int portnum,
- int port_op)
+static void get_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
+{
+ if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
+ IBERROR("smp query portinfo failed");
+}
+
+static void show_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
{
char buf[2048];
char val[64];
- if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
- return -1;
-
- if (port_op != 4) {
- mad_dump_portstates(buf, sizeof buf, data, sizeof data);
- mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val);
- mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F,
- buf + strlen(buf), sizeof buf - strlen(buf),
- val);
- sprintf(buf + strlen(buf), "%s", "\n");
- mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val);
- mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + strlen(buf),
- sizeof buf - strlen(buf), val);
- sprintf(buf + strlen(buf), "%s", "\n");
- mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val);
- mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf),
- sizeof buf - strlen(buf), val);
- sprintf(buf + strlen(buf), "%s", "\n");
- mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, val);
- mad_dump_field(IB_PORT_LINK_SPEED_SUPPORTED_F,
- buf + strlen(buf), sizeof buf - strlen(buf),
- val);
- sprintf(buf + strlen(buf), "%s", "\n");
- mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
- mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf + strlen(buf),
- sizeof buf - strlen(buf), val);
- sprintf(buf + strlen(buf), "%s", "\n");
- mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, val);
- mad_dump_field(IB_PORT_LINK_SPEED_ACTIVE_F, buf + strlen(buf),
- sizeof buf - strlen(buf), val);
- sprintf(buf + strlen(buf), "%s", "\n");
- } else {
- mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
- mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf, sizeof buf,
- val);
- sprintf(buf + strlen(buf), "%s", "\n");
- }
+ mad_dump_portstates(buf, sizeof buf, data, sizeof data);
+ mad_decode_field(data, IB_PORT_LID_F, val);
+ mad_dump_field(IB_PORT_LID_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
+ mad_decode_field(data, IB_PORT_SMLID_F, val);
+ mad_dump_field(IB_PORT_SMLID_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
+ mad_decode_field(data, IB_PORT_LMC_F, val);
+ mad_dump_field(IB_PORT_LMC_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
+ mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val);
+ mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
+ mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val);
+ mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
+ mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val);
+ mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
+ mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, val);
+ mad_dump_field(IB_PORT_LINK_SPEED_SUPPORTED_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
+ mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
+ mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
+ mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, val);
+ mad_dump_field(IB_PORT_LINK_SPEED_ACTIVE_F, buf + strlen(buf),
+ sizeof buf - strlen(buf), val);
+ sprintf(buf + strlen(buf), "%s", "\n");
printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
- return 0;
}
-static int set_port_info(ib_portid_t * dest, uint8_t * data, int portnum,
- int port_op)
+static void set_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
{
- char buf[2048];
- char val[64];
-
if (!smp_set_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
- return -1;
-
- if (port_op != 4)
- mad_dump_portstates(buf, sizeof buf, data, sizeof data);
- else {
- mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
- mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf, sizeof buf,
- val);
- sprintf(buf + strlen(buf), "%s", "\n");
- }
+ IBERROR("smp set portinfo failed");
printf("\nAfter PortInfo set:\n");
- printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
- return 0;
+ show_port_info(dest, data, portnum);
}
static int get_link_width(int lwe, int lws)
@@ -201,22 +241,23 @@ int main(int argc, char **argv)
int mgmt_classes[3] =
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
ib_portid_t portid = { 0 };
- int err;
- int port_op = 0; /* default to query */
- int speed = 15;
- int is_switch = 1;
+ int port_op = -1;
+ int is_switch;
int state, physstate, lwe, lws, lwa, lse, lss, lsa;
int peerlocalportnum, peerlwe, peerlws, peerlwa, peerlse, peerlss,
peerlsa;
- int width = 255, peerwidth, peerspeed;
+ int peerwidth, peerspeed;
uint8_t data[IB_SMP_DATA_SIZE];
ib_portid_t peerportid = { 0 };
int portnum = 0;
ib_portid_t selfportid = { 0 };
int selfport = 0;
-
+ int changed = 0;
+ int i;
+ long val;
char usage_args[] = "<dest dr_path|lid|guid> <portnum> [<op>]\n"
- "\nSupported ops: enable, disable, reset, speed, width, query";
+ "\nSupported ops: enable, disable, reset, speed, width, query,\n"
+ "\tdown, arm, active, vls, mtu, lid, smlid, lmc\n";
const char *usage_examples[] = {
"3 1 disable\t\t\t# by lid",
"-G 0x2C9000100D051 1 enable\t# by guid",
@@ -224,6 +265,7 @@ int main(int argc, char **argv)
"3 1 reset\t\t\t# by lid",
"3 1 speed 1\t\t\t# by lid",
"3 1 width 1\t\t\t# by lid",
+ "-D 0 1 lid 0x1234 arm\t\t# by direct route",
NULL
};
@@ -247,78 +289,130 @@ int main(int argc, char **argv)
if (argc > 1)
portnum = strtol(argv[1], 0, 0);
- /* First, make sure it is a switch port if it is a "set" */
- if (argc >= 3) {
- if (!strcmp(argv[2], "enable"))
- port_op = 1;
- else if (!strcmp(argv[2], "disable"))
- port_op = 2;
- else if (!strcmp(argv[2], "reset"))
- port_op = 3;
- else if (!strcmp(argv[2], "speed")) {
- if (argc < 4)
- IBERROR
- ("speed requires an additional parameter");
- port_op = 4;
- /* Parse speed value */
- speed = strtoul(argv[3], 0, 0);
- if (speed > 15)
- IBERROR("invalid speed value %d", speed);
- } else if (!strcmp(argv[2], "width")) {
- if (argc < 4)
- IBERROR
- ("width requires an additional parameter");
- port_op = 5;
- /* Parse width value */
- width = strtoul(argv[3], 0, 0);
- if (width > 15 && width != 255)
- IBERROR("invalid width value %d", width);
+ for (i = 2; i < argc; i++) {
+ int j;
+
+ for (j = 0; j < NPORT_ARGS; j++) {
+ if (strcmp(argv[i], port_args[j].name))
+ continue;
+ port_args[j].set = 1;
+ if (!port_args[j].val) {
+ if (port_op >= 0)
+ IBERROR("%s only one of: ",
+ "query, enable, disable, "
+ "reset, down, arm, active, "
+ "can be specified",
+ port_args[j].name);
+ port_op = j;
+ break;
+ }
+ if (++i >= argc)
+ IBERROR("%s requires an additional parameter",
+ port_args[j].name);
+ val = strtol(argv[i], 0, 0);
+ switch (j) {
+ case SPEED:
+ if (val < 0 || val > 15)
+ IBERROR("invalid speed value %ld", val);
+ break;
+ case WIDTH:
+ if (val < 0 || (val > 15 && val != 255))
+ IBERROR("invalid width value %ld", val);
+ break;
+ case VLS:
+ if (val <= 0 || val > 5)
+ IBERROR("invalid vls value %ld", val);
+ break;
+ case MTU:
+ if (val <= 0 || val > 5)
+ IBERROR("invalid mtu value %ld", val);
+ break;
+ case LID:
+ if (val <= 0 || val >= 0xC000)
+ IBERROR("invalid lid value 0x%lx", val);
+ break;
+ case SMLID:
+ if (val <= 0 || val >= 0xC000)
+ IBERROR("invalid smlid value 0x%lx",
+ val);
+ break;
+ case LMC:
+ if (val < 0 || val > 7)
+ IBERROR("invalid lmc value %ld", val);
+ }
+ *port_args[j].val = (int) val;
+ changed = 1;
+ break;
}
+ if (j == NPORT_ARGS)
+ IBERROR("invalid operation: %s", argv[i]);
}
+ if (port_op < 0)
+ port_op = QUERY;
- err = get_node_info(&portid, data);
- if (err < 0)
- IBERROR("smp query nodeinfo failed");
- if (err) { /* not switch */
- if (port_op == 0) /* query op */
- is_switch = 0;
- else if (port_op == 2) /* disable */
- IBERROR("Node type not switch - disable not allowed");
- }
+ is_switch = get_node_info(&portid, data);
- if (port_op)
- printf("Initial PortInfo:\n");
+ if (port_op != QUERY || changed)
+ printf("Initial %s PortInfo:\n", is_switch ? "Switch" : "CA");
else
- printf("PortInfo:\n");
- err = get_port_info(&portid, data, portnum, port_op);
- if (err < 0)
- IBERROR("smp query portinfo failed");
-
- /* Only if one of the "set" options is chosen */
- if (port_op) {
- if ((port_op == 1) || (port_op == 3)) { /* Enable or Reset port */
- mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2); /* Polling */
- mad_set_field(data, 0, IB_PORT_STATE_F, 0); /* No Change */
- } else if (port_op == 2) { /* Disable port */
+ printf("%s PortInfo:\n", is_switch ? "Switch" : "CA");
+ get_port_info(&portid, data, portnum);
+ show_port_info(&portid, data, portnum);
+
+ if (port_op != QUERY || changed) {
+ /*
+ * If we aren't setting the LID and the LID is the default,
+ * the SMA command will fail due to an invalid LID.
+ * Set it to something unlikely but valid.
+ */
+ val = mad_get_field(data, 0, IB_PORT_LID_F);
+ if (!port_args[LID].set && (!val || val == 0xFFFF))
+ mad_set_field(data, 0, IB_PORT_LID_F, 0x1234);
+ val = mad_get_field(data, 0, IB_PORT_SMLID_F);
+ if (!port_args[SMLID].set && (!val || val == 0xFFFF))
+ mad_set_field(data, 0, IB_PORT_SMLID_F, 0x1234);
+ mad_set_field(data, 0, IB_PORT_STATE_F, 0); /* NOP */
+ mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 0); /* NOP */
+
+ switch (port_op) {
+ case ENABLE:
+ case RESET:
+ /* Polling */
+ mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2);
+ break;
+ case DISABLE:
printf("Disable may be irreversible\n");
- mad_set_field(data, 0, IB_PORT_STATE_F, 1); /* Down */
- mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 3); /* Disabled */
- } else if (port_op == 4) { /* Set speed */
+ mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 3);
+ break;
+ case DOWN:
+ mad_set_field(data, 0, IB_PORT_STATE_F, 1);
+ break;
+ case ARM:
+ mad_set_field(data, 0, IB_PORT_STATE_F, 3);
+ break;
+ case ACTIVE:
+ mad_set_field(data, 0, IB_PORT_STATE_F, 4);
+ break;
+ }
+ if (port_args[SPEED].set)
mad_set_field(data, 0, IB_PORT_LINK_SPEED_ENABLED_F,
speed);
- mad_set_field(data, 0, IB_PORT_STATE_F, 0);
- mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 0);
- } else if (port_op == 5) { /* Set width */
+ if (port_args[WIDTH].set)
mad_set_field(data, 0, IB_PORT_LINK_WIDTH_ENABLED_F,
width);
- mad_set_field(data, 0, IB_PORT_STATE_F, 0);
- mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 0);
- }
+ if (port_args[VLS].set)
+ mad_set_field(data, 0, IB_PORT_OPER_VLS_F, vls);
+ if (port_args[MTU].set)
+ mad_set_field(data, 0, IB_PORT_NEIGHBOR_MTU_F, mtu);
+ if (port_args[LID].set)
+ mad_set_field(data, 0, IB_PORT_LID_F, lid);
+ if (port_args[SMLID].set)
+ mad_set_field(data, 0, IB_PORT_SMLID_F, smlid);
+ if (port_args[LMC].set)
+ mad_set_field(data, 0, IB_PORT_LMC_F, lmc);
+
+ set_port_info(&portid, data, portnum);
- err = set_port_info(&portid, data, portnum, port_op);
- if (err < 0)
- IBERROR("smp set portinfo failed");
- /* query op - only compare peer port if switch port, exclude SP0 */
} else if (is_switch && portnum) {
/* Now, make sure PortState is Active */
/* Or is PortPhysicalState LinkUp sufficient ? */
@@ -351,20 +445,15 @@ int main(int argc, char **argv)
peerportid.drpath.drdlid = 0xffff;
/* Get peer port NodeInfo to obtain peer port number */
- err = get_node_info(&peerportid, data);
- if (err < 0)
- IBERROR("smp query nodeinfo failed");
+ get_node_info(&peerportid, data);
mad_decode_field(data, IB_NODE_LOCAL_PORT_F,
&peerlocalportnum);
printf("Peer PortInfo:\n");
/* Get peer port characteristics */
- err =
- get_port_info(&peerportid, data, peerlocalportnum,
- port_op);
- if (err < 0)
- IBERROR("smp query peer portinfo failed");
+ get_port_info(&peerportid, data, peerlocalportnum);
+ show_port_info(&peerportid, data, peerlocalportnum);
mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F,
&peerlwe);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next reply other threads:[~2009-11-05 19:56 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-05 19:56 Ralph Campbell [this message]
[not found] ` <1257451016.992.173.camel-/vjeY7uYZjrPXfVEPVhPGq6RkeBMCJyt@public.gmane.org>
2009-12-01 3:17 ` [PATCH] infiniband-diags/ibportstate: allow changes to CA portinfo parameters Sasha Khapyorsky
2009-12-01 17:27 ` Ralph Campbell
2009-12-01 18:09 ` Ira Weiny
2010-01-11 21:43 ` Ralph Campbell
[not found] ` <1263246218.3077.75.camel-/vjeY7uYZjrPXfVEPVhPGq6RkeBMCJyt@public.gmane.org>
2010-01-12 10:11 ` Sasha Khapyorsky
2010-01-13 20:16 ` Hal Rosenstock
2010-01-12 10:14 ` Sasha Khapyorsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1257451016.992.173.camel@chromite.mv.qlogic.com \
--to=ralph.campbell-h88zbnxc6kdqt0dzr+alfa@public.gmane.org \
--cc=linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=sashak-smomgflXvOZWk0Htik3J/w@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox