1 /*
2 * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. 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 #ifdef OSM_VENDOR_INTF_MTL
37 /*
38 * Abstract:
39 * Implementation of InformInfo testing flow..
40 * Top level is osmt_run_inform_info_flow:
41 * osmt_bind_inform_qp
42 * osmt_reg_unreg_inform_info
43 * osmt_send_trap_wait_for_forward
44 *
45 */
46
47 #include <unistd.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <complib/cl_debug.h>
52 #include <vendor/osm_vendor_mlx_hca.h>
53 #include "osmtest.h"
54 #include "osmt_inform.h"
55
56 /*
57 * Prepare an asynchronous QP (rcv) for sending inform info and
58 * handling the incoming reports.
59 *
60 */
61 ib_api_status_t
osmt_bind_inform_qp(IN osmtest_t * const p_osmt,OUT osmt_qp_ctx_t * p_qp_ctx)62 osmt_bind_inform_qp(IN osmtest_t * const p_osmt, OUT osmt_qp_ctx_t * p_qp_ctx)
63 {
64 ib_net64_t port_guid;
65 VAPI_hca_hndl_t hca_hndl;
66 VAPI_hca_id_t hca_id;
67 uint32_t port_num;
68 VAPI_ret_t vapi_ret;
69 IB_MGT_ret_t mgt_ret;
70 uint8_t hca_index;
71 osm_log_t *p_log = &p_osmt->log;
72 ib_api_status_t status = IB_SUCCESS;
73
74 OSM_LOG_ENTER(p_log);
75
76 port_guid = p_osmt->local_port.port_guid;
77
78 OSM_LOG(p_log, OSM_LOG_DEBUG, "Binding to port 0x%" PRIx64 "\n",
79 cl_ntoh64(port_guid));
80
81 /* obtain the hca name and port num from the guid */
82 OSM_LOG(p_log, OSM_LOG_DEBUG,
83 "Finding CA and Port that owns port guid 0x%" PRIx64 "\n",
84 port_guid);
85
86 mgt_ret =
87 osm_vendor_get_guid_ca_and_port(p_osmt->p_vendor,
88 port_guid,
89 &hca_hndl,
90 &hca_id[0], &hca_index, &port_num);
91 if (mgt_ret != IB_MGT_OK) {
92 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0109: "
93 "Unable to obtain CA and port (%d).\n");
94 status = IB_ERROR;
95 goto Exit;
96 }
97 #define OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY 0x80010000
98
99 strncpy(p_qp_ctx->qp_bind_hndl.hca_id, hca_id, sizeof(hca_id));
100 p_qp_ctx->qp_bind_hndl.hca_hndl = hca_hndl;
101 p_qp_ctx->qp_bind_hndl.port_num = port_num;
102 p_qp_ctx->qp_bind_hndl.max_outs_sq = 10;
103 p_qp_ctx->qp_bind_hndl.max_outs_rq = 10;
104 p_qp_ctx->qp_bind_hndl.qkey = OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY;
105
106 vapi_ret = osmt_mtl_init_opened_hca(&p_qp_ctx->qp_bind_hndl);
107 if (vapi_ret != VAPI_OK) {
108 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0114: "
109 "Error initializing QP.\n");
110 status = IB_ERROR;
111 goto Exit;
112 }
113
114 /* we use the pre-allocated buffers for send and receive :
115 send from buf[0]
116 receive from buf[2]
117 */
118 p_qp_ctx->p_send_buf =
119 (uint8_t *) p_qp_ctx->qp_bind_hndl.buf_ptr + GRH_LEN;
120 p_qp_ctx->p_recv_buf =
121 (uint8_t *) p_qp_ctx->qp_bind_hndl.buf_ptr + 2 * (GRH_LEN +
122 MAD_BLOCK_SIZE);
123
124 /* Need to clear assigned memory of p_send_buf - before using it to send any data */
125 memset(p_qp_ctx->p_send_buf, 0, MAD_BLOCK_SIZE);
126
127 status = IB_SUCCESS;
128 OSM_LOG(p_log, OSM_LOG_DEBUG, "Initialized QP:0x%X in VAPI Mode\n",
129 p_qp_ctx->qp_bind_hndl.qp_id);
130
131 OSM_LOG(p_log, OSM_LOG_DEBUG, "Binding to IB_MGT SMI\n");
132
133 /* we also need a QP0 handle for sending packets */
134 mgt_ret = IB_MGT_get_handle(hca_id, port_num, IB_MGT_SMI,
135 &(p_qp_ctx->ib_mgt_qp0_handle));
136 if (IB_MGT_OK != mgt_ret) {
137 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0115: "
138 "Error obtaining IB_MGT handle to SMI\n");
139 status = IB_ERROR;
140 goto Exit;
141 }
142
143 Exit:
144 OSM_LOG_EXIT(p_log);
145 return status;
146 }
147
148 /*
149 * Close the QP
150 */
151 void
osmt_unbind_inform_qp(IN osmtest_t * const p_osmt,IN osmt_qp_ctx_t * p_qp_ctx)152 osmt_unbind_inform_qp(IN osmtest_t * const p_osmt, IN osmt_qp_ctx_t * p_qp_ctx)
153 {
154 osm_log_t *p_log = &p_osmt->log;
155
156 OSM_LOG_ENTER(p_log);
157
158 osmt_mtl_mad_cleanup(&p_qp_ctx->qp_bind_hndl);
159
160 IB_MGT_release_handle(p_qp_ctx->ib_mgt_qp0_handle);
161
162 OSM_LOG(p_log, OSM_LOG_DEBUG, "Unbind QP handles\n");
163 OSM_LOG_EXIT(&p_osmt->log);
164 }
165
166 /*
167 * Register/Unregister to receive the given InformInfo
168 *
169 * Uses the qp context to send the inform info mad.
170 * Wait for GetResp(InformInfoResp)
171 *
172 */
173 ib_api_status_t
osmt_reg_unreg_inform_info(IN osmtest_t * p_osmt,IN osmt_qp_ctx_t * p_qp_ctx,IN ib_inform_info_t * p_inform_info,IN uint8_t reg_flag)174 osmt_reg_unreg_inform_info(IN osmtest_t * p_osmt,
175 IN osmt_qp_ctx_t * p_qp_ctx,
176 IN ib_inform_info_t * p_inform_info,
177 IN uint8_t reg_flag)
178 {
179 ib_sa_mad_t *p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_send_buf);
180 ib_inform_info_t *p_ii = ib_sa_mad_get_payload_ptr(p_sa_mad); /* SA Payload */
181 VAPI_ret_t vapi_ret;
182 VAPI_wc_desc_t wc_desc;
183 VAPI_ud_av_hndl_t avh;
184 static VAPI_wr_id_t wrid = 16198;
185 osm_log_t *p_log = &p_osmt->log;
186 ib_api_status_t status = IB_SUCCESS;
187
188 OSM_LOG_ENTER(&p_osmt->log);
189
190 /* init the MAD */
191 ib_mad_init_new((ib_mad_t *) p_sa_mad,
192 IB_MCLASS_SUBN_ADM,
193 (uint8_t) 2,
194 IB_MAD_METHOD_SET, cl_hton64(wrid), (ib_net16_t) 0, 0);
195 wrid++;
196 p_sa_mad->attr_id = IB_MAD_ATTR_INFORM_INFO;
197
198 /* copy the reference inform info */
199 memcpy(p_ii, p_inform_info, sizeof(ib_inform_info_t));
200
201 if (reg_flag) {
202 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
203 "Subscribing InformInfo: Traps from lid:0x%X to 0x%X, trap num :0x%X\n",
204 p_ii->lid_range_begin, p_ii->lid_range_end,
205 p_ii->g_or_v.generic.trap_num);
206 } else {
207 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
208 "UnSubscribing InformInfo: Traps from lid:0x%X to 0x%X\n",
209 p_ii->lid_range_begin, p_ii->lid_range_end);
210 }
211
212 /* set the subscribe bit */
213 if (reg_flag) {
214 p_ii->subscribe = 1;
215 } else {
216 p_ii->subscribe = 0;
217 /*
218 * we need to set the QPN on the mad if we unsubscribe:
219 * o13-2.1.1 - QPN Field need to be set when unsubscribing.
220 */
221 ib_inform_info_set_qpn(p_ii,
222 cl_hton32(p_qp_ctx->qp_bind_hndl.qp_id.
223 qp_num));
224 }
225
226 osm_dump_inform_info(&p_osmt->log, p_ii, OSM_LOG_DEBUG);
227
228 /* --------------------- PREP ------------------------- */
229 if (osmt_mtl_mad_post_recv_bufs(&p_qp_ctx->qp_bind_hndl, p_qp_ctx->p_recv_buf, 1, /* but we need only one mad at a time */
230 GRH_LEN + MAD_BLOCK_SIZE, wrid) != 1) {
231 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0120: "
232 "Error posting recv bufs\n");
233 status = IB_ERROR;
234 goto Exit;
235 }
236 OSM_LOG(p_log, OSM_LOG_DEBUG, "Posted recv bufs\n");
237
238 vapi_ret =
239 osmt_mtl_create_av(&p_qp_ctx->qp_bind_hndl,
240 p_osmt->local_port.sm_lid, &avh);
241 if (vapi_ret != VAPI_OK) {
242 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0121: "
243 "Error Preparing AVH (%s)\n",
244 VAPI_strerror_sym(vapi_ret));
245 status = IB_ERROR;
246 goto Exit;
247 }
248 OSM_LOG(p_log, OSM_LOG_DEBUG, "Prepared AVH\n");
249
250 if (osm_log_is_active(p_log, OSM_LOG_DEBUG)) {
251 osm_dump_sa_mad(p_log, (ib_sa_mad_t *) (p_qp_ctx->p_send_buf),
252 OSM_LOG_DEBUG);
253 #if 0
254 for (i = 56; i < 253; i++) {
255 if (i % 8 == 0) {
256 printf("\n %d : ", i);
257 }
258 printf("0x%02X ", p_qp_ctx->p_send_buf[i]);
259 }
260 #endif
261 printf("\n");
262 }
263
264 /* --------------------- SEND ------------------------- */
265 vapi_ret = osmt_mtl_mad_send(&p_qp_ctx->qp_bind_hndl, wrid, p_qp_ctx->p_send_buf, 1, /* SA is QP1 */
266 0, /* SL is 0 */
267 OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY,
268 avh);
269 if (vapi_ret != VAPI_OK) {
270 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0122: "
271 "Error sending mad (%s)\n",
272 VAPI_strerror_sym(vapi_ret));
273 status = IB_ERROR;
274 goto Exit;
275 }
276
277 vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl,
278 p_qp_ctx->qp_bind_hndl.sq_cq_hndl,
279 &wc_desc, 20, 10000, NULL);
280 if (vapi_ret != VAPI_OK) {
281 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0123: "
282 "Error getting send completion (%s)\n",
283 VAPI_strerror_sym(vapi_ret));
284 status = IB_ERROR;
285 goto Exit;
286 }
287
288 if (wc_desc.status != VAPI_SUCCESS) {
289 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0124: "
290 "Error on send completion (%s) (%d)\n",
291 VAPI_strerror_sym(wc_desc.status), wc_desc.status);
292 status = IB_ERROR;
293 goto Exit;
294 }
295 OSM_LOG(p_log, OSM_LOG_DEBUG, "Sent MAD\n");
296
297 /* --------------------- RECV ------------------------- */
298 vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl,
299 p_qp_ctx->qp_bind_hndl.rq_cq_hndl,
300 &wc_desc, 20, 10000, &avh);
301 if (vapi_ret != VAPI_SUCCESS) {
302 if (vapi_ret == VAPI_CQ_EMPTY) {
303 status = IB_TIMEOUT;
304 } else {
305 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0125: "
306 "Error receiving mad (%s)\n",
307 VAPI_strerror_sym(vapi_ret));
308 status = IB_ERROR;
309 }
310 goto Exit;
311 }
312
313 /* check to see if successful - by examination of the subscribe bit */
314 p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_recv_buf + GRH_LEN);
315
316 if (p_sa_mad->status != IB_SUCCESS) {
317 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "Remote error = %s\n",
318 ib_get_mad_status_str((ib_mad_t *) p_sa_mad));
319 status = IB_REMOTE_ERROR;
320 goto Exit;
321 }
322
323 if (p_sa_mad->method != IB_MAD_METHOD_GET_RESP) {
324 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
325 "Expected IB_MAD_METHOD_GET_RESP but got:(%X)\n",
326 p_sa_mad->method);
327 status = IB_REMOTE_ERROR;
328 goto Exit;
329 }
330
331 if (p_sa_mad->attr_id != IB_MAD_ATTR_INFORM_INFO) {
332 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
333 "Expected IB_MAD_ATTR_INFORM_INFO but got:(%X)\n",
334 cl_ntoh16(p_sa_mad->attr_id));
335 status = IB_REMOTE_ERROR;
336 goto Exit;
337 }
338
339 p_ii = ib_sa_mad_get_payload_ptr(p_sa_mad);
340 if (!p_ii->subscribe) {
341 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0126: "
342 "Subscribe/Unsubscribe Failed\n");
343 status = IB_REMOTE_ERROR;
344 }
345
346 Exit:
347 OSM_LOG_EXIT(&p_osmt->log);
348 return status;
349 }
350
351 /*
352 * Send a trap (Subn LID Route) Trap(Notice) through the regular
353 * connection QP connection (targeted at QP0)
354 *
355 * Wait for the trap repress
356 */
357 ib_api_status_t
osmt_send_trap_wait_for_forward(IN osmtest_t * const p_osmt,IN osmt_qp_ctx_t * p_qp_ctx)358 osmt_send_trap_wait_for_forward(IN osmtest_t * const p_osmt,
359 IN osmt_qp_ctx_t * p_qp_ctx)
360 {
361 ib_smp_t *p_smp = (ib_smp_t *) (p_qp_ctx->p_send_buf);
362 ib_mad_notice_attr_t *p_ntc = ib_smp_get_payload_ptr(p_smp);
363 ib_sa_mad_t *p_sa_mad;
364 IB_MGT_ret_t mgt_res;
365 VAPI_ret_t vapi_ret;
366 VAPI_wc_desc_t wc_desc;
367 VAPI_ud_av_hndl_t avh;
368 IB_ud_av_t av;
369 static VAPI_wr_id_t wrid = 2222;
370 osm_log_t *p_log = &p_osmt->log;
371 ib_api_status_t status = IB_SUCCESS;
372
373 OSM_LOG_ENTER(p_log);
374
375 OSM_LOG(p_log, OSM_LOG_INFO,
376 "Sending Traps to QP0 of SA LID:0x%X\n",
377 p_osmt->local_port.sm_lid);
378
379 /* init the MAD */
380 memset(p_smp, 0, sizeof(ib_smp_t));
381 ib_mad_init_new((ib_mad_t *) p_smp,
382 IB_MCLASS_SUBN_LID,
383 (uint8_t) 2,
384 IB_MAD_METHOD_TRAP, cl_hton64(wrid), (ib_net16_t) 0, 0);
385
386 wrid++;
387 p_smp->attr_id = IB_MAD_ATTR_NOTICE;
388
389 /* prepare the notice */
390 p_ntc->generic_type = 0x82; /* generic, type = 2 */
391 ib_notice_set_prod_type_ho(p_ntc, 1);
392 p_ntc->g_or_v.generic.trap_num = cl_hton16(0x26);
393 p_ntc->issuer_lid = cl_hton16(2);
394
395 /* --------------------- PREP ------------------------- */
396 if (osmt_mtl_mad_post_recv_bufs(&p_qp_ctx->qp_bind_hndl, p_qp_ctx->p_recv_buf, 1, /* we need to receive both trap repress and report */
397 GRH_LEN + MAD_BLOCK_SIZE, wrid) != 1) {
398 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0127: "
399 "Error posting recv bufs\n");
400 status = IB_ERROR;
401 goto Exit;
402 }
403 OSM_LOG(p_log, OSM_LOG_DEBUG, "Posted recv bufs\n");
404
405 av.dlid = p_osmt->local_port.sm_lid;
406 av.grh_flag = FALSE;
407
408 /* EZ: returned in HACK: use constants */
409 av.static_rate = 0; /* p_mad_addr->static_rate; */
410 av.src_path_bits = 1; /* p_mad_addr->path_bits; */
411 av.sl = 0; /* p_mad_addr->addr_type.gsi.service_level; */
412
413 OSM_LOG(p_log, OSM_LOG_DEBUG,
414 "av.dlid 0x%X, av.static_rate %d, av.path_bits %d\n",
415 cl_ntoh16(av.dlid), av.static_rate, av.src_path_bits);
416
417 /* send it */
418 mgt_res = IB_MGT_send_mad(p_qp_ctx->ib_mgt_qp0_handle, p_smp, /* actual payload */
419 &av, /* address vector */
420 wrid, /* casting the mad wrapper pointer for err cb */
421 p_osmt->opt.transaction_timeout);
422 if (mgt_res != IB_MGT_OK) {
423 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0128: "
424 "Error sending mad (%d)\n", mgt_res);
425 status = IB_ERROR;
426 goto Exit;
427 }
428
429 vapi_ret =
430 osmt_mtl_create_av(&p_qp_ctx->qp_bind_hndl,
431 p_osmt->local_port.sm_lid, &avh);
432 if (vapi_ret != VAPI_OK) {
433 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0129: "
434 "Error Preparing AVH (%s)\n",
435 VAPI_strerror_sym(vapi_ret));
436 status = IB_ERROR;
437 goto Exit;
438 }
439 OSM_LOG(p_log, OSM_LOG_DEBUG, "Prepared AVH\n");
440
441 OSM_LOG(p_log, OSM_LOG_DEBUG, "Trap MAD Sent\n");
442
443 /* --------------------- RECV ------------------------- */
444 vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl,
445 p_qp_ctx->qp_bind_hndl.rq_cq_hndl,
446 &wc_desc, 200, 10000, &avh);
447 if (vapi_ret != VAPI_SUCCESS) {
448 if (vapi_ret == VAPI_CQ_EMPTY) {
449 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0130: "
450 "Timeout receiving mad (%s)\n",
451 VAPI_strerror_sym(vapi_ret));
452 status = IB_TIMEOUT;
453 } else {
454 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0131: "
455 "Error receiving mad (%s)\n",
456 VAPI_strerror_sym(vapi_ret));
457 status = IB_ERROR;
458 }
459 goto Exit;
460 }
461
462 /* check to see if successful - by examination of the subscribe bit */
463 p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_recv_buf + GRH_LEN);
464
465 if (p_sa_mad->method == IB_MAD_METHOD_REPORT) {
466 if (p_sa_mad->attr_id == IB_MAD_ATTR_NOTICE) {
467 OSM_LOG(p_log, OSM_LOG_INFO, "Received the Report!\n");
468 status = IB_SUCCESS;
469 } else {
470 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1020"
471 "Did not receive a Report(Notice) but attr:%d\n",
472 cl_ntoh16(p_sa_mad->attr_id));
473 status = IB_ERROR;
474 }
475 } else {
476 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1020"
477 "Received an Unexpected Method:%d\n", p_smp->method);
478 status = IB_ERROR;
479 }
480
481 Exit:
482 OSM_LOG_EXIT(p_log);
483 return status;
484 }
485
486 /*
487 * Wait for a trap on QPn
488 *
489 */
490 ib_api_status_t
osmt_trap_wait(IN osmtest_t * const p_osmt,IN osmt_qp_ctx_t * p_qp_ctx)491 osmt_trap_wait(IN osmtest_t * const p_osmt, IN osmt_qp_ctx_t * p_qp_ctx)
492 {
493 ib_smp_t *p_smp = (ib_smp_t *) (p_qp_ctx->p_send_buf);
494 ib_sa_mad_t *p_sa_mad;
495 VAPI_ret_t vapi_ret;
496 VAPI_wc_desc_t wc_desc;
497 osm_log_t *p_log = &p_osmt->log;
498 ib_api_status_t status = IB_SUCCESS;
499
500 OSM_LOG_ENTER(p_log);
501
502 OSM_LOG(p_log, OSM_LOG_INFO,
503 "Waiting for Traps under QP:0x%X of SA LID:0x%X\n",
504 cl_ntoh16(p_osmt->local_port.sm_lid));
505
506 /* --------------------- RECV ------------------------- */
507 vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl,
508 p_qp_ctx->qp_bind_hndl.rq_cq_hndl,
509 &wc_desc,
510 // 200,
511 p_osmt->opt.wait_time * 100,
512 10000, NULL);
513 if (vapi_ret != VAPI_SUCCESS) {
514 if (vapi_ret == VAPI_CQ_EMPTY) {
515 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0130: "
516 "Timeout receiving mad (%s)\n",
517 VAPI_strerror_sym(vapi_ret));
518 status = IB_TIMEOUT;
519 } else {
520 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0131: "
521 "Error receiving mad (%s)\n",
522 VAPI_strerror_sym(vapi_ret));
523 status = IB_ERROR;
524 }
525 goto Exit;
526 }
527
528 /* check to see if successful - by examination of the subscribe bit */
529 p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_recv_buf + GRH_LEN);
530
531 if (p_sa_mad->method == IB_MAD_METHOD_REPORT) {
532 if (p_sa_mad->attr_id == IB_MAD_ATTR_NOTICE) {
533 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
534 "Received the Report!\n");
535 status = IB_SUCCESS;
536 } else {
537 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 1020"
538 "Did not receive a Report(Notice) but attr:%d\n",
539 cl_ntoh16(p_sa_mad->attr_id));
540 status = IB_ERROR;
541 }
542 } else {
543 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 1020"
544 "Received an Unexpected Method:%d\n", p_smp->method);
545 status = IB_ERROR;
546 }
547
548 Exit:
549 OSM_LOG_EXIT(p_log);
550 return status;
551 }
552
553 /*
554 * Initialize an inform info attribute:
555 * Catch all traps in the lid range of the p_osmt
556 *
557 */
558 ib_api_status_t
osmt_init_inform_info(IN osmtest_t * const p_osmt,OUT ib_inform_info_t * p_ii)559 osmt_init_inform_info(IN osmtest_t * const p_osmt, OUT ib_inform_info_t * p_ii)
560 {
561
562 memset(p_ii, 0, sizeof(ib_inform_info_t));
563 /* p_ii->lid_range_begin = cl_hton16(1); */
564 p_ii->lid_range_begin = 0xFFFF;
565 p_ii->lid_range_end = cl_hton16(p_osmt->max_lid);
566 p_ii->is_generic = 1; /* have to choose */
567 p_ii->trap_type = 0xFFFF; /* ALL */
568 p_ii->g_or_v.generic.trap_num = 0xFFFF; /* ALL */
569 p_ii->g_or_v.generic.node_type_lsb = 0xFFFF; /* ALL */
570 p_ii->g_or_v.generic.node_type_msb = 0xFF; /* ALL */
571 return IB_SUCCESS;
572 }
573
574 ib_api_status_t
osmt_init_inform_info_by_trap(IN osmtest_t * const p_osmt,IN ib_net16_t trap_num,OUT ib_inform_info_t * p_ii)575 osmt_init_inform_info_by_trap(IN osmtest_t * const p_osmt,
576 IN ib_net16_t trap_num,
577 OUT ib_inform_info_t * p_ii)
578 {
579
580 memset(p_ii, 0, sizeof(ib_inform_info_t));
581 /* p_ii->lid_range_begin = cl_hton16(1); */
582 p_ii->lid_range_begin = 0xFFFF;
583 p_ii->lid_range_end = cl_hton16(p_osmt->max_lid);
584 p_ii->is_generic = 1; /* have to choose */
585 p_ii->trap_type = 0xFFFF; /* ALL */
586 p_ii->g_or_v.generic.trap_num = trap_num; /* ALL */
587 p_ii->g_or_v.generic.node_type_lsb = 0xFFFF; /* ALL */
588 p_ii->g_or_v.generic.node_type_msb = 0xFF; /* ALL */
589 return IB_SUCCESS;
590 }
591
592 /*
593 * Run a complete inform info test flow:
594 * - try to unregister inform info (should fail)
595 * - register an inform info
596 * - try to unregister inform info (should succeed)
597 * - register an inform info
598 * - send a trap - sleep
599 * - check that a Report(Notice) arrived that match the sent one
600 *
601 */
osmt_run_inform_info_flow(IN osmtest_t * const p_osmt)602 ib_api_status_t osmt_run_inform_info_flow(IN osmtest_t * const p_osmt)
603 {
604 ib_inform_info_t inform_info;
605 ib_api_status_t status;
606 osmt_qp_ctx_t qp_ctx;
607
608 OSM_LOG_ENTER(&p_osmt->log);
609
610 /* bind the QP */
611 status = osmt_bind_inform_qp(p_osmt, &qp_ctx);
612 if (status != IB_SUCCESS) {
613 goto Exit;
614 }
615
616 /* init the inform info */
617 osmt_init_inform_info(p_osmt, &inform_info);
618
619 /* first try to unsubscribe */
620 status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 0);
621 /* WAS IB_REMOTE_ERROR */
622 if (status != IB_REMOTE_ERROR) {
623 if (status != IB_SUCCESS) {
624 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
625 "Error during UnSubscribe: (%s)\n",
626 ib_get_err_str(status));
627 goto Exit;
628 } else {
629 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
630 "Expected Failure to UnSubscribe non existing InformInfo\n");
631 status = IB_ERROR;
632 goto Exit;
633 }
634 }
635
636 /* send the inform info registration */
637 status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 1);
638 if (status != IB_SUCCESS) {
639 goto Exit;
640 }
641
642 /* send a trap through QP0 and wait on QPN */
643 status = osmt_send_trap_wait_for_forward(p_osmt, &qp_ctx);
644 if (status != IB_SUCCESS) {
645 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
646 "Error during Send Trap and Wait For Report: (%s)\n",
647 ib_get_err_str(status));
648 goto Exit;
649 }
650
651 /* try to unsubscribe for cleanup */
652 status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 0);
653
654 if (status != IB_SUCCESS) {
655 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
656 "Error during UnSubscribe: (%s)\n",
657 ib_get_err_str(status));
658 goto Exit;
659 } else {
660 if (status == IB_REMOTE_ERROR) {
661 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
662 "Remote Error during UnSubscribe\n");
663 status = IB_ERROR;
664 goto Exit;
665 }
666 }
667
668 Exit:
669 osmt_unbind_inform_qp(p_osmt, &qp_ctx);
670 OSM_LOG_EXIT(&p_osmt->log);
671 return status;
672 }
673
674 /*
675 * Run a complete inform info test flow:
676 * - try to unregister inform info (should fail)
677 * - register an inform info
678 * - try to unregister inform info (should succeed)
679 * - register an inform info
680 * - send a trap - sleep
681 * - check that a Report(Notice) arrived that match the sent one
682 *
683 */
osmt_run_trap64_65_flow(IN osmtest_t * const p_osmt)684 ib_api_status_t osmt_run_trap64_65_flow(IN osmtest_t * const p_osmt)
685 {
686 ib_inform_info_t inform_info;
687 ib_api_status_t status;
688 osmt_qp_ctx_t qp_ctx;
689
690 OSM_LOG_ENTER(&p_osmt->log);
691
692 /* bind the QP */
693 status = osmt_bind_inform_qp(p_osmt, &qp_ctx);
694 if (status != IB_SUCCESS) {
695 goto Exit;
696 }
697
698 /* init the inform info */
699 osmt_init_inform_info_by_trap(p_osmt, cl_hton16(64), &inform_info);
700
701 /* send the inform info registration */
702 status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 1);
703 if (status != IB_SUCCESS) {
704 goto Exit;
705 }
706
707 /*--------------------- PREP -------------------------*/
708 if (osmt_mtl_mad_post_recv_bufs(&qp_ctx.qp_bind_hndl, qp_ctx.p_recv_buf, 1, /* we need to receive the report */
709 GRH_LEN + MAD_BLOCK_SIZE, 1) != 1) {
710 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0127: "
711 "Error posting recv bufs for trap 64\n");
712 status = IB_ERROR;
713 goto Exit;
714 }
715
716 OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "Posted recv bufs for trap 64\n");
717
718 /* init the inform info */
719 osmt_init_inform_info_by_trap(p_osmt, cl_hton16(65), &inform_info);
720
721 /* send the inform info registration */
722 status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 1);
723 if (status != IB_SUCCESS) {
724 goto Exit;
725 }
726
727 /*--------------------- PREP -------------------------*/
728 if (osmt_mtl_mad_post_recv_bufs(&qp_ctx.qp_bind_hndl, qp_ctx.p_recv_buf, 1, /* we need to reveive the report */
729 GRH_LEN + MAD_BLOCK_SIZE, 1) != 1) {
730 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0127: "
731 "Error posting recv bufs for trap 65\n");
732 status = IB_ERROR;
733 goto Exit;
734 }
735 OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "Posted recv bufs for trap 65\n");
736
737 /* Sleep for x seconds in order to allow external script trap generation */
738 #if 0
739 sleep(p_osmt->opt.wait_time);
740 #endif
741
742 /* wait for a trap on QPN */
743 status = osmt_trap_wait(p_osmt, &qp_ctx);
744 if (status != IB_SUCCESS) {
745 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
746 "Error during Send Trap and Wait For Report: (%s)\n",
747 ib_get_err_str(status));
748 goto Exit;
749 }
750
751 /* try to unsubscribe for cleanup */
752 status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 0);
753
754 if (status != IB_SUCCESS) {
755 OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
756 "Error during UnSubscribe: (%s)\n",
757 ib_get_err_str(status));
758 goto Exit;
759 }
760
761 Exit:
762 osmt_unbind_inform_qp(p_osmt, &qp_ctx);
763 OSM_LOG_EXIT(&p_osmt->log);
764 return status;
765 }
766
767 #endif /* OSM_VENDOR_INTF_MTL */
768