1 /* 2 * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved. 3 * Copyright (c) 2010,2011 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 2011,2016 Oracle and/or its affiliates. All rights reserved. 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 * 34 */ 35 36 #if HAVE_CONFIG_H 37 # include <config.h> 38 #endif /* HAVE_CONFIG_H */ 39 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <unistd.h> 43 #include <string.h> 44 #include <getopt.h> 45 #include <errno.h> 46 47 #include <infiniband/umad.h> 48 #include <infiniband/mad.h> 49 50 #include "ibdiag_common.h" 51 52 enum port_ops { 53 QUERY, 54 ENABLE, 55 RESET, 56 DISABLE, 57 SPEED, 58 ESPEED, 59 FDR10SPEED, 60 WIDTH, 61 DOWN, 62 ARM, 63 ACTIVE, 64 VLS, 65 MTU, 66 LID, 67 SMLID, 68 LMC, 69 MKEY, 70 MKEYLEASE, 71 MKEYPROT, 72 ON, 73 OFF 74 }; 75 76 struct ibmad_port *srcport; 77 uint64_t speed = 0; /* no state change */ 78 uint64_t espeed = 0; /* no state change */ 79 uint64_t fdr10 = 0; /* no state change */ 80 uint64_t width = 0; /* no state change */ 81 uint64_t lid; 82 uint64_t smlid; 83 uint64_t lmc; 84 uint64_t mtu; 85 uint64_t vls = 0; /* no state change */ 86 uint64_t mkey; 87 uint64_t mkeylease; 88 uint64_t mkeyprot; 89 90 struct { 91 const char *name; 92 uint64_t *val; 93 int set; 94 } port_args[] = { 95 {"query", NULL, 0}, /* QUERY */ 96 {"enable", NULL, 0}, /* ENABLE */ 97 {"reset", NULL, 0}, /* RESET */ 98 {"disable", NULL, 0}, /* DISABLE */ 99 {"speed", &speed, 0}, /* SPEED */ 100 {"espeed", &espeed, 0}, /* EXTENDED SPEED */ 101 {"fdr10", &fdr10, 0}, /* FDR10 SPEED */ 102 {"width", &width, 0}, /* WIDTH */ 103 {"down", NULL, 0}, /* DOWN */ 104 {"arm", NULL, 0}, /* ARM */ 105 {"active", NULL, 0}, /* ACTIVE */ 106 {"vls", &vls, 0}, /* VLS */ 107 {"mtu", &mtu, 0}, /* MTU */ 108 {"lid", &lid, 0}, /* LID */ 109 {"smlid", &smlid, 0}, /* SMLID */ 110 {"lmc", &lmc, 0}, /* LMC */ 111 {"mkey", &mkey, 0}, /* MKEY */ 112 {"mkeylease", &mkeylease, 0}, /* MKEY LEASE */ 113 {"mkeyprot", &mkeyprot, 0}, /* MKEY PROTECT BITS */ 114 {"on", NULL, 0}, /* ON */ 115 {"off", NULL, 0}, /* OFF */ 116 }; 117 118 #define NPORT_ARGS (sizeof(port_args) / sizeof(port_args[0])) 119 120 /*******************************************/ 121 122 /* 123 * Return 1 if node is a switch, else zero. 124 */ 125 static int get_node_info(ib_portid_t * dest, uint8_t * data) 126 { 127 int node_type; 128 129 if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport)) 130 IBEXIT("smp query nodeinfo failed"); 131 132 node_type = mad_get_field(data, 0, IB_NODE_TYPE_F); 133 if (node_type == IB_NODE_SWITCH) /* Switch NodeType ? */ 134 return 1; 135 else 136 return 0; 137 } 138 139 static int get_port_info(ib_portid_t * dest, uint8_t * data, int portnum, 140 int is_switch) 141 { 142 uint8_t smp[IB_SMP_DATA_SIZE]; 143 uint8_t *info; 144 int cap_mask; 145 146 if (is_switch) { 147 if (!smp_query_via(smp, dest, IB_ATTR_PORT_INFO, 0, 0, srcport)) 148 IBEXIT("smp query port 0 portinfo failed"); 149 info = smp; 150 } else 151 info = data; 152 153 if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport)) 154 IBEXIT("smp query portinfo failed"); 155 cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F); 156 return (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)); 157 } 158 159 static void show_port_info(ib_portid_t * dest, uint8_t * data, int portnum, 160 int espeed_cap, int is_switch) 161 { 162 char buf[2300]; 163 char val[64]; 164 165 mad_dump_portstates(buf, sizeof buf, data, sizeof *data); 166 mad_decode_field(data, IB_PORT_LID_F, val); 167 mad_dump_field(IB_PORT_LID_F, buf + strlen(buf), 168 sizeof buf - strlen(buf), val); 169 sprintf(buf + strlen(buf), "%s", "\n"); 170 mad_decode_field(data, IB_PORT_SMLID_F, val); 171 mad_dump_field(IB_PORT_SMLID_F, buf + strlen(buf), 172 sizeof buf - strlen(buf), val); 173 sprintf(buf + strlen(buf), "%s", "\n"); 174 mad_decode_field(data, IB_PORT_LMC_F, val); 175 mad_dump_field(IB_PORT_LMC_F, buf + strlen(buf), 176 sizeof buf - strlen(buf), val); 177 sprintf(buf + strlen(buf), "%s", "\n"); 178 mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val); 179 mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F, buf + strlen(buf), 180 sizeof buf - strlen(buf), val); 181 sprintf(buf + strlen(buf), "%s", "\n"); 182 mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val); 183 mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + strlen(buf), 184 sizeof buf - strlen(buf), val); 185 sprintf(buf + strlen(buf), "%s", "\n"); 186 mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val); 187 mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf), 188 sizeof buf - strlen(buf), val); 189 sprintf(buf + strlen(buf), "%s", "\n"); 190 mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, val); 191 mad_dump_field(IB_PORT_LINK_SPEED_SUPPORTED_F, buf + strlen(buf), 192 sizeof buf - strlen(buf), val); 193 sprintf(buf + strlen(buf), "%s", "\n"); 194 mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val); 195 mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf + strlen(buf), 196 sizeof buf - strlen(buf), val); 197 sprintf(buf + strlen(buf), "%s", "\n"); 198 mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, val); 199 mad_dump_field(IB_PORT_LINK_SPEED_ACTIVE_F, buf + strlen(buf), 200 sizeof buf - strlen(buf), val); 201 sprintf(buf + strlen(buf), "%s", "\n"); 202 if (espeed_cap) { 203 mad_decode_field(data, IB_PORT_LINK_SPEED_EXT_SUPPORTED_F, val); 204 mad_dump_field(IB_PORT_LINK_SPEED_EXT_SUPPORTED_F, 205 buf + strlen(buf), sizeof buf - strlen(buf), 206 val); 207 sprintf(buf + strlen(buf), "%s", "\n"); 208 mad_decode_field(data, IB_PORT_LINK_SPEED_EXT_ENABLED_F, val); 209 mad_dump_field(IB_PORT_LINK_SPEED_EXT_ENABLED_F, 210 buf + strlen(buf), sizeof buf - strlen(buf), 211 val); 212 sprintf(buf + strlen(buf), "%s", "\n"); 213 mad_decode_field(data, IB_PORT_LINK_SPEED_EXT_ACTIVE_F, val); 214 mad_dump_field(IB_PORT_LINK_SPEED_EXT_ACTIVE_F, 215 buf + strlen(buf), sizeof buf - strlen(buf), 216 val); 217 sprintf(buf + strlen(buf), "%s", "\n"); 218 } 219 if (!is_switch || portnum == 0) { 220 if (show_keys) { 221 mad_decode_field(data, IB_PORT_MKEY_F, val); 222 mad_dump_field(IB_PORT_MKEY_F, buf + strlen(buf), 223 sizeof buf - strlen(buf), val); 224 } else 225 snprint_field(buf+strlen(buf), sizeof(buf)-strlen(buf), 226 IB_PORT_MKEY_F, 32, NOT_DISPLAYED_STR); 227 sprintf(buf+strlen(buf), "%s", "\n"); 228 mad_decode_field(data, IB_PORT_MKEY_LEASE_F, val); 229 mad_dump_field(IB_PORT_MKEY_LEASE_F, buf + strlen(buf), 230 sizeof buf - strlen(buf), val); 231 sprintf(buf+strlen(buf), "%s", "\n"); 232 mad_decode_field(data, IB_PORT_MKEY_PROT_BITS_F, val); 233 mad_dump_field(IB_PORT_MKEY_PROT_BITS_F, buf + strlen(buf), 234 sizeof buf - strlen(buf), val); 235 sprintf(buf+strlen(buf), "%s", "\n"); 236 } 237 238 printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf); 239 } 240 241 static void set_port_info(ib_portid_t * dest, uint8_t * data, int portnum, 242 int espeed_cap, int is_switch) 243 { 244 unsigned mod; 245 246 mod = portnum; 247 if (espeed_cap) 248 mod |= 1<<31; 249 if (!smp_set_via(data, dest, IB_ATTR_PORT_INFO, mod, 0, srcport)) 250 IBEXIT("smp set portinfo failed"); 251 252 printf("\nAfter PortInfo set:\n"); 253 show_port_info(dest, data, portnum, espeed_cap, is_switch); 254 } 255 256 static void get_mlnx_ext_port_info(ib_portid_t * dest, uint8_t * data, int portnum) 257 { 258 if (!smp_query_via(data, dest, IB_ATTR_MLNX_EXT_PORT_INFO, 259 portnum, 0, srcport)) 260 IBEXIT("smp query ext portinfo failed"); 261 } 262 263 static void show_mlnx_ext_port_info(ib_portid_t * dest, uint8_t * data, int portnum) 264 { 265 char buf[256]; 266 267 mad_dump_mlnx_ext_port_info(buf, sizeof buf, data, IB_SMP_DATA_SIZE); 268 269 printf("# MLNX ext Port info: %s port %d\n%s", portid2str(dest), 270 portnum, buf); 271 } 272 273 static void set_mlnx_ext_port_info(ib_portid_t * dest, uint8_t * data, int portnum) 274 { 275 if (!smp_set_via(data, dest, IB_ATTR_MLNX_EXT_PORT_INFO, 276 portnum, 0, srcport)) 277 IBEXIT("smp set MLNX ext portinfo failed"); 278 279 printf("\nAfter MLNXExtendedPortInfo set:\n"); 280 show_mlnx_ext_port_info(dest, data, portnum); 281 } 282 283 static int get_link_width(int lwe, int lws) 284 { 285 if (lwe == 255) 286 return lws; 287 else 288 return lwe; 289 } 290 291 static int get_link_speed(int lse, int lss) 292 { 293 if (lse == 15) 294 return lss; 295 else 296 return lse; 297 } 298 299 static int get_link_speed_ext(int lsee, int lses) 300 { 301 if (lsee == 31) 302 return lses; 303 else 304 return lsee; 305 } 306 307 static void validate_width(int width, int peerwidth, int lwa) 308 { 309 if ((width & peerwidth & 0x8)) { 310 if (lwa != 8) 311 IBWARN 312 ("Peer ports operating at active width %d rather than 8 (12x)", 313 lwa); 314 } else if ((width & peerwidth & 0x4)) { 315 if (lwa != 4) 316 IBWARN 317 ("Peer ports operating at active width %d rather than 4 (8x)", 318 lwa); 319 } else if ((width & peerwidth & 0x2)) { 320 if (lwa != 2) 321 IBWARN 322 ("Peer ports operating at active width %d rather than 2 (4x)", 323 lwa); 324 } else if ((width & peerwidth & 0x10)) { 325 if (lwa != 16) 326 IBWARN 327 ("Peer ports operating at active width %d rather than 16 (2x)", 328 lwa); 329 } else if ((width & peerwidth & 0x1)) { 330 if (lwa != 1) 331 IBWARN 332 ("Peer ports operating at active width %d rather than 1 (1x)", 333 lwa); 334 } 335 } 336 337 static void validate_speed(int speed, int peerspeed, int lsa) 338 { 339 if ((speed & peerspeed & 0x4)) { 340 if (lsa != 4) 341 IBWARN 342 ("Peer ports operating at active speed %d rather than 4 (10.0 Gbps)", 343 lsa); 344 } else if ((speed & peerspeed & 0x2)) { 345 if (lsa != 2) 346 IBWARN 347 ("Peer ports operating at active speed %d rather than 2 (5.0 Gbps)", 348 lsa); 349 } else if ((speed & peerspeed & 0x1)) { 350 if (lsa != 1) 351 IBWARN 352 ("Peer ports operating at active speed %d rather than 1 (2.5 Gbps)", 353 lsa); 354 } 355 } 356 357 static void validate_extended_speed(int espeed, int peerespeed, int lsea) 358 { 359 if ((espeed & peerespeed & 0x2)) { 360 if (lsea != 2) 361 IBWARN 362 ("Peer ports operating at active extended speed %d rather than 2 (25.78125 Gbps)", 363 lsea); 364 } else if ((espeed & peerespeed & 0x1)) { 365 if (lsea != 1) 366 IBWARN 367 ("Peer ports operating at active extended speed %d rather than 1 (14.0625 Gbps)", 368 lsea); 369 } 370 } 371 372 int main(int argc, char **argv) 373 { 374 int mgmt_classes[3] = 375 { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS }; 376 ib_portid_t portid = { 0 }; 377 int port_op = -1; 378 int is_switch, is_peer_switch, espeed_cap, peer_espeed_cap; 379 int state, physstate, lwe, lws, lwa, lse, lss, lsa, lsee, lses, lsea, 380 fdr10s, fdr10e, fdr10a; 381 int peerlocalportnum, peerlwe, peerlws, peerlwa, peerlse, peerlss, 382 peerlsa, peerlsee, peerlses, peerlsea, peerfdr10s, peerfdr10e, 383 peerfdr10a; 384 int peerwidth, peerspeed, peerespeed; 385 uint8_t data[IB_SMP_DATA_SIZE] = { 0 }; 386 uint8_t data2[IB_SMP_DATA_SIZE] = { 0 }; 387 ib_portid_t peerportid = { 0 }; 388 int portnum = 0; 389 ib_portid_t selfportid = { 0 }; 390 int selfport = 0; 391 int changed = 0; 392 int i; 393 uint32_t vendorid, rem_vendorid; 394 uint16_t devid, rem_devid; 395 uint64_t val; 396 char *endp; 397 char usage_args[] = "<dest dr_path|lid|guid> <portnum> [<op>]\n" 398 "\nSupported ops: enable, disable, on, off, reset, speed, espeed, fdr10,\n" 399 "\twidth, query, down, arm, active, vls, mtu, lid, smlid, lmc,\n" 400 "\tmkey, mkeylease, mkeyprot\n"; 401 const char *usage_examples[] = { 402 "3 1 disable\t\t\t# by lid", 403 "-G 0x2C9000100D051 1 enable\t# by guid", 404 "-D 0 1\t\t\t# (query) by direct route", 405 "3 1 reset\t\t\t# by lid", 406 "3 1 speed 1\t\t\t# by lid", 407 "3 1 width 1\t\t\t# by lid", 408 "-D 0 1 lid 0x1234 arm\t\t# by direct route", 409 NULL 410 }; 411 412 ibdiag_process_opts(argc, argv, NULL, NULL, NULL, NULL, 413 usage_args, usage_examples); 414 415 argc -= optind; 416 argv += optind; 417 418 if (argc < 2) 419 ibdiag_show_usage(); 420 421 srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3); 422 if (!srcport) 423 IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port); 424 425 smp_mkey_set(srcport, ibd_mkey); 426 427 if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0], 428 ibd_dest_type, ibd_sm_id, srcport) < 0) 429 IBEXIT("can't resolve destination port %s", argv[0]); 430 431 if (argc > 1) 432 portnum = strtol(argv[1], 0, 0); 433 434 for (i = 2; i < argc; i++) { 435 int j; 436 437 for (j = 0; j < NPORT_ARGS; j++) { 438 if (strcmp(argv[i], port_args[j].name)) 439 continue; 440 port_args[j].set = 1; 441 if (!port_args[j].val) { 442 if (port_op >= 0) 443 IBEXIT("%s only one of: ", 444 "query, enable, disable, " 445 "reset, down, arm, active, " 446 "can be specified", 447 port_args[j].name); 448 port_op = j; 449 break; 450 } 451 if (++i >= argc) 452 IBEXIT("%s requires an additional parameter", 453 port_args[j].name); 454 val = strtoull(argv[i], 0, 0); 455 switch (j) { 456 case SPEED: 457 if (val > 15) 458 IBEXIT("invalid speed value %ld", val); 459 break; 460 case ESPEED: 461 if (val > 31) 462 IBEXIT("invalid extended speed value %ld", val); 463 break; 464 case FDR10SPEED: 465 if (val > 1) 466 IBEXIT("invalid fdr10 speed value %ld", val); 467 break; 468 case WIDTH: 469 if ((val > 31 && val != 255)) 470 IBEXIT("invalid width value %ld", val); 471 break; 472 case VLS: 473 if (val == 0 || val > 5) 474 IBEXIT("invalid vls value %ld", val); 475 break; 476 case MTU: 477 if (val == 0 || val > 5) 478 IBEXIT("invalid mtu value %ld", val); 479 break; 480 case LID: 481 if (val == 0 || val >= 0xC000) 482 IBEXIT("invalid lid value 0x%lx", val); 483 break; 484 case SMLID: 485 if (val == 0 || val >= 0xC000) 486 IBEXIT("invalid smlid value 0x%lx", 487 val); 488 break; 489 case LMC: 490 if (val > 7) 491 IBEXIT("invalid lmc value %ld", val); 492 break; 493 case MKEY: 494 errno = 0; 495 val = strtoull(argv[i], &endp, 0); 496 if (errno || *endp != '\0') { 497 errno = 0; 498 val = strtoull(getpass("New M_Key: "), 499 &endp, 0); 500 if (errno || *endp != '\0') { 501 IBEXIT("Bad new M_Key\n"); 502 } 503 } 504 /* All 64-bit values are legal */ 505 break; 506 case MKEYLEASE: 507 if (val > 0xFFFF) 508 IBEXIT("invalid mkey lease time %ld", val); 509 break; 510 case MKEYPROT: 511 if (val > 3) 512 IBEXIT("invalid mkey protection bit setting %ld", val); 513 } 514 *port_args[j].val = val; 515 changed = 1; 516 break; 517 } 518 if (j == NPORT_ARGS) 519 IBEXIT("invalid operation: %s", argv[i]); 520 } 521 if (port_op < 0) 522 port_op = QUERY; 523 524 is_switch = get_node_info(&portid, data); 525 vendorid = (uint32_t) mad_get_field(data, 0, IB_NODE_VENDORID_F); 526 devid = (uint16_t) mad_get_field(data, 0, IB_NODE_DEVID_F); 527 528 if ((port_args[MKEY].set || port_args[MKEYLEASE].set || 529 port_args[MKEYPROT].set) && is_switch && portnum != 0) 530 IBEXIT("Can't set M_Key fields on switch port != 0"); 531 532 if (port_op != QUERY || changed) 533 printf("Initial %s PortInfo:\n", is_switch ? "Switch" : "CA/RT"); 534 else 535 printf("%s PortInfo:\n", is_switch ? "Switch" : "CA/RT"); 536 espeed_cap = get_port_info(&portid, data, portnum, is_switch); 537 show_port_info(&portid, data, portnum, espeed_cap, is_switch); 538 if (is_mlnx_ext_port_info_supported(vendorid, devid)) { 539 get_mlnx_ext_port_info(&portid, data2, portnum); 540 show_mlnx_ext_port_info(&portid, data2, portnum); 541 } 542 543 if (port_op != QUERY || changed) { 544 /* 545 * If we aren't setting the LID and the LID is the default, 546 * the SMA command will fail due to an invalid LID. 547 * Set it to something unlikely but valid. 548 */ 549 physstate = mad_get_field(data, 0, IB_PORT_PHYS_STATE_F); 550 551 val = mad_get_field(data, 0, IB_PORT_LID_F); 552 if (!port_args[LID].set && (!val || val == 0xFFFF)) 553 mad_set_field(data, 0, IB_PORT_LID_F, 0x1234); 554 val = mad_get_field(data, 0, IB_PORT_SMLID_F); 555 if (!port_args[SMLID].set && (!val || val == 0xFFFF)) 556 mad_set_field(data, 0, IB_PORT_SMLID_F, 0x1234); 557 mad_set_field(data, 0, IB_PORT_STATE_F, 0); /* NOP */ 558 mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 0); /* NOP */ 559 560 switch (port_op) { 561 case ON: 562 /* Enable only if state is Disable */ 563 if(physstate != 3) { 564 printf("Port is already in enable state\n"); 565 goto close_port; 566 } 567 case ENABLE: 568 case RESET: 569 /* Polling */ 570 mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2); 571 break; 572 case OFF: 573 case DISABLE: 574 printf("Disable may be irreversible\n"); 575 mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 3); 576 break; 577 case DOWN: 578 mad_set_field(data, 0, IB_PORT_STATE_F, 1); 579 break; 580 case ARM: 581 mad_set_field(data, 0, IB_PORT_STATE_F, 3); 582 break; 583 case ACTIVE: 584 mad_set_field(data, 0, IB_PORT_STATE_F, 4); 585 break; 586 } 587 588 /* always set enabled speeds/width - defaults to NOP */ 589 mad_set_field(data, 0, IB_PORT_LINK_SPEED_ENABLED_F, speed); 590 mad_set_field(data, 0, IB_PORT_LINK_SPEED_EXT_ENABLED_F, espeed); 591 mad_set_field(data, 0, IB_PORT_LINK_WIDTH_ENABLED_F, width); 592 593 if (port_args[VLS].set) 594 mad_set_field(data, 0, IB_PORT_OPER_VLS_F, vls); 595 if (port_args[MTU].set) 596 mad_set_field(data, 0, IB_PORT_NEIGHBOR_MTU_F, mtu); 597 if (port_args[LID].set) 598 mad_set_field(data, 0, IB_PORT_LID_F, lid); 599 if (port_args[SMLID].set) 600 mad_set_field(data, 0, IB_PORT_SMLID_F, smlid); 601 if (port_args[LMC].set) 602 mad_set_field(data, 0, IB_PORT_LMC_F, lmc); 603 604 if (port_args[FDR10SPEED].set) { 605 mad_set_field(data2, 0, 606 IB_MLNX_EXT_PORT_STATE_CHG_ENABLE_F, 607 FDR10); 608 mad_set_field(data2, 0, 609 IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F, 610 fdr10); 611 set_mlnx_ext_port_info(&portid, data2, portnum); 612 } 613 614 if (port_args[MKEY].set) 615 mad_set_field64(data, 0, IB_PORT_MKEY_F, mkey); 616 if (port_args[MKEYLEASE].set) 617 mad_set_field(data, 0, IB_PORT_MKEY_LEASE_F, 618 mkeylease); 619 if (port_args[MKEYPROT].set) 620 mad_set_field(data, 0, IB_PORT_MKEY_PROT_BITS_F, 621 mkeyprot); 622 623 set_port_info(&portid, data, portnum, espeed_cap, is_switch); 624 625 } else if (is_switch && portnum) { 626 /* Now, make sure PortState is Active */ 627 /* Or is PortPhysicalState LinkUp sufficient ? */ 628 mad_decode_field(data, IB_PORT_STATE_F, &state); 629 mad_decode_field(data, IB_PORT_PHYS_STATE_F, &physstate); 630 if (state == 4) { /* Active */ 631 mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, 632 &lwe); 633 mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, 634 &lws); 635 mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, 636 &lwa); 637 mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, 638 &lss); 639 mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, 640 &lsa); 641 mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, 642 &lse); 643 mad_decode_field(data2, 644 IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F, 645 &fdr10s); 646 mad_decode_field(data2, 647 IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F, 648 &fdr10e); 649 mad_decode_field(data2, 650 IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F, 651 &fdr10a); 652 if (espeed_cap) { 653 mad_decode_field(data, 654 IB_PORT_LINK_SPEED_EXT_SUPPORTED_F, 655 &lses); 656 mad_decode_field(data, 657 IB_PORT_LINK_SPEED_EXT_ACTIVE_F, 658 &lsea); 659 mad_decode_field(data, 660 IB_PORT_LINK_SPEED_EXT_ENABLED_F, 661 &lsee); 662 } 663 664 /* Setup portid for peer port */ 665 memcpy(&peerportid, &portid, sizeof(peerportid)); 666 if (portid.lid == 0) { 667 peerportid.drpath.cnt++; 668 if (peerportid.drpath.cnt == IB_SUBNET_PATH_HOPS_MAX) { 669 IBEXIT("Too many hops"); 670 } 671 } else { 672 peerportid.drpath.cnt = 1; 673 674 /* Set DrSLID to local lid */ 675 if (resolve_self(ibd_ca, ibd_ca_port, &selfportid, 676 &selfport, 0) < 0) 677 IBEXIT("could not resolve self"); 678 peerportid.drpath.drslid = (uint16_t) selfportid.lid; 679 peerportid.drpath.drdlid = 0xffff; 680 } 681 peerportid.drpath.p[peerportid.drpath.cnt] = (uint8_t) portnum; 682 683 /* Get peer port NodeInfo to obtain peer port number */ 684 is_peer_switch = get_node_info(&peerportid, data); 685 rem_vendorid = (uint32_t) mad_get_field(data, 0, IB_NODE_VENDORID_F); 686 rem_devid = (uint16_t) mad_get_field(data, 0, IB_NODE_DEVID_F); 687 688 mad_decode_field(data, IB_NODE_LOCAL_PORT_F, 689 &peerlocalportnum); 690 691 printf("Peer PortInfo:\n"); 692 /* Get peer port characteristics */ 693 peer_espeed_cap = get_port_info(&peerportid, data, 694 peerlocalportnum, 695 is_peer_switch); 696 if (is_mlnx_ext_port_info_supported(rem_vendorid, rem_devid)) 697 get_mlnx_ext_port_info(&peerportid, data2, 698 peerlocalportnum); 699 show_port_info(&peerportid, data, peerlocalportnum, 700 peer_espeed_cap, is_peer_switch); 701 if (is_mlnx_ext_port_info_supported(rem_vendorid, rem_devid)) 702 show_mlnx_ext_port_info(&peerportid, data2, 703 peerlocalportnum); 704 705 mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, 706 &peerlwe); 707 mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, 708 &peerlws); 709 mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, 710 &peerlwa); 711 mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, 712 &peerlss); 713 mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, 714 &peerlsa); 715 mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, 716 &peerlse); 717 mad_decode_field(data2, 718 IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F, 719 &peerfdr10s); 720 mad_decode_field(data2, 721 IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F, 722 &peerfdr10e); 723 mad_decode_field(data2, 724 IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F, 725 &peerfdr10a); 726 if (peer_espeed_cap) { 727 mad_decode_field(data, 728 IB_PORT_LINK_SPEED_EXT_SUPPORTED_F, 729 &peerlses); 730 mad_decode_field(data, 731 IB_PORT_LINK_SPEED_EXT_ACTIVE_F, 732 &peerlsea); 733 mad_decode_field(data, 734 IB_PORT_LINK_SPEED_EXT_ENABLED_F, 735 &peerlsee); 736 } 737 738 /* Now validate peer port characteristics */ 739 /* Examine Link Width */ 740 width = get_link_width(lwe, lws); 741 peerwidth = get_link_width(peerlwe, peerlws); 742 validate_width(width, peerwidth, lwa); 743 744 /* Examine Link Speeds */ 745 speed = get_link_speed(lse, lss); 746 peerspeed = get_link_speed(peerlse, peerlss); 747 validate_speed(speed, peerspeed, lsa); 748 749 if (espeed_cap && peer_espeed_cap) { 750 espeed = get_link_speed_ext(lsee, lses); 751 peerespeed = get_link_speed_ext(peerlsee, 752 peerlses); 753 validate_extended_speed(espeed, peerespeed, 754 lsea); 755 } else { 756 if (fdr10e & FDR10 && peerfdr10e & FDR10) { 757 if (!(fdr10a & FDR10)) 758 IBWARN("Peer ports operating at active speed %d rather than FDR10", lsa); 759 } 760 } 761 } 762 } 763 764 close_port: 765 mad_rpc_close_port(srcport); 766 exit(0); 767 } 768