]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ofed/management/opensm/osmtest/osmt_inform.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ofed / management / opensm / osmtest / osmt_inform.c
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
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
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
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
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
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
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
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  */
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  */
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 */