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.campb...@qlogic.com> --- 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 majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html