osm_vendor_mlx_ts.c revision 296373
1167514Skmacy/* 2167514Skmacy * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. 3167514Skmacy * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4167514Skmacy * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5167514Skmacy * 6167514Skmacy * This software is available to you under a choice of one of two 7167514Skmacy * licenses. You may choose to be licensed under the terms of the GNU 8167514Skmacy * General Public License (GPL) Version 2, available from the file 9167514Skmacy * COPYING in the main directory of this source tree, or the 10167514Skmacy * OpenIB.org BSD license below: 11167514Skmacy * 12169978Skmacy * Redistribution and use in source and binary forms, with or 13167514Skmacy * without modification, are permitted provided that the following 14167514Skmacy * conditions are met: 15167514Skmacy * 16167514Skmacy * - Redistributions of source code must retain the above 17167514Skmacy * copyright notice, this list of conditions and the following 18167514Skmacy * disclaimer. 19167514Skmacy * 20167514Skmacy * - Redistributions in binary form must reproduce the above 21167514Skmacy * copyright notice, this list of conditions and the following 22167514Skmacy * disclaimer in the documentation and/or other materials 23167514Skmacy * provided with the distribution. 24167514Skmacy * 25167514Skmacy * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26167514Skmacy * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27167514Skmacy * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28167514Skmacy * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29167514Skmacy * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30167514Skmacy * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31167514Skmacy * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32167514Skmacy * SOFTWARE. 33167514Skmacy * 34167514Skmacy */ 35167514Skmacy 36167514Skmacy/* AUTHOR Edward Bortnikov 37167514Skmacy * 38167514Skmacy * DESCRIPTION 39167514Skmacy * The lower-level MAD transport interface implementation 40167514Skmacy * that allows sending a single MAD/receiving a callback 41167514Skmacy * when a single MAD is received. 42167514Skmacy */ 43167514Skmacy 44167514Skmacy#if HAVE_CONFIG_H 45167514Skmacy# include <config.h> 46167514Skmacy#endif /* HAVE_CONFIG_H */ 47167514Skmacy 48167514Skmacy#include <sys/types.h> 49167514Skmacy#include <sys/stat.h> 50167514Skmacy#include <sys/ioctl.h> 51167514Skmacy#include <fcntl.h> 52167514Skmacy#include <errno.h> 53167514Skmacy#include <stdlib.h> 54167514Skmacy#include <string.h> 55167514Skmacy 56167514Skmacy#include <vendor/osm_vendor_api.h> 57167514Skmacy#include <vendor/osm_vendor_mlx_transport.h> 58167514Skmacy#include <vendor/osm_vendor_mlx_dispatcher.h> 59167514Skmacy#include <vendor/osm_vendor_mlx_svc.h> 60167514Skmacy#include <vendor/osm_ts_useraccess.h> 61167514Skmacy 62167514Skmacytypedef struct _osmv_TOPSPIN_transport_mgr_ { 63167514Skmacy int device_fd; 64167514Skmacy osm_ts_user_mad_filter filter; 65167514Skmacy cl_thread_t receiver; 66167514Skmacy} osmv_TOPSPIN_transport_mgr_t; 67167514Skmacy 68167514Skmacystatic void 69167514Skmacy__osmv_TOPSPIN_mad_addr_to_osm_addr(IN osm_vendor_t const *p_vend, 70167514Skmacy IN struct ib_mad *p_mad, 71167514Skmacy IN uint8_t is_smi, 72167514Skmacy OUT osm_mad_addr_t * p_mad_addr); 73167514Skmacy 74167514Skmacystatic void 75170076Skmacy__osmv_TOPSPIN_osm_addr_to_mad_addr(IN const osm_mad_addr_t * p_mad_addr, 76170076Skmacy IN uint8_t is_smi, 77170076Skmacy OUT struct ib_mad *p_mad); 78170076Skmacy 79170076Skmacyvoid __osmv_TOPSPIN_receiver_thr(void *p_ctx) 80167514Skmacy{ 81167514Skmacy int ts_ret_code; 82167514Skmacy struct ib_mad mad; 83167514Skmacy osm_mad_addr_t mad_addr; 84167514Skmacy osmv_bind_obj_t *const p_bo = (osmv_bind_obj_t *) p_ctx; 85167514Skmacy ib_api_status_t status = IB_SUCCESS; 86170654Skmacy 87167514Skmacy OSM_LOG_ENTER(p_bo->p_vendor->p_log); 88167514Skmacy 89167734Skmacy /* Make sure the p_bo object is still relevant */ 90167514Skmacy if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing) 91167514Skmacy return; 92167514Skmacy 93167514Skmacy /* we set the type of cancelation for this thread */ 94167514Skmacy /* pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); */ 95167514Skmacy 96167514Skmacy while (1) { 97167514Skmacy /* Make sure the p_bo object is still relevant */ 98167514Skmacy if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing) 99170869Skmacy return; 100170869Skmacy 101167514Skmacy /* we read one mad at a time and pass it to the read callback function */ 102167514Skmacy ts_ret_code = 103167514Skmacy read(((osmv_TOPSPIN_transport_mgr_t *) (p_bo-> 104167514Skmacy p_transp_mgr))-> 105167514Skmacy device_fd, &mad, sizeof(mad)); 106167514Skmacy /* Make sure the p_bo object is still relevant */ 107167514Skmacy if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing) 108167514Skmacy return; 109167514Skmacy 110167514Skmacy if (ts_ret_code != sizeof(mad)) { 111167514Skmacy osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR, 112167514Skmacy "__osmv_TOPSPIN_receiver_thr: ERR 6803: " 113167514Skmacy "error with read, bytes = %d, errno = %d\n", 114167514Skmacy ts_ret_code, errno); 115169978Skmacy break; 116170789Skmacy } else { 117169978Skmacy osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG, 118170789Skmacy "__osmv_TOPSPIN_receiver_thr: " 119167514Skmacy "MAD QPN:%d SLID:0x%04x class:0x%02x " 120169978Skmacy "method:0x%02x attr:0x%04x status:0x%04x " 121167514Skmacy "tid:0x%016" PRIx64 "\n", 122167514Skmacy mad.dqpn, 123167514Skmacy cl_ntoh16(mad.slid), 124167514Skmacy mad.mgmt_class, 125167514Skmacy mad.r_method, 126167514Skmacy cl_ntoh16(mad.attribute_id), 127167514Skmacy cl_ntoh16(mad.status), 128167514Skmacy cl_ntoh64(mad.transaction_id)); 129167514Skmacy 130167514Skmacy /* first arrange an address */ 131167514Skmacy __osmv_TOPSPIN_mad_addr_to_osm_addr(p_bo->p_vendor, 132167514Skmacy &mad, 133167514Skmacy (((ib_mad_t *) & 134167514Skmacy mad)-> 135167514Skmacy mgmt_class == 136167514Skmacy IB_MCLASS_SUBN_LID) 137167514Skmacy || 138167514Skmacy (((ib_mad_t *) & 139167514Skmacy mad)-> 140167514Skmacy mgmt_class == 141167514Skmacy IB_MCLASS_SUBN_DIR), 142167514Skmacy &mad_addr); 143167514Skmacy 144167514Skmacy /* call the receiver callback */ 145167514Skmacy 146167514Skmacy status = 147167514Skmacy osmv_dispatch_mad((osm_bind_handle_t) p_bo, 148167514Skmacy (void *)&mad, &mad_addr); 149167514Skmacy 150167514Skmacy /* Make sure the p_bo object is still relevant */ 151167514Skmacy if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing) 152167514Skmacy return; 153167514Skmacy 154167514Skmacy if (IB_INTERRUPTED == status) { 155167514Skmacy 156167514Skmacy osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG, 157167514Skmacy "__osmv_TOPSPIN_receiver_thr: " 158167514Skmacy "The bind handle %p is being closed. " 159167514Skmacy "Breaking the loop.\n", p_bo); 160167514Skmacy break; 161167514Skmacy } 162167514Skmacy } 163167514Skmacy } 164170654Skmacy 165170654Skmacy OSM_LOG_EXIT(p_bo->p_vendor->p_log); 166167514Skmacy} 167170654Skmacy 168170654Skmacy/* 169170654Skmacy * NAME 170170654Skmacy * osmv_transport_init 171170654Skmacy * 172170654Skmacy * DESCRIPTION 173170654Skmacy * Setup the MAD transport infrastructure (filters, callbacks etc). 174170654Skmacy */ 175170654Skmacy 176167514Skmacyib_api_status_t 177167514Skmacyosmv_transport_init(IN osm_bind_info_t * p_info, 178167514Skmacy IN char hca_id[VENDOR_HCA_MAXNAMES], 179167514Skmacy IN uint8_t hca_idx, IN osmv_bind_obj_t * p_bo) 180167514Skmacy{ 181168749Skmacy cl_status_t cl_st; 182167514Skmacy char device_file[16]; 183167514Skmacy int device_fd; 184167514Skmacy int ts_ioctl_ret; 185167514Skmacy osmv_TOPSPIN_transport_mgr_t *p_mgr = 186167514Skmacy malloc(sizeof(osmv_TOPSPIN_transport_mgr_t)); 187167514Skmacy int qpn; 188167514Skmacy 189167514Skmacy if (!p_mgr) { 190167514Skmacy return IB_INSUFFICIENT_MEMORY; 191167760Skmacy } 192170083Skmacy 193167514Skmacy memset(p_mgr, 0, sizeof(osmv_TOPSPIN_transport_mgr_t)); 194167514Skmacy 195167514Skmacy /* open TopSpin file device */ 196167514Skmacy /* HACK: assume last char in hostid is the HCA index */ 197169978Skmacy sprintf(device_file, "/dev/ts_ua%u", hca_idx); 198169053Skmacy device_fd = open(device_file, O_RDWR); 199169978Skmacy if (device_fd < 0) { 200169978Skmacy fprintf(stderr, "Fatal: Fail to open the file:%s err:%d\n", 201169053Skmacy device_file, errno); 202169978Skmacy return IB_ERROR; 203169978Skmacy } 204169978Skmacy 205169978Skmacy /* 206169978Skmacy * Create the MAD filter on this file handle. 207169978Skmacy */ 208169978Skmacy 209169978Skmacy p_mgr->filter.port = p_bo->port_num; 210169978Skmacy p_mgr->filter.direction = TS_IB_MAD_DIRECTION_IN; 211169053Skmacy p_mgr->filter.mask = 212169978Skmacy TS_IB_MAD_FILTER_DIRECTION | 213169978Skmacy TS_IB_MAD_FILTER_PORT | 214169978Skmacy TS_IB_MAD_FILTER_QPN | TS_IB_MAD_FILTER_MGMT_CLASS; 215167514Skmacy 216167514Skmacy switch (p_info->mad_class) { 217167514Skmacy case IB_MCLASS_SUBN_LID: 218167514Skmacy case IB_MCLASS_SUBN_DIR: 219167514Skmacy qpn = 0; 220167514Skmacy p_mgr->filter.qpn = qpn; 221167514Skmacy p_mgr->filter.mgmt_class = IB_MCLASS_SUBN_LID; 222167514Skmacy ts_ioctl_ret = 223167514Skmacy ioctl(device_fd, TS_IB_IOCSMADFILTADD, &p_mgr->filter); 224167514Skmacy if (ts_ioctl_ret < 0) { 225167514Skmacy return IB_ERROR; 226167514Skmacy } 227167514Skmacy 228171471Skmacy p_mgr->filter.mgmt_class = IB_MCLASS_SUBN_DIR; 229171471Skmacy ts_ioctl_ret = 230171471Skmacy ioctl(device_fd, TS_IB_IOCSMADFILTADD, &p_mgr->filter); 231171471Skmacy if (ts_ioctl_ret < 0) { 232171471Skmacy return IB_ERROR; 233171471Skmacy } 234171471Skmacy 235171471Skmacy break; 236171471Skmacy 237171471Skmacy case IB_MCLASS_SUBN_ADM: 238171471Skmacy default: 239171471Skmacy qpn = 1; 240171471Skmacy p_mgr->filter.qpn = qpn; 241171471Skmacy p_mgr->filter.mgmt_class = p_info->mad_class; 242171471Skmacy ts_ioctl_ret = 243171471Skmacy ioctl(device_fd, TS_IB_IOCSMADFILTADD, &p_mgr->filter); 244171471Skmacy if (ts_ioctl_ret < 0) { 245171471Skmacy return IB_ERROR; 246171471Skmacy } 247171471Skmacy break; 248171471Skmacy } 249171471Skmacy 250167514Skmacy p_mgr->device_fd = device_fd; 251167514Skmacy 252167514Skmacy p_bo->p_transp_mgr = p_mgr; 253167514Skmacy 254167514Skmacy /* Initialize the magic_ptr to the pointer of the p_bo info. 255167514Skmacy This will be used to signal when the object is being destroyed, so no 256167514Skmacy real action will be done then. */ 257167514Skmacy p_bo->magic_ptr = p_bo; 258167514Skmacy 259167514Skmacy /* init receiver thread */ 260167514Skmacy cl_st = 261167514Skmacy cl_thread_init(&p_mgr->receiver, __osmv_TOPSPIN_receiver_thr, 262167514Skmacy (void *)p_bo, "osmv TOPSPIN rcv thr"); 263167514Skmacy 264167514Skmacy return (ib_api_status_t) cl_st; 265167514Skmacy} 266167514Skmacy 267167514Skmacy/* 268167514Skmacy * NAME 269170654Skmacy * osmv_transport_send_mad 270167514Skmacy * 271167514Skmacy * DESCRIPTION 272167514Skmacy * Send a single MAD (256 byte) 273171471Skmacy */ 274171471Skmacy 275171471Skmacyib_api_status_t 276171471Skmacyosmv_transport_mad_send(IN const osm_bind_handle_t h_bind, 277171471Skmacy IN void *p_mad, IN const osm_mad_addr_t * p_mad_addr) 278171471Skmacy{ 279171471Skmacy 280171471Skmacy osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind; 281171471Skmacy osm_vendor_t const *p_vend = p_bo->p_vendor; 282171471Skmacy struct ib_mad ts_mad; 283171471Skmacy int ret; 284171471Skmacy ib_api_status_t status; 285171471Skmacy 286171471Skmacy const ib_mad_t *p_mad_hdr = p_mad; 287171471Skmacy 288171471Skmacy OSM_LOG_ENTER(p_vend->p_log); 289171471Skmacy 290171471Skmacy memset(&ts_mad, 0, sizeof(ts_mad)); 291171471Skmacy 292171471Skmacy /* Make sure the p_bo object is still relevant */ 293171471Skmacy if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing) 294171471Skmacy return IB_INVALID_CALLBACK; 295171471Skmacy 296167514Skmacy /* 297167514Skmacy * Copy the MAD over to the sent mad 298167514Skmacy */ 299167514Skmacy memcpy(&ts_mad, p_mad_hdr, MAD_BLOCK_SIZE); 300167514Skmacy 301167514Skmacy /* 302167514Skmacy * For all sends other than directed route SM MADs, 303167514Skmacy * acquire an address vector for the destination. 304167514Skmacy */ 305167514Skmacy if (p_mad_hdr->mgmt_class != IB_MCLASS_SUBN_DIR) { 306167514Skmacy 307167514Skmacy __osmv_TOPSPIN_osm_addr_to_mad_addr(p_mad_addr, 308167514Skmacy p_mad_hdr->mgmt_class == 309167514Skmacy IB_MCLASS_SUBN_LID, 310167514Skmacy &ts_mad); 311167514Skmacy } else { 312167514Skmacy /* is a directed route - we need to construct a permissive address */ 313167514Skmacy /* we do not need port number since it is part of the mad_hndl */ 314167514Skmacy ts_mad.dlid = IB_LID_PERMISSIVE; 315167514Skmacy ts_mad.slid = IB_LID_PERMISSIVE; 316167514Skmacy ts_mad.sqpn = 0; 317167514Skmacy ts_mad.dqpn = 0; 318167514Skmacy } 319167514Skmacy 320167514Skmacy ts_mad.port = p_bo->port_num; 321167514Skmacy 322167514Skmacy osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG, 323167514Skmacy "osmv_transport_mad_send: " 324167514Skmacy "Sending QPN:%d DLID:0x%04x class:0x%02x " 325167514Skmacy "method:0x%02x attr:0x%04x status:0x%04x " 326167514Skmacy "tid:0x%016" PRIx64 "\n", 327167514Skmacy ts_mad.dqpn, 328167514Skmacy cl_ntoh16(ts_mad.dlid), 329167514Skmacy ts_mad.mgmt_class, 330170654Skmacy ts_mad.r_method, 331170654Skmacy cl_ntoh16(ts_mad.attribute_id), 332167514Skmacy cl_ntoh16(ts_mad.status), cl_ntoh64(ts_mad.transaction_id) 333167514Skmacy ); 334167514Skmacy 335167514Skmacy /* send it */ 336170654Skmacy ret = 337170654Skmacy write(((osmv_TOPSPIN_transport_mgr_t *) (p_bo->p_transp_mgr))-> 338167514Skmacy device_fd, &ts_mad, sizeof(ts_mad)); 339167514Skmacy 340167514Skmacy if (ret != sizeof(ts_mad)) { 341167514Skmacy osm_log(p_vend->p_log, OSM_LOG_ERROR, 342170654Skmacy "osmv_transport_mad_send: ERR 6804: " 343167514Skmacy "Error sending mad (%d).\n", ret); 344167514Skmacy status = IB_ERROR; 345167514Skmacy goto Exit; 346167514Skmacy } 347171471Skmacy 348171471Skmacy status = IB_SUCCESS; 349171471Skmacy 350171471SkmacyExit: 351167514Skmacy OSM_LOG_EXIT(p_vend->p_log); 352169978Skmacy return (status); 353167514Skmacy} 354167514Skmacy 355167514Skmacy/* 356167514Skmacy register a new mad type to the opened device file 357167514Skmacy and send a mad through - the main idea is to make 358167514Skmacy the filter catch it such that the read unblocks 359167514Skmacy*/ 360167514Skmacyvoid __osm_transport_gen_dummy_mad(osmv_bind_obj_t * p_bo) 361167514Skmacy{ 362171471Skmacy struct ib_mad ts_mad; 363169978Skmacy osmv_TOPSPIN_transport_mgr_t *p_mgr = 364167514Skmacy (osmv_TOPSPIN_transport_mgr_t *) (p_bo->p_transp_mgr); 365167514Skmacy struct ib_get_port_info_ioctl port_data; 366167514Skmacy int ts_ioctl_ret; 367167514Skmacy 368169978Skmacy /* prepare the mad fields following the stored filter on the bind */ 369169978Skmacy memset(&ts_mad, 0, sizeof(ts_mad)); 370171471Skmacy ts_mad.format_version = 1; 371171471Skmacy ts_mad.mgmt_class = p_mgr->filter.mgmt_class; 372167514Skmacy ts_mad.attribute_id = 0x2; 373167514Skmacy ts_mad.class_version = 1; 374171471Skmacy ts_mad.r_method = cl_ntoh16(0x2); 375171471Skmacy ts_mad.port = p_bo->port_num; 376167514Skmacy ts_mad.sqpn = p_mgr->filter.qpn; 377167514Skmacy ts_mad.dqpn = p_mgr->filter.qpn; 378167514Skmacy ts_mad.slid = 0xffff; 379167514Skmacy /* we must send to our local lid ... */ 380167514Skmacy port_data.port = p_bo->port_num; 381167514Skmacy ts_ioctl_ret = ioctl(p_mgr->device_fd, TS_IB_IOCGPORTINFO, &port_data); 382167514Skmacy ts_mad.dlid = port_data.port_info.lid; 383167514Skmacy ts_mad.transaction_id = 0x9999; 384167514Skmacy write(p_mgr->device_fd, &ts_mad, sizeof(ts_mad)); 385167514Skmacy} 386167514Skmacy 387169978Skmacyvoid osmv_transport_done(IN const osm_bind_handle_t h_bind) 388167514Skmacy{ 389167760Skmacy osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind; 390170869Skmacy osmv_TOPSPIN_transport_mgr_t *p_tpot_mgr = 391167514Skmacy (osmv_TOPSPIN_transport_mgr_t *) (p_bo->p_transp_mgr); 392167514Skmacy 393169978Skmacy CL_ASSERT(p_bo); 394169978Skmacy 395167840Skmacy /* First of all - zero out the magic_ptr, so if a callback is called - 396167840Skmacy it'll know that we are currently closing down, and will not handle the 397167840Skmacy mad. */ 398167840Skmacy p_bo->magic_ptr = 0; 399167840Skmacy /* usleep(3000000); */ 400167840Skmacy 401167840Skmacy /* seems the only way to abort a blocking read is to make it read something */ 402167840Skmacy __osm_transport_gen_dummy_mad(p_bo); 403167840Skmacy cl_thread_destroy(&(p_tpot_mgr->receiver)); 404167840Skmacy free(p_tpot_mgr); 405171471Skmacy} 406171471Skmacy 407171471Skmacystatic void 408171471Skmacy__osmv_TOPSPIN_osm_addr_to_mad_addr(IN const osm_mad_addr_t * p_mad_addr, 409167840Skmacy IN uint8_t is_smi, OUT struct ib_mad *p_mad) 410167862Skmacy{ 411167840Skmacy 412167840Skmacy /* For global destination or Multicast address: */ 413167840Skmacy p_mad->dlid = cl_ntoh16(p_mad_addr->dest_lid); 414167514Skmacy p_mad->sl = p_mad_addr->addr_type.gsi.service_level; 415167514Skmacy if (is_smi) { 416167514Skmacy p_mad->sqpn = 0; 417167514Skmacy p_mad->dqpn = 0; 418167514Skmacy } else { 419167514Skmacy p_mad->sqpn = 1; 420167514Skmacy p_mad->dqpn = cl_ntoh32(p_mad_addr->addr_type.gsi.remote_qp); 421167514Skmacy } 422167514Skmacy /* 423167514Skmacy HACK we limit to the first PKey Index assuming it will 424167514Skmacy always be the default PKey 425167514Skmacy */ 426170869Skmacy p_mad->pkey_index = 0; 427170869Skmacy} 428170869Skmacy 429170869Skmacystatic void 430170869Skmacy__osmv_TOPSPIN_mad_addr_to_osm_addr(IN osm_vendor_t const *p_vend, 431170869Skmacy IN struct ib_mad *p_mad, 432170869Skmacy IN uint8_t is_smi, 433170869Skmacy OUT osm_mad_addr_t * p_mad_addr) 434170869Skmacy{ 435170869Skmacy p_mad_addr->dest_lid = cl_hton16(p_mad->slid); 436167514Skmacy p_mad_addr->static_rate = 0; 437170869Skmacy p_mad_addr->path_bits = 0; 438170869Skmacy if (is_smi) { 439170869Skmacy /* SMI */ 440170869Skmacy p_mad_addr->addr_type.smi.source_lid = cl_hton16(p_mad->slid); 441167514Skmacy p_mad_addr->addr_type.smi.port_num = p_mad->port; 442167514Skmacy } else { 443167514Skmacy /* GSI */ 444167769Skmacy p_mad_addr->addr_type.gsi.remote_qp = cl_ntoh32(p_mad->sqpn); 445167769Skmacy p_mad_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY; 446170654Skmacy /* There is a TAVOR limitation that only one P_KEY is supported per */ 447167769Skmacy /* QP - so QP1 must use IB_DEFAULT_PKEY */ 448167769Skmacy p_mad_addr->addr_type.gsi.pkey_ix = p_mad->pkey_index; 449167769Skmacy p_mad_addr->addr_type.gsi.service_level = p_mad->sl; 450167514Skmacy 451167514Skmacy p_mad_addr->addr_type.gsi.global_route = FALSE; 452167514Skmacy /* copy the GRH data if relevant - TopSpin imp doesnt relate to GRH!!! */ 453167514Skmacy /* 454167514Skmacy if (p_mad_addr->addr_type.gsi.global_route) 455167514Skmacy { 456167760Skmacy p_mad_addr->addr_type.gsi.grh_info.ver_class_flow = 457167514Skmacy ib_grh_set_ver_class_flow(p_rcv_desc->grh.IP_version, 458167514Skmacy p_rcv_desc->grh.traffic_class, 459167514Skmacy p_rcv_desc->grh.flow_label); 460167514Skmacy p_mad_addr->addr_type.gsi.grh_info.hop_limit = p_rcv_desc->grh.hop_limit; 461167514Skmacy memcpy(&p_mad_addr->addr_type.gsi.grh_info.src_gid.raw, 462169978Skmacy &p_rcv_desc->grh.sgid, sizeof(ib_net64_t)); 463167760Skmacy memcpy(&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw, 464169978Skmacy p_rcv_desc->grh.dgid, sizeof(ib_net64_t)); 465169978Skmacy } 466169978Skmacy */ 467169978Skmacy } 468169978Skmacy} 469169978Skmacy 470167514Skmacy/* 471167514Skmacy * NAME osm_vendor_set_sm 472167514Skmacy * 473167514Skmacy * DESCRIPTION Modifies the port info for the bound port to set the "IS_SM" bit 474167514Skmacy * according to the value given (TRUE or FALSE). 475167514Skmacy */ 476170081Skmacy#if (defined(OSM_VENDOR_INTF_TS_NO_VAPI) || defined(OSM_VENDOR_INTF_TS)) 477167514Skmacy 478167514Skmacyvoid osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val) 479167514Skmacy{ 480169978Skmacy osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind; 481169978Skmacy osm_vendor_t const *p_vend = p_bo->p_vendor; 482169978Skmacy int ts_ioctl_ret; 483167760Skmacy int device_fd = 484169978Skmacy ((osmv_TOPSPIN_transport_mgr_t *) (p_bo->p_transp_mgr))->device_fd; 485167514Skmacy struct ib_set_port_info_ioctl set_port_data; 486167514Skmacy 487167514Skmacy OSM_LOG_ENTER(p_vend->p_log); 488167514Skmacy 489170081Skmacy memset(&set_port_data, 0, sizeof(set_port_data)); 490167514Skmacy 491167514Skmacy set_port_data.port = p_bo->port_num; 492167514Skmacy set_port_data.port_info.valid_fields = IB_PORT_IS_SM; 493169978Skmacy set_port_data.port_info.is_sm = is_sm_val; 494167760Skmacy ts_ioctl_ret = ioctl(device_fd, TS_IB_IOCSPORTINFO, &set_port_data); 495167514Skmacy if (ts_ioctl_ret < 0) { 496170081Skmacy osm_log(p_vend->p_log, OSM_LOG_ERROR, 497167514Skmacy "osm_vendor_set_sm: ERR 6805: " 498167514Skmacy "Unable set 'IS_SM' bit to:%u in port attributes (%d).\n", 499167514Skmacy is_sm_val, ts_ioctl_ret); 500167514Skmacy } 501167514Skmacy 502167514Skmacy OSM_LOG_EXIT(p_vend->p_log); 503167514Skmacy} 504167514Skmacy 505167514Skmacy#endif 506167514Skmacy