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 */
get_node_info(ib_portid_t * dest,uint8_t * data)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
get_port_info(ib_portid_t * dest,uint8_t * data,int portnum,int is_switch)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
show_port_info(ib_portid_t * dest,uint8_t * data,int portnum,int espeed_cap,int is_switch)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
set_port_info(ib_portid_t * dest,uint8_t * data,int portnum,int espeed_cap,int is_switch)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
get_mlnx_ext_port_info(ib_portid_t * dest,uint8_t * data,int portnum)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
show_mlnx_ext_port_info(ib_portid_t * dest,uint8_t * data,int portnum)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
set_mlnx_ext_port_info(ib_portid_t * dest,uint8_t * data,int portnum)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
get_link_width(int lwe,int lws)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
get_link_speed(int lse,int lss)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
get_link_speed_ext(int lsee,int lses)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
validate_width(int width,int peerwidth,int lwa)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
validate_speed(int speed,int peerspeed,int lsa)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
validate_extended_speed(int espeed,int peerespeed,int lsea)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
main(int argc,char ** argv)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 /* FALLTHROUGH */
568 case ENABLE:
569 case RESET:
570 /* Polling */
571 mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2);
572 break;
573 case OFF:
574 case DISABLE:
575 printf("Disable may be irreversible\n");
576 mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 3);
577 break;
578 case DOWN:
579 mad_set_field(data, 0, IB_PORT_STATE_F, 1);
580 break;
581 case ARM:
582 mad_set_field(data, 0, IB_PORT_STATE_F, 3);
583 break;
584 case ACTIVE:
585 mad_set_field(data, 0, IB_PORT_STATE_F, 4);
586 break;
587 }
588
589 /* always set enabled speeds/width - defaults to NOP */
590 mad_set_field(data, 0, IB_PORT_LINK_SPEED_ENABLED_F, speed);
591 mad_set_field(data, 0, IB_PORT_LINK_SPEED_EXT_ENABLED_F, espeed);
592 mad_set_field(data, 0, IB_PORT_LINK_WIDTH_ENABLED_F, width);
593
594 if (port_args[VLS].set)
595 mad_set_field(data, 0, IB_PORT_OPER_VLS_F, vls);
596 if (port_args[MTU].set)
597 mad_set_field(data, 0, IB_PORT_NEIGHBOR_MTU_F, mtu);
598 if (port_args[LID].set)
599 mad_set_field(data, 0, IB_PORT_LID_F, lid);
600 if (port_args[SMLID].set)
601 mad_set_field(data, 0, IB_PORT_SMLID_F, smlid);
602 if (port_args[LMC].set)
603 mad_set_field(data, 0, IB_PORT_LMC_F, lmc);
604
605 if (port_args[FDR10SPEED].set) {
606 mad_set_field(data2, 0,
607 IB_MLNX_EXT_PORT_STATE_CHG_ENABLE_F,
608 FDR10);
609 mad_set_field(data2, 0,
610 IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F,
611 fdr10);
612 set_mlnx_ext_port_info(&portid, data2, portnum);
613 }
614
615 if (port_args[MKEY].set)
616 mad_set_field64(data, 0, IB_PORT_MKEY_F, mkey);
617 if (port_args[MKEYLEASE].set)
618 mad_set_field(data, 0, IB_PORT_MKEY_LEASE_F,
619 mkeylease);
620 if (port_args[MKEYPROT].set)
621 mad_set_field(data, 0, IB_PORT_MKEY_PROT_BITS_F,
622 mkeyprot);
623
624 set_port_info(&portid, data, portnum, espeed_cap, is_switch);
625
626 } else if (is_switch && portnum) {
627 /* Now, make sure PortState is Active */
628 /* Or is PortPhysicalState LinkUp sufficient ? */
629 mad_decode_field(data, IB_PORT_STATE_F, &state);
630 mad_decode_field(data, IB_PORT_PHYS_STATE_F, &physstate);
631 if (state == 4) { /* Active */
632 mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F,
633 &lwe);
634 mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F,
635 &lws);
636 mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F,
637 &lwa);
638 mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F,
639 &lss);
640 mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F,
641 &lsa);
642 mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F,
643 &lse);
644 mad_decode_field(data2,
645 IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F,
646 &fdr10s);
647 mad_decode_field(data2,
648 IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F,
649 &fdr10e);
650 mad_decode_field(data2,
651 IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F,
652 &fdr10a);
653 if (espeed_cap) {
654 mad_decode_field(data,
655 IB_PORT_LINK_SPEED_EXT_SUPPORTED_F,
656 &lses);
657 mad_decode_field(data,
658 IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
659 &lsea);
660 mad_decode_field(data,
661 IB_PORT_LINK_SPEED_EXT_ENABLED_F,
662 &lsee);
663 }
664
665 /* Setup portid for peer port */
666 memcpy(&peerportid, &portid, sizeof(peerportid));
667 if (portid.lid == 0) {
668 peerportid.drpath.cnt++;
669 if (peerportid.drpath.cnt == IB_SUBNET_PATH_HOPS_MAX) {
670 IBEXIT("Too many hops");
671 }
672 } else {
673 peerportid.drpath.cnt = 1;
674
675 /* Set DrSLID to local lid */
676 if (resolve_self(ibd_ca, ibd_ca_port, &selfportid,
677 &selfport, 0) < 0)
678 IBEXIT("could not resolve self");
679 peerportid.drpath.drslid = (uint16_t) selfportid.lid;
680 peerportid.drpath.drdlid = 0xffff;
681 }
682 peerportid.drpath.p[peerportid.drpath.cnt] = (uint8_t) portnum;
683
684 /* Get peer port NodeInfo to obtain peer port number */
685 is_peer_switch = get_node_info(&peerportid, data);
686 rem_vendorid = (uint32_t) mad_get_field(data, 0, IB_NODE_VENDORID_F);
687 rem_devid = (uint16_t) mad_get_field(data, 0, IB_NODE_DEVID_F);
688
689 mad_decode_field(data, IB_NODE_LOCAL_PORT_F,
690 &peerlocalportnum);
691
692 printf("Peer PortInfo:\n");
693 /* Get peer port characteristics */
694 peer_espeed_cap = get_port_info(&peerportid, data,
695 peerlocalportnum,
696 is_peer_switch);
697 if (is_mlnx_ext_port_info_supported(rem_vendorid, rem_devid))
698 get_mlnx_ext_port_info(&peerportid, data2,
699 peerlocalportnum);
700 show_port_info(&peerportid, data, peerlocalportnum,
701 peer_espeed_cap, is_peer_switch);
702 if (is_mlnx_ext_port_info_supported(rem_vendorid, rem_devid))
703 show_mlnx_ext_port_info(&peerportid, data2,
704 peerlocalportnum);
705
706 mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F,
707 &peerlwe);
708 mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F,
709 &peerlws);
710 mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F,
711 &peerlwa);
712 mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F,
713 &peerlss);
714 mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F,
715 &peerlsa);
716 mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F,
717 &peerlse);
718 mad_decode_field(data2,
719 IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F,
720 &peerfdr10s);
721 mad_decode_field(data2,
722 IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F,
723 &peerfdr10e);
724 mad_decode_field(data2,
725 IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F,
726 &peerfdr10a);
727 if (peer_espeed_cap) {
728 mad_decode_field(data,
729 IB_PORT_LINK_SPEED_EXT_SUPPORTED_F,
730 &peerlses);
731 mad_decode_field(data,
732 IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
733 &peerlsea);
734 mad_decode_field(data,
735 IB_PORT_LINK_SPEED_EXT_ENABLED_F,
736 &peerlsee);
737 }
738
739 /* Now validate peer port characteristics */
740 /* Examine Link Width */
741 width = get_link_width(lwe, lws);
742 peerwidth = get_link_width(peerlwe, peerlws);
743 validate_width(width, peerwidth, lwa);
744
745 /* Examine Link Speeds */
746 speed = get_link_speed(lse, lss);
747 peerspeed = get_link_speed(peerlse, peerlss);
748 validate_speed(speed, peerspeed, lsa);
749
750 if (espeed_cap && peer_espeed_cap) {
751 espeed = get_link_speed_ext(lsee, lses);
752 peerespeed = get_link_speed_ext(peerlsee,
753 peerlses);
754 validate_extended_speed(espeed, peerespeed,
755 lsea);
756 } else {
757 if (fdr10e & FDR10 && peerfdr10e & FDR10) {
758 if (!(fdr10a & FDR10))
759 IBWARN("Peer ports operating at active speed %d rather than FDR10", lsa);
760 }
761 }
762 }
763 }
764
765 close_port:
766 mad_rpc_close_port(srcport);
767 exit(0);
768 }
769