/infiniband-diags-1.5.12/src/ibportstate.c

# · C · 674 lines · 561 code · 60 blank · 53 comment · 125 complexity · bb706e010daa25801546655dab1b1fc9 MD5 · raw file

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