]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ofed/infiniband-diags/src/ibportstate.c
Upgrade Unbound to 1.6.0. More to follow.
[FreeBSD/FreeBSD.git] / contrib / ofed / infiniband-diags / src / ibportstate.c
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 }