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 */ 61ib_api_status_t 62osmt_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 143Exit: 144 OSM_LOG_EXIT(p_log); 145 return status; 146} 147 148/* 149 * Close the QP 150 */ 151void 152osmt_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 */ 173ib_api_status_t 174osmt_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 346Exit: 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 */ 357ib_api_status_t 358osmt_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 481Exit: 482 OSM_LOG_EXIT(p_log); 483 return status; 484} 485 486/* 487 * Wait for a trap on QPn 488 * 489 */ 490ib_api_status_t 491osmt_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 548Exit: 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 */ 558ib_api_status_t 559osmt_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 574ib_api_status_t 575osmt_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 */ 602ib_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 668Exit: 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 */ 684ib_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 761Exit: 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