Hi Ralph, On 11:56 Thu 05 Nov , Ralph Campbell wrote: > 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".
As far as I can see this changes a functionality of ibportstate dramatically. Actually it makes it more like to 'ibportset' than just 'ibportstate', correct? If so, wouldn't it be better to introduce a new tool - let's say 'ibportset' (or like this)? (Or even wider 'smpset' - however such 'smpset' can be done later following a real needs by extending ibportset or so). Don't understand me wrong I'm not disagree at all, just trying to find the best way to add such functionality to infiniband-diags. Sasha > > 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