2 * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 #endif /* HAVE_CONFIG_H */
47 #include <sys/types.h>
50 #include <sys/ioctl.h>
57 #include <netinet/in.h>
59 #include <infiniband/common.h>
60 #include <infiniband/mad.h>
61 #include <infiniband/umad.h>
63 #include <ibdiag_common.h>
65 static const uint8_t CLASS_SUBN_DIRECTED_ROUTE = 0x81;
66 static const uint8_t CLASS_SUBN_LID_ROUTE = 0x1;
68 #define ATTR_NODE_DESC ((uint16_t)(htons(0x10)))
69 #define ATTR_NODE_INFO ((uint16_t)(htons(0x11)))
70 #define ATTR_PORT_INFO ((uint16_t)(htons(0x15)))
73 static int drmad_tid = 0x123;
75 static int debug, verbose;
77 char *argv0 = "smpdump";
87 uint8_t class_version;
101 uint8_t initial_path[64];
102 uint8_t return_path[64];
106 drsmp_get_init(void *umad, DRPath *path, int attr, int mod)
108 struct drsmp *smp = (struct drsmp *)(umad_get_mad(umad));
110 memset(smp, 0, sizeof (*smp));
112 smp->base_version = 1;
113 smp->mgmt_class = CLASS_SUBN_DIRECTED_ROUTE;
114 smp->class_version = 1;
117 smp->attr_id = (uint16_t)htons((uint16_t)attr);
118 smp->attr_mod = htonl(mod);
119 smp->tid = htonll(drmad_tid++);
120 smp->dr_slid = 0xffff;
121 smp->dr_dlid = 0xffff;
123 umad_set_addr(umad, 0xffff, 0, 0, 0);
126 memcpy(smp->initial_path, path->path, path->hop_cnt+1);
128 smp->hop_cnt = path->hop_cnt;
132 smp_get_init(void *umad, int lid, int attr, int mod)
134 struct drsmp *smp = (struct drsmp *)(umad_get_mad(umad));
136 memset(smp, 0, sizeof (*smp));
138 smp->base_version = 1;
139 smp->mgmt_class = CLASS_SUBN_LID_ROUTE;
140 smp->class_version = 1;
143 smp->attr_id = (uint16_t)htons((uint16_t)attr);
144 smp->attr_mod = htonl(mod);
145 smp->tid = htonll(drmad_tid++);
147 umad_set_addr(umad, lid, 0, 0xffff, 0);
151 drsmp_set_init(void *umad, DRPath *path, int attr, int mod, void *data)
153 struct drsmp *smp = (struct drsmp *)(umad_get_mad(umad));
155 memset(smp, 0, sizeof (*smp));
157 smp->method = 2; /* SET */
158 smp->attr_id = (uint16_t)htons((uint16_t)attr);
159 smp->attr_mod = htonl(mod);
160 smp->tid = htonll(drmad_tid++);
161 smp->dr_slid = 0xffff;
162 smp->dr_dlid = 0xffff;
164 umad_set_addr(umad, 0xffff, 0, 0, 0);
167 memcpy(smp->initial_path, path->path, path->hop_cnt+1);
170 memcpy(smp->data, data, sizeof smp->data);
172 smp->hop_cnt = path->hop_cnt;
176 drmad_status_str(struct drsmp *drsmp)
178 switch (drsmp->status) {
184 return "unknown error";
188 str2DRPath(char *str, DRPath *path)
194 DEBUG("DR str: %s", str);
195 while (str && *str) {
196 if ((s = strchr(str, ',')))
198 path->path[++path->hop_cnt] = atoi(str);
205 if (path->path[0] != 0 ||
206 (path->hop_cnt > 0 && dev_port && path->path[1] != dev_port)) {
207 DEBUG("hop 0 != 0 or hop 1 != dev_port");
212 return path->hop_cnt;
218 fprintf(stderr, "Usage: %s [-s(ring) -D(irect) -V(ersion) -C ca_name -P ca_port -t(imeout) timeout_ms] <dlid|dr_path> <attr> [mod]\n", argv0);
219 fprintf(stderr, "\tDR examples:\n");
220 fprintf(stderr, "\t\t%s -D 0,1,2,3,5 16 # NODE DESC\n", argv0);
221 fprintf(stderr, "\t\t%s -D 0,1,2 0x15 2 # PORT INFO, port 2\n", argv0);
222 fprintf(stderr, "\n\tLID routed examples:\n");
223 fprintf(stderr, "\t\t%s 3 0x15 2 # PORT INFO, lid 3 port 2\n", argv0);
224 fprintf(stderr, "\t\t%s 0xa0 0x11 # NODE INFO, lid 0xa0\n", argv0);
225 fprintf(stderr, "\n");
230 main(int argc, char *argv[])
232 int dump_char = 0, timeout_ms = 1000;
233 int dev_port = 0, mgmt_class = CLASS_SUBN_LID_ROUTE, dlid = 0;
237 int i, portid, mod = 0, attr;
242 static char const str_opts[] = "C:P:t:dsDVhu";
243 static const struct option long_opts[] = {
246 { "debug", 0, 0, 'd'},
247 { "sring", 0, 0, 's'},
248 { "Direct", 0, 0, 'D'},
249 { "timeout", 1, 0, 't'},
250 { "Version", 0, 0, 'V'},
251 { "help", 0, 0, 'h'},
252 { "usage", 0, 0, 'u'},
259 int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);
272 mgmt_class = CLASS_SUBN_DIRECTED_ROUTE;
278 dev_port = atoi(optarg);
281 timeout_ms = strtoul(optarg, 0, 0);
284 fprintf(stderr, "%s %s\n", argv0, get_build_version() );
297 if (mgmt_class == CLASS_SUBN_DIRECTED_ROUTE &&
298 str2DRPath(strdup(argv[0]), &path) < 0)
299 IBPANIC("bad path str '%s'", argv[0]);
301 if (mgmt_class == CLASS_SUBN_LID_ROUTE)
302 dlid = strtoul(argv[0], 0, 0);
304 attr = strtoul(argv[1], 0, 0);
306 mod = strtoul(argv[2], 0, 0);
309 IBPANIC("can't init UMAD library");
311 if ((portid = umad_open_port(dev_name, dev_port)) < 0)
312 IBPANIC("can't open UMAD port (%s:%d)", dev_name, dev_port);
314 if ((mad_agent = umad_register(portid, mgmt_class, 1, 0, 0)) < 0)
315 IBPANIC("Couldn't register agent for SMPs");
317 if (!(umad = umad_alloc(1, umad_size() + IB_MAD_SIZE)))
318 IBPANIC("can't alloc MAD");
320 smp = umad_get_mad(umad);
322 if (mgmt_class == CLASS_SUBN_DIRECTED_ROUTE)
323 drsmp_get_init(umad, &path, attr, mod);
325 smp_get_init(umad, dlid, attr, mod);
328 xdump(stderr, "before send:\n", smp, 256);
330 length = IB_MAD_SIZE;
331 if (umad_send(portid, mad_agent, umad, length, timeout_ms, 0) < 0)
332 IBPANIC("send failed");
334 if (umad_recv(portid, umad, &length, -1) != mad_agent)
335 IBPANIC("recv error: %s", drmad_status_str(smp));
338 xdump(stdout, 0, smp->data, 64);
340 fprintf(stdout, "SMP status: 0x%x\n", ntohs(smp->status));
345 for (i = 0; i < 64; ++i) {
352 fprintf(stdout, "SMP status: 0x%x\n", ntohs(smp->status));