1219820Sjeff/* 2219820Sjeff * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff * 34219820Sjeff */ 35219820Sjeff 36219820Sjeff#ifdef OSM_VENDOR_INTF_MTL 37219820Sjeff/* 38219820Sjeff * Abstract: 39219820Sjeff * Implementation of InformInfo testing flow.. 40219820Sjeff * Top level is osmt_run_inform_info_flow: 41219820Sjeff * osmt_bind_inform_qp 42219820Sjeff * osmt_reg_unreg_inform_info 43219820Sjeff * osmt_send_trap_wait_for_forward 44219820Sjeff * 45219820Sjeff */ 46219820Sjeff 47219820Sjeff#include <unistd.h> 48219820Sjeff#include <stdio.h> 49219820Sjeff#include <stdlib.h> 50219820Sjeff#include <string.h> 51219820Sjeff#include <complib/cl_debug.h> 52219820Sjeff#include <vendor/osm_vendor_mlx_hca.h> 53219820Sjeff#include "osmtest.h" 54219820Sjeff#include "osmt_inform.h" 55219820Sjeff 56219820Sjeff/* 57219820Sjeff * Prepare an asynchronous QP (rcv) for sending inform info and 58219820Sjeff * handling the incoming reports. 59219820Sjeff * 60219820Sjeff */ 61219820Sjeffib_api_status_t 62219820Sjeffosmt_bind_inform_qp(IN osmtest_t * const p_osmt, OUT osmt_qp_ctx_t * p_qp_ctx) 63219820Sjeff{ 64219820Sjeff ib_net64_t port_guid; 65219820Sjeff VAPI_hca_hndl_t hca_hndl; 66219820Sjeff VAPI_hca_id_t hca_id; 67219820Sjeff uint32_t port_num; 68219820Sjeff VAPI_ret_t vapi_ret; 69219820Sjeff IB_MGT_ret_t mgt_ret; 70219820Sjeff uint8_t hca_index; 71219820Sjeff osm_log_t *p_log = &p_osmt->log; 72219820Sjeff ib_api_status_t status = IB_SUCCESS; 73219820Sjeff 74219820Sjeff OSM_LOG_ENTER(p_log); 75219820Sjeff 76219820Sjeff port_guid = p_osmt->local_port.port_guid; 77219820Sjeff 78219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Binding to port 0x%" PRIx64 "\n", 79219820Sjeff cl_ntoh64(port_guid)); 80219820Sjeff 81219820Sjeff /* obtain the hca name and port num from the guid */ 82219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, 83219820Sjeff "Finding CA and Port that owns port guid 0x%" PRIx64 "\n", 84219820Sjeff port_guid); 85219820Sjeff 86219820Sjeff mgt_ret = 87219820Sjeff osm_vendor_get_guid_ca_and_port(p_osmt->p_vendor, 88219820Sjeff port_guid, 89219820Sjeff &hca_hndl, 90219820Sjeff &hca_id[0], &hca_index, &port_num); 91219820Sjeff if (mgt_ret != IB_MGT_OK) { 92219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0109: " 93219820Sjeff "Unable to obtain CA and port (%d).\n"); 94219820Sjeff status = IB_ERROR; 95219820Sjeff goto Exit; 96219820Sjeff } 97219820Sjeff#define OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY 0x80010000 98219820Sjeff 99219820Sjeff strncpy(p_qp_ctx->qp_bind_hndl.hca_id, hca_id, sizeof(hca_id)); 100219820Sjeff p_qp_ctx->qp_bind_hndl.hca_hndl = hca_hndl; 101219820Sjeff p_qp_ctx->qp_bind_hndl.port_num = port_num; 102219820Sjeff p_qp_ctx->qp_bind_hndl.max_outs_sq = 10; 103219820Sjeff p_qp_ctx->qp_bind_hndl.max_outs_rq = 10; 104219820Sjeff p_qp_ctx->qp_bind_hndl.qkey = OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY; 105219820Sjeff 106219820Sjeff vapi_ret = osmt_mtl_init_opened_hca(&p_qp_ctx->qp_bind_hndl); 107219820Sjeff if (vapi_ret != VAPI_OK) { 108219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0114: " 109219820Sjeff "Error initializing QP.\n"); 110219820Sjeff status = IB_ERROR; 111219820Sjeff goto Exit; 112219820Sjeff } 113219820Sjeff 114219820Sjeff /* we use the pre-allocated buffers for send and receive : 115219820Sjeff send from buf[0] 116219820Sjeff receive from buf[2] 117219820Sjeff */ 118219820Sjeff p_qp_ctx->p_send_buf = 119219820Sjeff (uint8_t *) p_qp_ctx->qp_bind_hndl.buf_ptr + GRH_LEN; 120219820Sjeff p_qp_ctx->p_recv_buf = 121219820Sjeff (uint8_t *) p_qp_ctx->qp_bind_hndl.buf_ptr + 2 * (GRH_LEN + 122219820Sjeff MAD_BLOCK_SIZE); 123219820Sjeff 124219820Sjeff /* Need to clear assigned memory of p_send_buf - before using it to send any data */ 125219820Sjeff memset(p_qp_ctx->p_send_buf, 0, MAD_BLOCK_SIZE); 126219820Sjeff 127219820Sjeff status = IB_SUCCESS; 128219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Initialized QP:0x%X in VAPI Mode\n", 129219820Sjeff p_qp_ctx->qp_bind_hndl.qp_id); 130219820Sjeff 131219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Binding to IB_MGT SMI\n"); 132219820Sjeff 133219820Sjeff /* we also need a QP0 handle for sending packets */ 134219820Sjeff mgt_ret = IB_MGT_get_handle(hca_id, port_num, IB_MGT_SMI, 135219820Sjeff &(p_qp_ctx->ib_mgt_qp0_handle)); 136219820Sjeff if (IB_MGT_OK != mgt_ret) { 137219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0115: " 138219820Sjeff "Error obtaining IB_MGT handle to SMI\n"); 139219820Sjeff status = IB_ERROR; 140219820Sjeff goto Exit; 141219820Sjeff } 142219820Sjeff 143219820SjeffExit: 144219820Sjeff OSM_LOG_EXIT(p_log); 145219820Sjeff return status; 146219820Sjeff} 147219820Sjeff 148219820Sjeff/* 149219820Sjeff * Close the QP 150219820Sjeff */ 151219820Sjeffvoid 152219820Sjeffosmt_unbind_inform_qp(IN osmtest_t * const p_osmt, IN osmt_qp_ctx_t * p_qp_ctx) 153219820Sjeff{ 154219820Sjeff osm_log_t *p_log = &p_osmt->log; 155219820Sjeff 156219820Sjeff OSM_LOG_ENTER(p_log); 157219820Sjeff 158219820Sjeff osmt_mtl_mad_cleanup(&p_qp_ctx->qp_bind_hndl); 159219820Sjeff 160219820Sjeff IB_MGT_release_handle(p_qp_ctx->ib_mgt_qp0_handle); 161219820Sjeff 162219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Unbind QP handles\n"); 163219820Sjeff OSM_LOG_EXIT(&p_osmt->log); 164219820Sjeff} 165219820Sjeff 166219820Sjeff/* 167219820Sjeff * Register/Unregister to receive the given InformInfo 168219820Sjeff * 169219820Sjeff * Uses the qp context to send the inform info mad. 170219820Sjeff * Wait for GetResp(InformInfoResp) 171219820Sjeff * 172219820Sjeff */ 173219820Sjeffib_api_status_t 174219820Sjeffosmt_reg_unreg_inform_info(IN osmtest_t * p_osmt, 175219820Sjeff IN osmt_qp_ctx_t * p_qp_ctx, 176219820Sjeff IN ib_inform_info_t * p_inform_info, 177219820Sjeff IN uint8_t reg_flag) 178219820Sjeff{ 179219820Sjeff ib_sa_mad_t *p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_send_buf); 180219820Sjeff ib_inform_info_t *p_ii = ib_sa_mad_get_payload_ptr(p_sa_mad); /* SA Payload */ 181219820Sjeff VAPI_ret_t vapi_ret; 182219820Sjeff VAPI_wc_desc_t wc_desc; 183219820Sjeff VAPI_ud_av_hndl_t avh; 184219820Sjeff static VAPI_wr_id_t wrid = 16198; 185219820Sjeff osm_log_t *p_log = &p_osmt->log; 186219820Sjeff ib_api_status_t status = IB_SUCCESS; 187219820Sjeff 188219820Sjeff OSM_LOG_ENTER(&p_osmt->log); 189219820Sjeff 190219820Sjeff /* init the MAD */ 191219820Sjeff ib_mad_init_new((ib_mad_t *) p_sa_mad, 192219820Sjeff IB_MCLASS_SUBN_ADM, 193219820Sjeff (uint8_t) 2, 194219820Sjeff IB_MAD_METHOD_SET, cl_hton64(wrid), (ib_net16_t) 0, 0); 195219820Sjeff wrid++; 196219820Sjeff p_sa_mad->attr_id = IB_MAD_ATTR_INFORM_INFO; 197219820Sjeff 198219820Sjeff /* copy the reference inform info */ 199219820Sjeff memcpy(p_ii, p_inform_info, sizeof(ib_inform_info_t)); 200219820Sjeff 201219820Sjeff if (reg_flag) { 202219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 203219820Sjeff "Subscribing InformInfo: Traps from lid:0x%X to 0x%X, trap num :0x%X\n", 204219820Sjeff p_ii->lid_range_begin, p_ii->lid_range_end, 205219820Sjeff p_ii->g_or_v.generic.trap_num); 206219820Sjeff } else { 207219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 208219820Sjeff "UnSubscribing InformInfo: Traps from lid:0x%X to 0x%X\n", 209219820Sjeff p_ii->lid_range_begin, p_ii->lid_range_end); 210219820Sjeff } 211219820Sjeff 212219820Sjeff /* set the subscribe bit */ 213219820Sjeff if (reg_flag) { 214219820Sjeff p_ii->subscribe = 1; 215219820Sjeff } else { 216219820Sjeff p_ii->subscribe = 0; 217219820Sjeff /* 218219820Sjeff * we need to set the QPN on the mad if we unsubscribe: 219219820Sjeff * o13-2.1.1 - QPN Field need to be set when unsubscribing. 220219820Sjeff */ 221219820Sjeff ib_inform_info_set_qpn(p_ii, 222219820Sjeff cl_hton32(p_qp_ctx->qp_bind_hndl.qp_id. 223219820Sjeff qp_num)); 224219820Sjeff } 225219820Sjeff 226219820Sjeff osm_dump_inform_info(&p_osmt->log, p_ii, OSM_LOG_DEBUG); 227219820Sjeff 228219820Sjeff /* --------------------- PREP ------------------------- */ 229219820Sjeff 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 */ 230219820Sjeff GRH_LEN + MAD_BLOCK_SIZE, wrid) != 1) { 231219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0120: " 232219820Sjeff "Error posting recv bufs\n"); 233219820Sjeff status = IB_ERROR; 234219820Sjeff goto Exit; 235219820Sjeff } 236219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Posted recv bufs\n"); 237219820Sjeff 238219820Sjeff vapi_ret = 239219820Sjeff osmt_mtl_create_av(&p_qp_ctx->qp_bind_hndl, 240219820Sjeff p_osmt->local_port.sm_lid, &avh); 241219820Sjeff if (vapi_ret != VAPI_OK) { 242219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0121: " 243219820Sjeff "Error Preparing AVH (%s)\n", 244219820Sjeff VAPI_strerror_sym(vapi_ret)); 245219820Sjeff status = IB_ERROR; 246219820Sjeff goto Exit; 247219820Sjeff } 248219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Prepared AVH\n"); 249219820Sjeff 250219820Sjeff if (osm_log_is_active(p_log, OSM_LOG_DEBUG)) { 251219820Sjeff osm_dump_sa_mad(p_log, (ib_sa_mad_t *) (p_qp_ctx->p_send_buf), 252219820Sjeff OSM_LOG_DEBUG); 253219820Sjeff#if 0 254219820Sjeff for (i = 56; i < 253; i++) { 255219820Sjeff if (i % 8 == 0) { 256219820Sjeff printf("\n %d : ", i); 257219820Sjeff } 258219820Sjeff printf("0x%02X ", p_qp_ctx->p_send_buf[i]); 259219820Sjeff } 260219820Sjeff#endif 261219820Sjeff printf("\n"); 262219820Sjeff } 263219820Sjeff 264219820Sjeff /* --------------------- SEND ------------------------- */ 265219820Sjeff vapi_ret = osmt_mtl_mad_send(&p_qp_ctx->qp_bind_hndl, wrid, p_qp_ctx->p_send_buf, 1, /* SA is QP1 */ 266219820Sjeff 0, /* SL is 0 */ 267219820Sjeff OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY, 268219820Sjeff avh); 269219820Sjeff if (vapi_ret != VAPI_OK) { 270219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0122: " 271219820Sjeff "Error sending mad (%s)\n", 272219820Sjeff VAPI_strerror_sym(vapi_ret)); 273219820Sjeff status = IB_ERROR; 274219820Sjeff goto Exit; 275219820Sjeff } 276219820Sjeff 277219820Sjeff vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl, 278219820Sjeff p_qp_ctx->qp_bind_hndl.sq_cq_hndl, 279219820Sjeff &wc_desc, 20, 10000, NULL); 280219820Sjeff if (vapi_ret != VAPI_OK) { 281219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0123: " 282219820Sjeff "Error getting send completion (%s)\n", 283219820Sjeff VAPI_strerror_sym(vapi_ret)); 284219820Sjeff status = IB_ERROR; 285219820Sjeff goto Exit; 286219820Sjeff } 287219820Sjeff 288219820Sjeff if (wc_desc.status != VAPI_SUCCESS) { 289219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0124: " 290219820Sjeff "Error on send completion (%s) (%d)\n", 291219820Sjeff VAPI_strerror_sym(wc_desc.status), wc_desc.status); 292219820Sjeff status = IB_ERROR; 293219820Sjeff goto Exit; 294219820Sjeff } 295219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Sent MAD\n"); 296219820Sjeff 297219820Sjeff /* --------------------- RECV ------------------------- */ 298219820Sjeff vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl, 299219820Sjeff p_qp_ctx->qp_bind_hndl.rq_cq_hndl, 300219820Sjeff &wc_desc, 20, 10000, &avh); 301219820Sjeff if (vapi_ret != VAPI_SUCCESS) { 302219820Sjeff if (vapi_ret == VAPI_CQ_EMPTY) { 303219820Sjeff status = IB_TIMEOUT; 304219820Sjeff } else { 305219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0125: " 306219820Sjeff "Error receiving mad (%s)\n", 307219820Sjeff VAPI_strerror_sym(vapi_ret)); 308219820Sjeff status = IB_ERROR; 309219820Sjeff } 310219820Sjeff goto Exit; 311219820Sjeff } 312219820Sjeff 313219820Sjeff /* check to see if successful - by examination of the subscribe bit */ 314219820Sjeff p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_recv_buf + GRH_LEN); 315219820Sjeff 316219820Sjeff if (p_sa_mad->status != IB_SUCCESS) { 317219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "Remote error = %s\n", 318219820Sjeff ib_get_mad_status_str((ib_mad_t *) p_sa_mad)); 319219820Sjeff status = IB_REMOTE_ERROR; 320219820Sjeff goto Exit; 321219820Sjeff } 322219820Sjeff 323219820Sjeff if (p_sa_mad->method != IB_MAD_METHOD_GET_RESP) { 324219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, 325219820Sjeff "Expected IB_MAD_METHOD_GET_RESP but got:(%X)\n", 326219820Sjeff p_sa_mad->method); 327219820Sjeff status = IB_REMOTE_ERROR; 328219820Sjeff goto Exit; 329219820Sjeff } 330219820Sjeff 331219820Sjeff if (p_sa_mad->attr_id != IB_MAD_ATTR_INFORM_INFO) { 332219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, 333219820Sjeff "Expected IB_MAD_ATTR_INFORM_INFO but got:(%X)\n", 334219820Sjeff cl_ntoh16(p_sa_mad->attr_id)); 335219820Sjeff status = IB_REMOTE_ERROR; 336219820Sjeff goto Exit; 337219820Sjeff } 338219820Sjeff 339219820Sjeff p_ii = ib_sa_mad_get_payload_ptr(p_sa_mad); 340219820Sjeff if (!p_ii->subscribe) { 341219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0126: " 342219820Sjeff "Subscribe/Unsubscribe Failed\n"); 343219820Sjeff status = IB_REMOTE_ERROR; 344219820Sjeff } 345219820Sjeff 346219820SjeffExit: 347219820Sjeff OSM_LOG_EXIT(&p_osmt->log); 348219820Sjeff return status; 349219820Sjeff} 350219820Sjeff 351219820Sjeff/* 352219820Sjeff * Send a trap (Subn LID Route) Trap(Notice) through the regular 353219820Sjeff * connection QP connection (targeted at QP0) 354219820Sjeff * 355219820Sjeff * Wait for the trap repress 356219820Sjeff */ 357219820Sjeffib_api_status_t 358219820Sjeffosmt_send_trap_wait_for_forward(IN osmtest_t * const p_osmt, 359219820Sjeff IN osmt_qp_ctx_t * p_qp_ctx) 360219820Sjeff{ 361219820Sjeff ib_smp_t *p_smp = (ib_smp_t *) (p_qp_ctx->p_send_buf); 362219820Sjeff ib_mad_notice_attr_t *p_ntc = ib_smp_get_payload_ptr(p_smp); 363219820Sjeff ib_sa_mad_t *p_sa_mad; 364219820Sjeff IB_MGT_ret_t mgt_res; 365219820Sjeff VAPI_ret_t vapi_ret; 366219820Sjeff VAPI_wc_desc_t wc_desc; 367219820Sjeff VAPI_ud_av_hndl_t avh; 368219820Sjeff IB_ud_av_t av; 369219820Sjeff static VAPI_wr_id_t wrid = 2222; 370219820Sjeff osm_log_t *p_log = &p_osmt->log; 371219820Sjeff ib_api_status_t status = IB_SUCCESS; 372219820Sjeff 373219820Sjeff OSM_LOG_ENTER(p_log); 374219820Sjeff 375219820Sjeff OSM_LOG(p_log, OSM_LOG_INFO, 376219820Sjeff "Sending Traps to QP0 of SA LID:0x%X\n", 377219820Sjeff p_osmt->local_port.sm_lid); 378219820Sjeff 379219820Sjeff /* init the MAD */ 380219820Sjeff memset(p_smp, 0, sizeof(ib_smp_t)); 381219820Sjeff ib_mad_init_new((ib_mad_t *) p_smp, 382219820Sjeff IB_MCLASS_SUBN_LID, 383219820Sjeff (uint8_t) 2, 384219820Sjeff IB_MAD_METHOD_TRAP, cl_hton64(wrid), (ib_net16_t) 0, 0); 385219820Sjeff 386219820Sjeff wrid++; 387219820Sjeff p_smp->attr_id = IB_MAD_ATTR_NOTICE; 388219820Sjeff 389219820Sjeff /* prepare the notice */ 390219820Sjeff p_ntc->generic_type = 0x82; /* generic, type = 2 */ 391219820Sjeff ib_notice_set_prod_type_ho(p_ntc, 1); 392219820Sjeff p_ntc->g_or_v.generic.trap_num = cl_hton16(0x26); 393219820Sjeff p_ntc->issuer_lid = cl_hton16(2); 394219820Sjeff 395219820Sjeff /* --------------------- PREP ------------------------- */ 396219820Sjeff 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 */ 397219820Sjeff GRH_LEN + MAD_BLOCK_SIZE, wrid) != 1) { 398219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0127: " 399219820Sjeff "Error posting recv bufs\n"); 400219820Sjeff status = IB_ERROR; 401219820Sjeff goto Exit; 402219820Sjeff } 403219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Posted recv bufs\n"); 404219820Sjeff 405219820Sjeff av.dlid = p_osmt->local_port.sm_lid; 406219820Sjeff av.grh_flag = FALSE; 407219820Sjeff 408219820Sjeff /* EZ: returned in HACK: use constants */ 409219820Sjeff av.static_rate = 0; /* p_mad_addr->static_rate; */ 410219820Sjeff av.src_path_bits = 1; /* p_mad_addr->path_bits; */ 411219820Sjeff av.sl = 0; /* p_mad_addr->addr_type.gsi.service_level; */ 412219820Sjeff 413219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, 414219820Sjeff "av.dlid 0x%X, av.static_rate %d, av.path_bits %d\n", 415219820Sjeff cl_ntoh16(av.dlid), av.static_rate, av.src_path_bits); 416219820Sjeff 417219820Sjeff /* send it */ 418219820Sjeff mgt_res = IB_MGT_send_mad(p_qp_ctx->ib_mgt_qp0_handle, p_smp, /* actual payload */ 419219820Sjeff &av, /* address vector */ 420219820Sjeff wrid, /* casting the mad wrapper pointer for err cb */ 421219820Sjeff p_osmt->opt.transaction_timeout); 422219820Sjeff if (mgt_res != IB_MGT_OK) { 423219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0128: " 424219820Sjeff "Error sending mad (%d)\n", mgt_res); 425219820Sjeff status = IB_ERROR; 426219820Sjeff goto Exit; 427219820Sjeff } 428219820Sjeff 429219820Sjeff vapi_ret = 430219820Sjeff osmt_mtl_create_av(&p_qp_ctx->qp_bind_hndl, 431219820Sjeff p_osmt->local_port.sm_lid, &avh); 432219820Sjeff if (vapi_ret != VAPI_OK) { 433219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0129: " 434219820Sjeff "Error Preparing AVH (%s)\n", 435219820Sjeff VAPI_strerror_sym(vapi_ret)); 436219820Sjeff status = IB_ERROR; 437219820Sjeff goto Exit; 438219820Sjeff } 439219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Prepared AVH\n"); 440219820Sjeff 441219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, "Trap MAD Sent\n"); 442219820Sjeff 443219820Sjeff /* --------------------- RECV ------------------------- */ 444219820Sjeff vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl, 445219820Sjeff p_qp_ctx->qp_bind_hndl.rq_cq_hndl, 446219820Sjeff &wc_desc, 200, 10000, &avh); 447219820Sjeff if (vapi_ret != VAPI_SUCCESS) { 448219820Sjeff if (vapi_ret == VAPI_CQ_EMPTY) { 449219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0130: " 450219820Sjeff "Timeout receiving mad (%s)\n", 451219820Sjeff VAPI_strerror_sym(vapi_ret)); 452219820Sjeff status = IB_TIMEOUT; 453219820Sjeff } else { 454219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0131: " 455219820Sjeff "Error receiving mad (%s)\n", 456219820Sjeff VAPI_strerror_sym(vapi_ret)); 457219820Sjeff status = IB_ERROR; 458219820Sjeff } 459219820Sjeff goto Exit; 460219820Sjeff } 461219820Sjeff 462219820Sjeff /* check to see if successful - by examination of the subscribe bit */ 463219820Sjeff p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_recv_buf + GRH_LEN); 464219820Sjeff 465219820Sjeff if (p_sa_mad->method == IB_MAD_METHOD_REPORT) { 466219820Sjeff if (p_sa_mad->attr_id == IB_MAD_ATTR_NOTICE) { 467219820Sjeff OSM_LOG(p_log, OSM_LOG_INFO, "Received the Report!\n"); 468219820Sjeff status = IB_SUCCESS; 469219820Sjeff } else { 470219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1020" 471219820Sjeff "Did not receive a Report(Notice) but attr:%d\n", 472219820Sjeff cl_ntoh16(p_sa_mad->attr_id)); 473219820Sjeff status = IB_ERROR; 474219820Sjeff } 475219820Sjeff } else { 476219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1020" 477219820Sjeff "Received an Unexpected Method:%d\n", p_smp->method); 478219820Sjeff status = IB_ERROR; 479219820Sjeff } 480219820Sjeff 481219820SjeffExit: 482219820Sjeff OSM_LOG_EXIT(p_log); 483219820Sjeff return status; 484219820Sjeff} 485219820Sjeff 486219820Sjeff/* 487219820Sjeff * Wait for a trap on QPn 488219820Sjeff * 489219820Sjeff */ 490219820Sjeffib_api_status_t 491219820Sjeffosmt_trap_wait(IN osmtest_t * const p_osmt, IN osmt_qp_ctx_t * p_qp_ctx) 492219820Sjeff{ 493219820Sjeff ib_smp_t *p_smp = (ib_smp_t *) (p_qp_ctx->p_send_buf); 494219820Sjeff ib_sa_mad_t *p_sa_mad; 495219820Sjeff VAPI_ret_t vapi_ret; 496219820Sjeff VAPI_wc_desc_t wc_desc; 497219820Sjeff osm_log_t *p_log = &p_osmt->log; 498219820Sjeff ib_api_status_t status = IB_SUCCESS; 499219820Sjeff 500219820Sjeff OSM_LOG_ENTER(p_log); 501219820Sjeff 502219820Sjeff OSM_LOG(p_log, OSM_LOG_INFO, 503219820Sjeff "Waiting for Traps under QP:0x%X of SA LID:0x%X\n", 504219820Sjeff cl_ntoh16(p_osmt->local_port.sm_lid)); 505219820Sjeff 506219820Sjeff /* --------------------- RECV ------------------------- */ 507219820Sjeff vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl, 508219820Sjeff p_qp_ctx->qp_bind_hndl.rq_cq_hndl, 509219820Sjeff &wc_desc, 510219820Sjeff // 200, 511219820Sjeff p_osmt->opt.wait_time * 100, 512219820Sjeff 10000, NULL); 513219820Sjeff if (vapi_ret != VAPI_SUCCESS) { 514219820Sjeff if (vapi_ret == VAPI_CQ_EMPTY) { 515219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0130: " 516219820Sjeff "Timeout receiving mad (%s)\n", 517219820Sjeff VAPI_strerror_sym(vapi_ret)); 518219820Sjeff status = IB_TIMEOUT; 519219820Sjeff } else { 520219820Sjeff OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0131: " 521219820Sjeff "Error receiving mad (%s)\n", 522219820Sjeff VAPI_strerror_sym(vapi_ret)); 523219820Sjeff status = IB_ERROR; 524219820Sjeff } 525219820Sjeff goto Exit; 526219820Sjeff } 527219820Sjeff 528219820Sjeff /* check to see if successful - by examination of the subscribe bit */ 529219820Sjeff p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_recv_buf + GRH_LEN); 530219820Sjeff 531219820Sjeff if (p_sa_mad->method == IB_MAD_METHOD_REPORT) { 532219820Sjeff if (p_sa_mad->attr_id == IB_MAD_ATTR_NOTICE) { 533219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 534219820Sjeff "Received the Report!\n"); 535219820Sjeff status = IB_SUCCESS; 536219820Sjeff } else { 537219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 1020" 538219820Sjeff "Did not receive a Report(Notice) but attr:%d\n", 539219820Sjeff cl_ntoh16(p_sa_mad->attr_id)); 540219820Sjeff status = IB_ERROR; 541219820Sjeff } 542219820Sjeff } else { 543219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 1020" 544219820Sjeff "Received an Unexpected Method:%d\n", p_smp->method); 545219820Sjeff status = IB_ERROR; 546219820Sjeff } 547219820Sjeff 548219820SjeffExit: 549219820Sjeff OSM_LOG_EXIT(p_log); 550219820Sjeff return status; 551219820Sjeff} 552219820Sjeff 553219820Sjeff/* 554219820Sjeff * Initialize an inform info attribute: 555219820Sjeff * Catch all traps in the lid range of the p_osmt 556219820Sjeff * 557219820Sjeff */ 558219820Sjeffib_api_status_t 559219820Sjeffosmt_init_inform_info(IN osmtest_t * const p_osmt, OUT ib_inform_info_t * p_ii) 560219820Sjeff{ 561219820Sjeff 562219820Sjeff memset(p_ii, 0, sizeof(ib_inform_info_t)); 563219820Sjeff /* p_ii->lid_range_begin = cl_hton16(1); */ 564219820Sjeff p_ii->lid_range_begin = 0xFFFF; 565219820Sjeff p_ii->lid_range_end = cl_hton16(p_osmt->max_lid); 566219820Sjeff p_ii->is_generic = 1; /* have to choose */ 567219820Sjeff p_ii->trap_type = 0xFFFF; /* ALL */ 568219820Sjeff p_ii->g_or_v.generic.trap_num = 0xFFFF; /* ALL */ 569219820Sjeff p_ii->g_or_v.generic.node_type_lsb = 0xFFFF; /* ALL */ 570219820Sjeff p_ii->g_or_v.generic.node_type_msb = 0xFF; /* ALL */ 571219820Sjeff return IB_SUCCESS; 572219820Sjeff} 573219820Sjeff 574219820Sjeffib_api_status_t 575219820Sjeffosmt_init_inform_info_by_trap(IN osmtest_t * const p_osmt, 576219820Sjeff IN ib_net16_t trap_num, 577219820Sjeff OUT ib_inform_info_t * p_ii) 578219820Sjeff{ 579219820Sjeff 580219820Sjeff memset(p_ii, 0, sizeof(ib_inform_info_t)); 581219820Sjeff /* p_ii->lid_range_begin = cl_hton16(1); */ 582219820Sjeff p_ii->lid_range_begin = 0xFFFF; 583219820Sjeff p_ii->lid_range_end = cl_hton16(p_osmt->max_lid); 584219820Sjeff p_ii->is_generic = 1; /* have to choose */ 585219820Sjeff p_ii->trap_type = 0xFFFF; /* ALL */ 586219820Sjeff p_ii->g_or_v.generic.trap_num = trap_num; /* ALL */ 587219820Sjeff p_ii->g_or_v.generic.node_type_lsb = 0xFFFF; /* ALL */ 588219820Sjeff p_ii->g_or_v.generic.node_type_msb = 0xFF; /* ALL */ 589219820Sjeff return IB_SUCCESS; 590219820Sjeff} 591219820Sjeff 592219820Sjeff/* 593219820Sjeff * Run a complete inform info test flow: 594219820Sjeff * - try to unregister inform info (should fail) 595219820Sjeff * - register an inform info 596219820Sjeff * - try to unregister inform info (should succeed) 597219820Sjeff * - register an inform info 598219820Sjeff * - send a trap - sleep 599219820Sjeff * - check that a Report(Notice) arrived that match the sent one 600219820Sjeff * 601219820Sjeff */ 602219820Sjeffib_api_status_t osmt_run_inform_info_flow(IN osmtest_t * const p_osmt) 603219820Sjeff{ 604219820Sjeff ib_inform_info_t inform_info; 605219820Sjeff ib_api_status_t status; 606219820Sjeff osmt_qp_ctx_t qp_ctx; 607219820Sjeff 608219820Sjeff OSM_LOG_ENTER(&p_osmt->log); 609219820Sjeff 610219820Sjeff /* bind the QP */ 611219820Sjeff status = osmt_bind_inform_qp(p_osmt, &qp_ctx); 612219820Sjeff if (status != IB_SUCCESS) { 613219820Sjeff goto Exit; 614219820Sjeff } 615219820Sjeff 616219820Sjeff /* init the inform info */ 617219820Sjeff osmt_init_inform_info(p_osmt, &inform_info); 618219820Sjeff 619219820Sjeff /* first try to unsubscribe */ 620219820Sjeff status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 0); 621219820Sjeff /* WAS IB_REMOTE_ERROR */ 622219820Sjeff if (status != IB_REMOTE_ERROR) { 623219820Sjeff if (status != IB_SUCCESS) { 624219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 625219820Sjeff "Error during UnSubscribe: (%s)\n", 626219820Sjeff ib_get_err_str(status)); 627219820Sjeff goto Exit; 628219820Sjeff } else { 629219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 630219820Sjeff "Expected Failure to UnSubscribe non existing InformInfo\n"); 631219820Sjeff status = IB_ERROR; 632219820Sjeff goto Exit; 633219820Sjeff } 634219820Sjeff } 635219820Sjeff 636219820Sjeff /* send the inform info registration */ 637219820Sjeff status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 1); 638219820Sjeff if (status != IB_SUCCESS) { 639219820Sjeff goto Exit; 640219820Sjeff } 641219820Sjeff 642219820Sjeff /* send a trap through QP0 and wait on QPN */ 643219820Sjeff status = osmt_send_trap_wait_for_forward(p_osmt, &qp_ctx); 644219820Sjeff if (status != IB_SUCCESS) { 645219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 646219820Sjeff "Error during Send Trap and Wait For Report: (%s)\n", 647219820Sjeff ib_get_err_str(status)); 648219820Sjeff goto Exit; 649219820Sjeff } 650219820Sjeff 651219820Sjeff /* try to unsubscribe for cleanup */ 652219820Sjeff status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 0); 653219820Sjeff 654219820Sjeff if (status != IB_SUCCESS) { 655219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 656219820Sjeff "Error during UnSubscribe: (%s)\n", 657219820Sjeff ib_get_err_str(status)); 658219820Sjeff goto Exit; 659219820Sjeff } else { 660219820Sjeff if (status == IB_REMOTE_ERROR) { 661219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 662219820Sjeff "Remote Error during UnSubscribe\n"); 663219820Sjeff status = IB_ERROR; 664219820Sjeff goto Exit; 665219820Sjeff } 666219820Sjeff } 667219820Sjeff 668219820SjeffExit: 669219820Sjeff osmt_unbind_inform_qp(p_osmt, &qp_ctx); 670219820Sjeff OSM_LOG_EXIT(&p_osmt->log); 671219820Sjeff return status; 672219820Sjeff} 673219820Sjeff 674219820Sjeff/* 675219820Sjeff * Run a complete inform info test flow: 676219820Sjeff * - try to unregister inform info (should fail) 677219820Sjeff * - register an inform info 678219820Sjeff * - try to unregister inform info (should succeed) 679219820Sjeff * - register an inform info 680219820Sjeff * - send a trap - sleep 681219820Sjeff * - check that a Report(Notice) arrived that match the sent one 682219820Sjeff * 683219820Sjeff */ 684219820Sjeffib_api_status_t osmt_run_trap64_65_flow(IN osmtest_t * const p_osmt) 685219820Sjeff{ 686219820Sjeff ib_inform_info_t inform_info; 687219820Sjeff ib_api_status_t status; 688219820Sjeff osmt_qp_ctx_t qp_ctx; 689219820Sjeff 690219820Sjeff OSM_LOG_ENTER(&p_osmt->log); 691219820Sjeff 692219820Sjeff /* bind the QP */ 693219820Sjeff status = osmt_bind_inform_qp(p_osmt, &qp_ctx); 694219820Sjeff if (status != IB_SUCCESS) { 695219820Sjeff goto Exit; 696219820Sjeff } 697219820Sjeff 698219820Sjeff /* init the inform info */ 699219820Sjeff osmt_init_inform_info_by_trap(p_osmt, cl_hton16(64), &inform_info); 700219820Sjeff 701219820Sjeff /* send the inform info registration */ 702219820Sjeff status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 1); 703219820Sjeff if (status != IB_SUCCESS) { 704219820Sjeff goto Exit; 705219820Sjeff } 706219820Sjeff 707219820Sjeff /*--------------------- PREP -------------------------*/ 708219820Sjeff if (osmt_mtl_mad_post_recv_bufs(&qp_ctx.qp_bind_hndl, qp_ctx.p_recv_buf, 1, /* we need to receive the report */ 709219820Sjeff GRH_LEN + MAD_BLOCK_SIZE, 1) != 1) { 710219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0127: " 711219820Sjeff "Error posting recv bufs for trap 64\n"); 712219820Sjeff status = IB_ERROR; 713219820Sjeff goto Exit; 714219820Sjeff } 715219820Sjeff 716219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "Posted recv bufs for trap 64\n"); 717219820Sjeff 718219820Sjeff /* init the inform info */ 719219820Sjeff osmt_init_inform_info_by_trap(p_osmt, cl_hton16(65), &inform_info); 720219820Sjeff 721219820Sjeff /* send the inform info registration */ 722219820Sjeff status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 1); 723219820Sjeff if (status != IB_SUCCESS) { 724219820Sjeff goto Exit; 725219820Sjeff } 726219820Sjeff 727219820Sjeff /*--------------------- PREP -------------------------*/ 728219820Sjeff if (osmt_mtl_mad_post_recv_bufs(&qp_ctx.qp_bind_hndl, qp_ctx.p_recv_buf, 1, /* we need to reveive the report */ 729219820Sjeff GRH_LEN + MAD_BLOCK_SIZE, 1) != 1) { 730219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0127: " 731219820Sjeff "Error posting recv bufs for trap 65\n"); 732219820Sjeff status = IB_ERROR; 733219820Sjeff goto Exit; 734219820Sjeff } 735219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "Posted recv bufs for trap 65\n"); 736219820Sjeff 737219820Sjeff /* Sleep for x seconds in order to allow external script trap generation */ 738219820Sjeff#if 0 739219820Sjeff sleep(p_osmt->opt.wait_time); 740219820Sjeff#endif 741219820Sjeff 742219820Sjeff /* wait for a trap on QPN */ 743219820Sjeff status = osmt_trap_wait(p_osmt, &qp_ctx); 744219820Sjeff if (status != IB_SUCCESS) { 745219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 746219820Sjeff "Error during Send Trap and Wait For Report: (%s)\n", 747219820Sjeff ib_get_err_str(status)); 748219820Sjeff goto Exit; 749219820Sjeff } 750219820Sjeff 751219820Sjeff /* try to unsubscribe for cleanup */ 752219820Sjeff status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 0); 753219820Sjeff 754219820Sjeff if (status != IB_SUCCESS) { 755219820Sjeff OSM_LOG(&p_osmt->log, OSM_LOG_INFO, 756219820Sjeff "Error during UnSubscribe: (%s)\n", 757219820Sjeff ib_get_err_str(status)); 758219820Sjeff goto Exit; 759219820Sjeff } 760219820Sjeff 761219820SjeffExit: 762219820Sjeff osmt_unbind_inform_qp(p_osmt, &qp_ctx); 763219820Sjeff OSM_LOG_EXIT(&p_osmt->log); 764219820Sjeff return status; 765219820Sjeff} 766219820Sjeff 767219820Sjeff#endif /* OSM_VENDOR_INTF_MTL */ 768