|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* AUTHOR Edward Bortnikov
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* The lower-level MAD transport interface implementation
|
|
Packit |
13e616 |
* that allows sending a single MAD/receiving a callback
|
|
Packit |
13e616 |
* when a single MAD is received.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <string.h>
|
|
Packit |
13e616 |
#include <ib_mgt.h>
|
|
Packit |
13e616 |
#include <complib/cl_event.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_transport.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_dispatcher.h>
|
|
Packit |
13e616 |
#include <opensm/osm_log.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
typedef struct _osmv_IBMGT_transport_mgr_ {
|
|
Packit |
13e616 |
IB_MGT_mad_type_t mad_type;
|
|
Packit |
13e616 |
uint8_t mgmt_class; /* for gsi */
|
|
Packit |
13e616 |
/* for communication between send call back and send mad */
|
|
Packit |
13e616 |
boolean_t is_send_ok;
|
|
Packit |
13e616 |
cl_event_t send_done;
|
|
Packit |
13e616 |
} osmv_IBMGT_transport_mgr_t;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
typedef struct _osmv_IBMGT_transport_info_ {
|
|
Packit |
13e616 |
IB_MGT_mad_hndl_t smi_h;
|
|
Packit |
13e616 |
cl_qlist_t *p_smi_list;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
IB_MGT_mad_hndl_t gsi_h;
|
|
Packit |
13e616 |
/* holds bind object list for every binded mgmt class */
|
|
Packit |
13e616 |
cl_qlist_t *gsi_mgmt_lists[15];
|
|
Packit |
13e616 |
} osmv_IBMGT_transport_info_t;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void
|
|
Packit |
13e616 |
__osmv_IBMGT_rcv_desc_to_osm_addr(IN IB_MGT_mad_rcv_desc_t * p_rcv_desc,
|
|
Packit |
13e616 |
IN uint8_t is_smi,
|
|
Packit |
13e616 |
OUT osm_mad_addr_t * p_mad_addr);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void
|
|
Packit |
13e616 |
__osmv_IBMGT_osm_addr_to_ibmgt_addr(IN const osm_mad_addr_t * p_mad_addr,
|
|
Packit |
13e616 |
IN uint8_t is_smi, OUT IB_ud_av_t * p_av);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void
|
|
Packit |
13e616 |
__osmv_IBMGT_send_cb(IN IB_MGT_mad_hndl_t mad_hndl,
|
|
Packit |
13e616 |
IN u_int64_t wrid,
|
|
Packit |
13e616 |
IN IB_comp_status_t status, IN void *private_ctx_p);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void
|
|
Packit |
13e616 |
__osmv_IBMGT_rcv_cb(IN IB_MGT_mad_hndl_t mad_hndl,
|
|
Packit |
13e616 |
IN void *private_ctx_p,
|
|
Packit |
13e616 |
IN void *payload_p,
|
|
Packit |
13e616 |
IN IB_MGT_mad_rcv_desc_t * rcv_remote_info_p);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* osmv_transport_init
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* Setup the MAD transport infrastructure (filters, callbacks etc).
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_transport_init(IN osm_bind_info_t * p_info,
|
|
Packit |
13e616 |
IN char hca_id[VENDOR_HCA_MAXNAMES],
|
|
Packit |
13e616 |
IN uint8_t hca_idx, IN osmv_bind_obj_t * p_bo)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t st = IB_SUCCESS;
|
|
Packit |
13e616 |
IB_MGT_ret_t ret;
|
|
Packit |
13e616 |
IB_MGT_mad_type_t mad_type;
|
|
Packit |
13e616 |
osmv_IBMGT_transport_mgr_t *p_mgr;
|
|
Packit |
13e616 |
osmv_IBMGT_transport_info_t *p_tpot_info;
|
|
Packit |
13e616 |
cl_list_obj_t *p_obj = NULL;
|
|
Packit |
13e616 |
osm_log_t *p_log = p_bo->p_vendor->p_log;
|
|
Packit |
13e616 |
int i;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
UNUSED_PARAM(hca_idx);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* if first bind, allocate tranport_info at vendor */
|
|
Packit |
13e616 |
if (NULL == p_bo->p_vendor->p_transport_info) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osmv_transport_init: first bind() for the vendor\n");
|
|
Packit |
13e616 |
p_bo->p_vendor->p_transport_info
|
|
Packit |
13e616 |
= (osmv_IBMGT_transport_info_t *)
|
|
Packit |
13e616 |
malloc(sizeof(osmv_IBMGT_transport_info_t));
|
|
Packit |
13e616 |
if (NULL == p_bo->p_vendor->p_transport_info) {
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
memset(p_bo->p_vendor->p_transport_info, 0,
|
|
Packit |
13e616 |
sizeof(osmv_IBMGT_transport_info_t));
|
|
Packit |
13e616 |
p_tpot_info =
|
|
Packit |
13e616 |
(osmv_IBMGT_transport_info_t *) (p_bo->p_vendor->
|
|
Packit |
13e616 |
p_transport_info);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tpot_info->smi_h = 0xffffffff;
|
|
Packit |
13e616 |
p_tpot_info->p_smi_list = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tpot_info->gsi_h = 0xffffffff;
|
|
Packit |
13e616 |
for (i = 0; i < 15; i++) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tpot_info->gsi_mgmt_lists[i] = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tpot_info =
|
|
Packit |
13e616 |
(osmv_IBMGT_transport_info_t *) (p_bo->p_vendor->
|
|
Packit |
13e616 |
p_transport_info);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Initialize the magic_ptr to the pointer of the p_bo info.
|
|
Packit |
13e616 |
This will be used to signal when the object is being destroyed, so no
|
|
Packit |
13e616 |
real action will be done then. */
|
|
Packit |
13e616 |
p_bo->magic_ptr = p_bo;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* allocate transport mgr */
|
|
Packit |
13e616 |
p_mgr = malloc(sizeof(osmv_IBMGT_transport_mgr_t));
|
|
Packit |
13e616 |
if (NULL == p_mgr) {
|
|
Packit |
13e616 |
free(p_tpot_info);
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7201: " "alloc failed \n");
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_mgr, 0, sizeof(osmv_IBMGT_transport_mgr_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_bo->p_transp_mgr = p_mgr;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
switch (p_info->mad_class) {
|
|
Packit |
13e616 |
case IB_MCLASS_SUBN_LID:
|
|
Packit |
13e616 |
case IB_MCLASS_SUBN_DIR:
|
|
Packit |
13e616 |
mad_type = IB_MGT_SMI;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MCLASS_SUBN_ADM:
|
|
Packit |
13e616 |
default:
|
|
Packit |
13e616 |
mad_type = IB_MGT_GSI;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* we only support one class registration per SMI/GSI !!! */
|
|
Packit |
13e616 |
switch (mad_type) {
|
|
Packit |
13e616 |
case IB_MGT_SMI:
|
|
Packit |
13e616 |
/* we do not need to bind the handle if already available */
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osmv_transport_init: SMI bind\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_tpot_info->smi_h == 0xffffffff) {
|
|
Packit |
13e616 |
ret = IB_MGT_get_handle(hca_id,
|
|
Packit |
13e616 |
p_bo->port_num,
|
|
Packit |
13e616 |
IB_MGT_SMI,
|
|
Packit |
13e616 |
&(p_tpot_info->smi_h));
|
|
Packit |
13e616 |
if (IB_MGT_OK != ret) {
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7202: "
|
|
Packit |
13e616 |
"IB_MGT_get_handle for smi failed \n");
|
|
Packit |
13e616 |
st = IB_ERROR;
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osmv_transport_init: got smi handle:%d \n",
|
|
Packit |
13e616 |
p_tpot_info->smi_h);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = IB_MGT_bind_sm(p_tpot_info->smi_h);
|
|
Packit |
13e616 |
if (IB_MGT_OK != ret) {
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7203: "
|
|
Packit |
13e616 |
"IB_MGT_bind_sm failed \n");
|
|
Packit |
13e616 |
st = IB_ERROR;
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* init smi list */
|
|
Packit |
13e616 |
p_tpot_info->p_smi_list = malloc(sizeof(cl_qlist_t));
|
|
Packit |
13e616 |
if (NULL == p_tpot_info->p_smi_list) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7204: "
|
|
Packit |
13e616 |
"alloc failed \n");
|
|
Packit |
13e616 |
IB_MGT_unbind_sm(p_tpot_info->smi_h);
|
|
Packit |
13e616 |
IB_MGT_release_handle(p_tpot_info->smi_h);
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
memset(p_tpot_info->p_smi_list, 0, sizeof(cl_qlist_t));
|
|
Packit |
13e616 |
cl_qlist_init(p_tpot_info->p_smi_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osmv_transport_init: before reg_cb\n");
|
|
Packit |
13e616 |
ret = IB_MGT_reg_cb(p_tpot_info->smi_h,
|
|
Packit |
13e616 |
&__osmv_IBMGT_rcv_cb,
|
|
Packit |
13e616 |
p_bo,
|
|
Packit |
13e616 |
&__osmv_IBMGT_send_cb,
|
|
Packit |
13e616 |
p_tpot_info->p_smi_list,
|
|
Packit |
13e616 |
IB_MGT_RCV_CB_MASK |
|
|
Packit |
13e616 |
IB_MGT_SEND_CB_MASK);
|
|
Packit |
13e616 |
if (ret != IB_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7205: "
|
|
Packit |
13e616 |
"reg_cb failed with return code:%x \n",
|
|
Packit |
13e616 |
ret);
|
|
Packit |
13e616 |
IB_MGT_unbind_sm(p_tpot_info->smi_h);
|
|
Packit |
13e616 |
IB_MGT_release_handle(p_tpot_info->smi_h);
|
|
Packit |
13e616 |
free(p_tpot_info->p_smi_list);
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
st = IB_ERROR;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* insert to list of smi's - for raising callbacks later on */
|
|
Packit |
13e616 |
p_obj = malloc(sizeof(cl_list_obj_t));
|
|
Packit |
13e616 |
if (p_obj)
|
|
Packit |
13e616 |
memset(p_obj, 0, sizeof(cl_list_obj_t));
|
|
Packit |
13e616 |
cl_qlist_set_obj(p_obj, p_bo);
|
|
Packit |
13e616 |
cl_qlist_insert_tail(p_tpot_info->p_smi_list,
|
|
Packit |
13e616 |
&p_obj->list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MGT_GSI:
|
|
Packit |
13e616 |
/* we do not need to bind the handle if already available */
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7206: GSI bind\n");
|
|
Packit |
13e616 |
if (p_tpot_info->gsi_h == 0xffffffff) {
|
|
Packit |
13e616 |
ret = IB_MGT_get_handle(hca_id,
|
|
Packit |
13e616 |
p_bo->port_num,
|
|
Packit |
13e616 |
IB_MGT_GSI,
|
|
Packit |
13e616 |
&(p_tpot_info->gsi_h));
|
|
Packit |
13e616 |
if (IB_MGT_OK != ret) {
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7207: "
|
|
Packit |
13e616 |
"IB_MGT_get_handle for gsi failed \n");
|
|
Packit |
13e616 |
st = IB_ERROR;
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* this mgmt class was not binded yet */
|
|
Packit |
13e616 |
if (p_tpot_info->gsi_mgmt_lists[p_info->mad_class] == NULL) {
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
IB_MGT_bind_gsi_class(p_tpot_info->gsi_h,
|
|
Packit |
13e616 |
p_info->mad_class);
|
|
Packit |
13e616 |
if (IB_MGT_OK != ret) {
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7208: "
|
|
Packit |
13e616 |
"IB_MGT_bind_gsi_class failed \n");
|
|
Packit |
13e616 |
st = IB_ERROR;
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tpot_info->gsi_mgmt_lists[p_info->mad_class] =
|
|
Packit |
13e616 |
malloc(sizeof(cl_qlist_t));
|
|
Packit |
13e616 |
if (NULL ==
|
|
Packit |
13e616 |
p_tpot_info->gsi_mgmt_lists[p_info->mad_class]) {
|
|
Packit |
13e616 |
IB_MGT_unbind_gsi_class(p_tpot_info->gsi_h,
|
|
Packit |
13e616 |
p_info->mad_class);
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
memset(p_tpot_info->gsi_mgmt_lists[p_info->mad_class],
|
|
Packit |
13e616 |
0, sizeof(cl_qlist_t));
|
|
Packit |
13e616 |
cl_qlist_init(p_tpot_info->
|
|
Packit |
13e616 |
gsi_mgmt_lists[p_info->mad_class]);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* insert to list of smi's - for raising callbacks later on */
|
|
Packit |
13e616 |
p_obj = malloc(sizeof(cl_list_obj_t));
|
|
Packit |
13e616 |
if (p_obj)
|
|
Packit |
13e616 |
memset(p_obj, 0, sizeof(cl_list_obj_t));
|
|
Packit |
13e616 |
cl_qlist_set_obj(p_obj, p_bo);
|
|
Packit |
13e616 |
cl_qlist_insert_tail(p_tpot_info->
|
|
Packit |
13e616 |
gsi_mgmt_lists[p_info->mad_class],
|
|
Packit |
13e616 |
&p_obj->list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mgr->mgmt_class = p_info->mad_class;
|
|
Packit |
13e616 |
ret = IB_MGT_reg_cb(p_tpot_info->gsi_h,
|
|
Packit |
13e616 |
&__osmv_IBMGT_rcv_cb,
|
|
Packit |
13e616 |
p_bo,
|
|
Packit |
13e616 |
&__osmv_IBMGT_send_cb,
|
|
Packit |
13e616 |
p_bo,
|
|
Packit |
13e616 |
IB_MGT_RCV_CB_MASK | IB_MGT_SEND_CB_MASK);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (ret != IB_SUCCESS) {
|
|
Packit |
13e616 |
IB_MGT_unbind_gsi_class(p_tpot_info->gsi_h,
|
|
Packit |
13e616 |
p_mgr->mgmt_class);
|
|
Packit |
13e616 |
free(p_tpot_info->gsi_mgmt_lists[p_mgr->mgmt_class]);
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
st = IB_ERROR;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
default:
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_init: ERR 7209: unrecognized mgmt class \n");
|
|
Packit |
13e616 |
st = IB_ERROR;
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osmv_transport_init: GSI bind\n");
|
|
Packit |
13e616 |
cl_event_construct(&p_mgr->send_done);
|
|
Packit |
13e616 |
cl_event_init(&p_mgr->send_done, TRUE);
|
|
Packit |
13e616 |
p_mgr->is_send_ok = FALSE;
|
|
Packit |
13e616 |
p_mgr->mad_type = mad_type;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
/* OSM_LOG_EXIT(p_log ); */
|
|
Packit |
13e616 |
return (ib_api_status_t) st;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* osmv_transport_send_mad
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* Send a single MAD (256 byte)
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_transport_mad_send(IN const osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN void *p_ib_mad, IN const osm_mad_addr_t * p_mad_addr)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osmv_IBMGT_transport_info_t *p_tpot_info =
|
|
Packit |
13e616 |
(osmv_IBMGT_transport_info_t *) (p_bo->p_vendor->p_transport_info);
|
|
Packit |
13e616 |
osm_vendor_t const *p_vend = p_bo->p_vendor;
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
IB_ud_av_t av;
|
|
Packit |
13e616 |
IB_MGT_ret_t ret;
|
|
Packit |
13e616 |
ib_mad_t *p_mad = p_ib_mad;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_bo->p_vendor->p_transport_info);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* For all sends other than directed route SM MADs,
|
|
Packit |
13e616 |
* acquire an address vector for the destination.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) {
|
|
Packit |
13e616 |
__osmv_IBMGT_osm_addr_to_ibmgt_addr(p_mad_addr,
|
|
Packit |
13e616 |
p_mad->mgmt_class ==
|
|
Packit |
13e616 |
IB_MCLASS_SUBN_LID, &av;;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* is a directed route - we need to construct a permissive address */
|
|
Packit |
13e616 |
memset(&av, 0, sizeof(av));
|
|
Packit |
13e616 |
/* we do not need port number since it is part of the mad_hndl */
|
|
Packit |
13e616 |
av.dlid = IB_LID_PERMISSIVE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* send it */
|
|
Packit |
13e616 |
if ((p_mad->mgmt_class == IB_MCLASS_SUBN_DIR) ||
|
|
Packit |
13e616 |
(p_mad->mgmt_class == IB_MCLASS_SUBN_LID)) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* SMI CASE */
|
|
Packit |
13e616 |
if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osmv_transport_mad_send: "
|
|
Packit |
13e616 |
"av.dlid:0x%X, "
|
|
Packit |
13e616 |
"av.static_rate:%d, "
|
|
Packit |
13e616 |
"av.path_bits:%d.\n",
|
|
Packit |
13e616 |
cl_ntoh16(av.dlid), av.static_rate,
|
|
Packit |
13e616 |
av.src_path_bits);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = IB_MGT_send_mad(p_tpot_info->smi_h, p_mad, /* actual payload */
|
|
Packit |
13e616 |
&av, /* address vector */
|
|
Packit |
13e616 |
(u_int64_t) CAST_P2LONG(p_bo),
|
|
Packit |
13e616 |
IB_MGT_DEFAULT_SEND_TIME);
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* GSI CASE - Support Remote QP */
|
|
Packit |
13e616 |
if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osmv_transport_mad_send: "
|
|
Packit |
13e616 |
"av.dlid:0x%X, av.static_rate:%d, av.path_bits:%d, remote qp:%d \n",
|
|
Packit |
13e616 |
cl_ntoh16(av.dlid), av.static_rate,
|
|
Packit |
13e616 |
av.src_path_bits,
|
|
Packit |
13e616 |
cl_ntoh32(p_mad_addr->addr_type.gsi.remote_qp)
|
|
Packit |
13e616 |
);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = IB_MGT_send_mad_to_qp(p_tpot_info->gsi_h, p_mad, /* actual payload */
|
|
Packit |
13e616 |
&av, /* address vector */
|
|
Packit |
13e616 |
(u_int64_t) CAST_P2LONG(p_bo),
|
|
Packit |
13e616 |
IB_MGT_DEFAULT_SEND_TIME,
|
|
Packit |
13e616 |
cl_ntoh32(p_mad_addr->addr_type.gsi.
|
|
Packit |
13e616 |
remote_qp));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = IB_SUCCESS;
|
|
Packit |
13e616 |
if (ret != IB_MGT_OK) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_mad_send: ERR 7210: "
|
|
Packit |
13e616 |
"Error sending mad (%d).\n", ret);
|
|
Packit |
13e616 |
status = IB_ERROR;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
osmv_IBMGT_transport_mgr_t *p_mgr =
|
|
Packit |
13e616 |
(osmv_IBMGT_transport_mgr_t *) (p_bo->p_transp_mgr);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Let the others work when I am sleeping ... */
|
|
Packit |
13e616 |
osmv_txn_unlock(p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_event_wait_on(&(p_mgr->send_done), 0xffffffff, TRUE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Re-acquire the lock */
|
|
Packit |
13e616 |
osmv_txn_lock(p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == p_bo->is_closing) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_mad_send: ERR 7211: "
|
|
Packit |
13e616 |
"The handle %p is being unbound, cannot send.\n",
|
|
Packit |
13e616 |
h_bind);
|
|
Packit |
13e616 |
status = IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_mgr->is_send_ok == FALSE) {
|
|
Packit |
13e616 |
status = IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
return (status);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osmv_transport_done(IN const osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osm_log_t *p_log = p_bo->p_vendor->p_log;
|
|
Packit |
13e616 |
osmv_IBMGT_transport_mgr_t *p_mgr;
|
|
Packit |
13e616 |
osmv_IBMGT_transport_info_t *p_tpot_info;
|
|
Packit |
13e616 |
IB_MGT_ret_t ret;
|
|
Packit |
13e616 |
cl_list_obj_t *p_obj = NULL;
|
|
Packit |
13e616 |
cl_list_item_t *p_item, *p_item_tmp;
|
|
Packit |
13e616 |
int i;
|
|
Packit |
13e616 |
cl_qlist_t *p_list = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* First of all - zero out the magic_ptr, so if a callback is called -
|
|
Packit |
13e616 |
it'll know that we are currently closing down, and will not handle the
|
|
Packit |
13e616 |
mad. */
|
|
Packit |
13e616 |
p_bo->magic_ptr = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mgr = (osmv_IBMGT_transport_mgr_t *) (p_bo->p_transp_mgr);
|
|
Packit |
13e616 |
p_tpot_info =
|
|
Packit |
13e616 |
(osmv_IBMGT_transport_info_t *) (p_bo->p_vendor->p_transport_info);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
switch (p_mgr->mad_type) {
|
|
Packit |
13e616 |
case IB_MGT_SMI:
|
|
Packit |
13e616 |
p_list = p_tpot_info->p_smi_list;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* remove from the bindings list */
|
|
Packit |
13e616 |
p_item = cl_qlist_head(p_list);
|
|
Packit |
13e616 |
while (p_item != cl_qlist_end(p_list)) {
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item);
|
|
Packit |
13e616 |
if (cl_qlist_obj(p_obj) == h_bind) {
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_item_tmp = cl_qlist_next(p_item);
|
|
Packit |
13e616 |
p_item = p_item_tmp;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_item != cl_qlist_end(p_list));
|
|
Packit |
13e616 |
cl_qlist_remove_item(p_list, p_item);
|
|
Packit |
13e616 |
if (p_obj)
|
|
Packit |
13e616 |
free(p_obj);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* no one is binded to smi anymore - we can free the list, unbind & realease the hndl */
|
|
Packit |
13e616 |
if (cl_is_qlist_empty(p_list) == TRUE) {
|
|
Packit |
13e616 |
free(p_list);
|
|
Packit |
13e616 |
p_list = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = IB_MGT_unbind_sm(p_tpot_info->smi_h);
|
|
Packit |
13e616 |
if (ret != IB_MGT_OK) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_done: ERR 7212: "
|
|
Packit |
13e616 |
"Failed to unbind sm\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = IB_MGT_release_handle(p_tpot_info->smi_h);
|
|
Packit |
13e616 |
if (ret != IB_MGT_OK) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_done: ERR 7213: "
|
|
Packit |
13e616 |
"Failed to release smi handle\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_tpot_info->smi_h = 0xffffffff;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MGT_GSI:
|
|
Packit |
13e616 |
p_list = p_tpot_info->gsi_mgmt_lists[p_mgr->mgmt_class];
|
|
Packit |
13e616 |
/* remove from the bindings list */
|
|
Packit |
13e616 |
p_item = cl_qlist_head(p_list);
|
|
Packit |
13e616 |
while (p_item != cl_qlist_end(p_list)) {
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item);
|
|
Packit |
13e616 |
if (cl_qlist_obj(p_obj) == h_bind) {
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_item_tmp = cl_qlist_next(p_item);
|
|
Packit |
13e616 |
p_item = p_item_tmp;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_item != cl_qlist_end(p_list));
|
|
Packit |
13e616 |
cl_qlist_remove_item(p_list, p_item);
|
|
Packit |
13e616 |
if (p_obj)
|
|
Packit |
13e616 |
free(p_obj);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* no one is binded to this class anymore - we can free the list and unbind this class */
|
|
Packit |
13e616 |
if (cl_is_qlist_empty(p_list) == TRUE) {
|
|
Packit |
13e616 |
free(p_list);
|
|
Packit |
13e616 |
p_list = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
IB_MGT_unbind_gsi_class(p_tpot_info->gsi_h,
|
|
Packit |
13e616 |
p_mgr->mgmt_class);
|
|
Packit |
13e616 |
if (ret != IB_MGT_OK) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_done: ERR 7214: "
|
|
Packit |
13e616 |
"Failed to unbind gsi class\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* all the mgmt classes are unbinded - release gsi handle */
|
|
Packit |
13e616 |
for (i = 0; i < 15; i++) {
|
|
Packit |
13e616 |
if (p_tpot_info->gsi_mgmt_lists[i] != NULL) {
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (i == 15) {
|
|
Packit |
13e616 |
ret = IB_MGT_release_handle(p_tpot_info->gsi_h);
|
|
Packit |
13e616 |
if (ret != IB_MGT_OK) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_transport_done: ERR 7215: "
|
|
Packit |
13e616 |
"Failed to release gsi handle\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_tpot_info->gsi_h = 0xffffffff;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} /* end switch */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p_mgr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/**********************************************************************
|
|
Packit |
13e616 |
* IB_MGT Receive callback : invoked after each receive
|
|
Packit |
13e616 |
**********************************************************************/
|
|
Packit |
13e616 |
void
|
|
Packit |
13e616 |
__osmv_IBMGT_rcv_cb(IN IB_MGT_mad_hndl_t mad_hndl,
|
|
Packit |
13e616 |
IN void *private_ctx_p,
|
|
Packit |
13e616 |
IN void *payload_p,
|
|
Packit |
13e616 |
IN IB_MGT_mad_rcv_desc_t * rcv_remote_info_p)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo;
|
|
Packit |
13e616 |
osm_mad_addr_t mad_addr;
|
|
Packit |
13e616 |
cl_list_item_t *p_item;
|
|
Packit |
13e616 |
cl_list_obj_t *p_obj;
|
|
Packit |
13e616 |
cl_qlist_t *p_list;
|
|
Packit |
13e616 |
ib_mad_t *p_mad = (ib_mad_t *) payload_p;
|
|
Packit |
13e616 |
osm_vendor_t *p_vendor;
|
|
Packit |
13e616 |
osmv_IBMGT_transport_info_t *p_tinfo;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
__osmv_IBMGT_rcv_desc_to_osm_addr(rcv_remote_info_p,
|
|
Packit |
13e616 |
((p_mad->mgmt_class ==
|
|
Packit |
13e616 |
IB_MCLASS_SUBN_LID)
|
|
Packit |
13e616 |
|| (p_mad->mgmt_class ==
|
|
Packit |
13e616 |
IB_MCLASS_SUBN_DIR)), &mad_addr);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* different handling of SMI and GSI */
|
|
Packit |
13e616 |
if ((p_mad->mgmt_class == IB_MCLASS_SUBN_DIR) ||
|
|
Packit |
13e616 |
(p_mad->mgmt_class == IB_MCLASS_SUBN_LID)) {
|
|
Packit |
13e616 |
/* SMI CASE */
|
|
Packit |
13e616 |
p_bo = (osmv_bind_obj_t *) private_ctx_p;
|
|
Packit |
13e616 |
/* Make sure the p_bo object is still relevant */
|
|
Packit |
13e616 |
if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vendor = p_bo->p_vendor;
|
|
Packit |
13e616 |
p_tinfo =
|
|
Packit |
13e616 |
(osmv_IBMGT_transport_info_t *) p_vendor->p_transport_info;
|
|
Packit |
13e616 |
p_list = p_tinfo->p_smi_list;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* GSI CASE */
|
|
Packit |
13e616 |
p_bo = (osmv_bind_obj_t *) private_ctx_p;
|
|
Packit |
13e616 |
/* Make sure the p_bo object is still relevant */
|
|
Packit |
13e616 |
if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vendor = p_bo->p_vendor;
|
|
Packit |
13e616 |
p_tinfo =
|
|
Packit |
13e616 |
(osmv_IBMGT_transport_info_t *) p_vendor->p_transport_info;
|
|
Packit |
13e616 |
p_list = p_tinfo->gsi_mgmt_lists[p_mad->mgmt_class];
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* go over the bindings list and send the mad, one of them will accept it,
|
|
Packit |
13e616 |
the others will drope
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
p_item = cl_qlist_head(p_list);
|
|
Packit |
13e616 |
while (p_item != cl_qlist_end(p_list)) {
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item);
|
|
Packit |
13e616 |
p_bo = cl_qlist_obj(p_obj);
|
|
Packit |
13e616 |
/* give upper layer the mad */
|
|
Packit |
13e616 |
osmv_dispatch_mad((osm_bind_handle_t) p_bo, payload_p,
|
|
Packit |
13e616 |
&mad_addr);
|
|
Packit |
13e616 |
/* Make sure the p_bo object is still relevant */
|
|
Packit |
13e616 |
if ((p_bo->magic_ptr != p_bo) || p_bo->is_closing)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_item = cl_qlist_next(p_item);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/**********************************************************************
|
|
Packit |
13e616 |
* IB_MGT Send callback : invoked after each send
|
|
Packit |
13e616 |
**********************************************************************/
|
|
Packit |
13e616 |
void
|
|
Packit |
13e616 |
__osmv_IBMGT_send_cb(IN IB_MGT_mad_hndl_t mad_hndl,
|
|
Packit |
13e616 |
IN u_int64_t wrid,
|
|
Packit |
13e616 |
IN IB_comp_status_t status, IN void *private_ctx_p)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) CAST_P2LONG(wrid);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_IBMGT_transport_mgr_t *p_mgr =
|
|
Packit |
13e616 |
(osmv_IBMGT_transport_mgr_t *) p_bo->p_transp_mgr;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Make sure the p_bo object is still relevant */
|
|
Packit |
13e616 |
if (p_bo->magic_ptr != p_bo)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* we assume that each send on a bind object is synchronized, and no paralel sends
|
|
Packit |
13e616 |
from diffrent threads with same object can be made */
|
|
Packit |
13e616 |
if (status == IB_COMP_SUCCESS) {
|
|
Packit |
13e616 |
p_mgr->is_send_ok = TRUE;
|
|
Packit |
13e616 |
} else
|
|
Packit |
13e616 |
p_mgr->is_send_ok = FALSE;
|
|
Packit |
13e616 |
cl_event_signal(&p_mgr->send_done);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/**********************************************************************
|
|
Packit |
13e616 |
* IB_MGT to OSM ADDRESS VECTOR
|
|
Packit |
13e616 |
**********************************************************************/
|
|
Packit |
13e616 |
static void
|
|
Packit |
13e616 |
__osmv_IBMGT_rcv_desc_to_osm_addr(IN IB_MGT_mad_rcv_desc_t * p_rcv_desc,
|
|
Packit |
13e616 |
IN uint8_t is_smi,
|
|
Packit |
13e616 |
OUT osm_mad_addr_t * p_mad_addr)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
/* p_mad_addr->dest_lid = p_osm->subn.sm_base_lid; - for resp we use the dest lid ... */
|
|
Packit |
13e616 |
p_mad_addr->dest_lid = cl_hton16(p_rcv_desc->remote_lid);
|
|
Packit |
13e616 |
p_mad_addr->static_rate = 0; /* HACK - we do not know the rate ! */
|
|
Packit |
13e616 |
p_mad_addr->path_bits = p_rcv_desc->local_path_bits;
|
|
Packit |
13e616 |
/* Clear the grh any way to avoid unset fields */
|
|
Packit |
13e616 |
memset(&p_mad_addr->addr_type.gsi.grh_info, 0,
|
|
Packit |
13e616 |
sizeof(p_mad_addr->addr_type.gsi.grh_info));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (is_smi) {
|
|
Packit |
13e616 |
/* SMI */
|
|
Packit |
13e616 |
p_mad_addr->addr_type.smi.source_lid =
|
|
Packit |
13e616 |
cl_hton16(p_rcv_desc->remote_lid);
|
|
Packit |
13e616 |
p_mad_addr->addr_type.smi.port_num = 99; /* HACK - if used - should fail */
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* GSI */
|
|
Packit |
13e616 |
/* seems to me there is a IBMGT bug reversing the QPN ... */
|
|
Packit |
13e616 |
/* Does IBMGT supposed to provide the QPN is network or HOST ? */
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.remote_qp = cl_hton32(p_rcv_desc->qp);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
|
|
Packit |
13e616 |
/* we do have the p_mad_addr->pkey_ix but how to get the PKey by index ? */
|
|
Packit |
13e616 |
/* the only way seems to be to use VAPI_query_hca_pkey_tbl and obtain */
|
|
Packit |
13e616 |
/* the full PKey table - than go by the index. */
|
|
Packit |
13e616 |
/* since this does not seem reasonable to me I simply use the default */
|
|
Packit |
13e616 |
/* There is a TAVOR limitation that only one P_KEY is supported per */
|
|
Packit |
13e616 |
/* QP - so QP1 must use IB_DEFAULT_PKEY */
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.pkey_ix = 0;
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.service_level = p_rcv_desc->sl;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.global_route = p_rcv_desc->grh_flag;
|
|
Packit |
13e616 |
/* copy the GRH data if relevant */
|
|
Packit |
13e616 |
if (p_mad_addr->addr_type.gsi.global_route) {
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
|
|
Packit |
13e616 |
ib_grh_set_ver_class_flow(p_rcv_desc->grh.
|
|
Packit |
13e616 |
IP_version,
|
|
Packit |
13e616 |
p_rcv_desc->grh.
|
|
Packit |
13e616 |
traffic_class,
|
|
Packit |
13e616 |
p_rcv_desc->grh.
|
|
Packit |
13e616 |
flow_label);
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.grh_info.hop_limit =
|
|
Packit |
13e616 |
p_rcv_desc->grh.hop_limit;
|
|
Packit |
13e616 |
memcpy(&p_mad_addr->addr_type.gsi.grh_info.src_gid.raw,
|
|
Packit |
13e616 |
&p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
|
|
Packit |
13e616 |
memcpy(&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
|
|
Packit |
13e616 |
p_rcv_desc->grh.dgid, sizeof(ib_net64_t));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/**********************************************************************
|
|
Packit |
13e616 |
* OSM ADDR VECTOR TO IB_MGT
|
|
Packit |
13e616 |
**********************************************************************/
|
|
Packit |
13e616 |
void
|
|
Packit |
13e616 |
__osmv_IBMGT_osm_addr_to_ibmgt_addr(IN const osm_mad_addr_t * p_mad_addr,
|
|
Packit |
13e616 |
IN uint8_t is_smi, OUT IB_ud_av_t * p_av)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* For global destination or Multicast address: */
|
|
Packit |
13e616 |
u_int8_t ver;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_av, 0, sizeof(IB_ud_av_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_av->src_path_bits = p_mad_addr->path_bits;
|
|
Packit |
13e616 |
p_av->static_rate = p_mad_addr->static_rate;
|
|
Packit |
13e616 |
p_av->dlid = cl_ntoh16(p_mad_addr->dest_lid);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (is_smi) {
|
|
Packit |
13e616 |
p_av->sl = 0; /* Just to note we use 0 here. */
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
p_av->sl = p_mad_addr->addr_type.gsi.service_level;
|
|
Packit |
13e616 |
p_av->grh_flag = p_mad_addr->addr_type.gsi.global_route;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_mad_addr->addr_type.gsi.global_route) {
|
|
Packit |
13e616 |
ib_grh_get_ver_class_flow(p_mad_addr->addr_type.gsi.
|
|
Packit |
13e616 |
grh_info.ver_class_flow, &ver,
|
|
Packit |
13e616 |
&p_av->traffic_class,
|
|
Packit |
13e616 |
&p_av->flow_label);
|
|
Packit |
13e616 |
p_av->hop_limit =
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.grh_info.hop_limit;
|
|
Packit |
13e616 |
p_av->sgid_index = 0; /* we always use source GID 0 */
|
|
Packit |
13e616 |
memcpy(&p_av->dgid,
|
|
Packit |
13e616 |
&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
|
|
Packit |
13e616 |
sizeof(ib_net64_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|