Blame osmtest/osmt_mtl_regular_qp.c

Packit 13e616
/*
Packit 13e616
 * Copyright (c) 2009 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
#ifdef OSM_VENDOR_INTF_MTL
Packit 13e616
Packit 13e616
/*                  - Mellanox Confidential and Proprietary -
Packit 13e616
 *
Packit 13e616
 *  Copyright (C) Jul. 2001, Mellanox Technologies Ltd.  ALL RIGHTS RESERVED.
Packit 13e616
 *
Packit 13e616
 *  Except as specifically permitted herein, no portion of the information,
Packit 13e616
 *  including but not limited to object code and source code, may be reproduced,
Packit 13e616
 *  modified, distributed, republished or otherwise exploited in any form or by
Packit 13e616
 *  any means for any purpose without the prior written permission of Mellanox
Packit 13e616
 *  Technologies Ltd. Use of software subject to the terms and conditions
Packit 13e616
 *  detailed in the file "LICENSE.txt".
Packit 13e616
 *
Packit 13e616
 *  End of legal section ......................................................
Packit 13e616
 *
Packit 13e616
 *  osmt_mtl_regular_qp.c -
Packit 13e616
 *    Provide Simple Interface for Sending and Receiving MADS through a regular QP
Packit 13e616
 *
Packit 13e616
 *  Creation date:
Packit 13e616
 *
Packit 13e616
 *  Version: $Id$
Packit 13e616
 *
Packit 13e616
 *  Authors:
Packit 13e616
 *    Eitan Zahavi
Packit 13e616
 *
Packit 13e616
 *  Changes:
Packit 13e616
 */
Packit 13e616
Packit 13e616
#include <stdio.h>
Packit 13e616
#include <stdlib.h>
Packit 13e616
#include <string.h>
Packit 13e616
#include <unistd.h>
Packit 13e616
#include <signal.h>
Packit 13e616
Packit 13e616
#include <mtl_common.h>
Packit 13e616
#include <vapi.h>
Packit 13e616
#include <evapi.h>
Packit 13e616
#include <vapi_common.h>
Packit 13e616
#include <ib_defs.h>
Packit 13e616
#include <osmt_mtl_regular_qp.h>
Packit 13e616
#include <complib/cl_types.h>
Packit 13e616
/*
Packit 13e616
 * Initialize the QP etc.
Packit 13e616
 * Given in res: port_num, max_outs_sq, max_outs_rq
Packit 13e616
 */
Packit 13e616
VAPI_ret_t osmt_mtl_get_qp_resources(IN OUT osmt_mtl_mad_res_t * res)
Packit 13e616
{
Packit 13e616
	VAPI_ret_t ret;
Packit 13e616
	VAPI_hca_port_t hca_port_info;
Packit 13e616
	VAPI_qp_init_attr_t qp_init_attr;
Packit 13e616
	VAPI_qp_prop_t qp_prop;
Packit 13e616
	VAPI_cqe_num_t act_num;
Packit 13e616
Packit 13e616
	/* Get HCA LID */
Packit 13e616
	ret =
Packit 13e616
	    VAPI_query_hca_port_prop(res->hca_hndl, res->port_num,
Packit 13e616
				     &hca_port_info);
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
	res->slid = hca_port_info.lid;
Packit 13e616
Packit 13e616
	/* Get a PD */
Packit 13e616
	ret = VAPI_alloc_pd(res->hca_hndl, &(res->pd_hndl));
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
Packit 13e616
	/* Create CQ for RQ and SQ *//* TBD - Check we have enough act nums */
Packit 13e616
	ret =
Packit 13e616
	    VAPI_create_cq(res->hca_hndl, res->max_outs_sq + 1,
Packit 13e616
			   &(res->sq_cq_hndl), &act_num);
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
	ret =
Packit 13e616
	    VAPI_create_cq(res->hca_hndl, res->max_outs_rq + 1,
Packit 13e616
			   &(res->rq_cq_hndl), &act_num);
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
Packit 13e616
	/* register event handlers for polling(block mode) internal use */
Packit 13e616
	/* ret= EVAPI_set_comp_eventh(res->hca_hndl,res->rq_cq_hndl, */
Packit 13e616
	/*                            EVAPI_POLL_CQ_UNBLOCK_HANDLER,NULL,&(res->rq_cq_eventh)); */
Packit 13e616
	/* VAPI_CHECK_RET; */
Packit 13e616
	/* ret= EVAPI_set_comp_eventh(res->hca_hndl,res->sq_cq_hndl, */
Packit 13e616
	/*                            EVAPI_POLL_CQ_UNBLOCK_HANDLER,NULL,&(res->sq_cq_eventh)); */
Packit 13e616
	/* VAPI_CHECK_RET; */
Packit 13e616
Packit 13e616
	/* Create QP */
Packit 13e616
	qp_init_attr.cap.max_oust_wr_sq = res->max_outs_sq + 1;
Packit 13e616
	qp_init_attr.cap.max_oust_wr_rq = res->max_outs_rq + 1;
Packit 13e616
	qp_init_attr.cap.max_sg_size_sq = 4;
Packit 13e616
	qp_init_attr.cap.max_sg_size_rq = 4;
Packit 13e616
Packit 13e616
	qp_init_attr.pd_hndl = res->pd_hndl;
Packit 13e616
	qp_init_attr.rdd_hndl = 0;
Packit 13e616
	qp_init_attr.rq_cq_hndl = res->rq_cq_hndl;
Packit 13e616
	qp_init_attr.rq_sig_type = VAPI_SIGNAL_ALL_WR;	/* That's default for IB */
Packit 13e616
	qp_init_attr.sq_cq_hndl = res->sq_cq_hndl;
Packit 13e616
	qp_init_attr.sq_sig_type = VAPI_SIGNAL_REQ_WR;
Packit 13e616
	qp_init_attr.ts_type = VAPI_TS_UD;
Packit 13e616
Packit 13e616
	ret =
Packit 13e616
	    VAPI_create_qp(res->hca_hndl, &qp_init_attr, &(res->qp_hndl),
Packit 13e616
			   &qp_prop);
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
	res->qp_id.qp_num = qp_prop.qp_num;
Packit 13e616
Packit 13e616
	return (VAPI_OK);
Packit 13e616
}
Packit 13e616
Packit 13e616
VAPI_ret_t osmt_mtl_qp_init(osmt_mtl_mad_res_t * res)
Packit 13e616
{
Packit 13e616
	VAPI_ret_t ret;
Packit 13e616
Packit 13e616
	VAPI_qp_attr_t qp_attr;
Packit 13e616
	VAPI_qp_attr_mask_t qp_attr_mask;
Packit 13e616
	VAPI_qp_cap_t qp_cap;
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * Change QP to INIT
Packit 13e616
	 *
Packit 13e616
	 */
Packit 13e616
	QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
Packit 13e616
	qp_attr.qp_state = VAPI_INIT;
Packit 13e616
	QP_ATTR_MASK_SET(qp_attr_mask, QP_ATTR_QP_STATE);
Packit 13e616
	qp_attr.pkey_ix = 0;
Packit 13e616
	QP_ATTR_MASK_SET(qp_attr_mask, QP_ATTR_PKEY_IX);
Packit 13e616
	qp_attr.port = res->port_num;
Packit 13e616
	QP_ATTR_MASK_SET(qp_attr_mask, QP_ATTR_PORT);
Packit 13e616
	qp_attr.qkey = res->qkey;
Packit 13e616
	QP_ATTR_MASK_SET(qp_attr_mask, QP_ATTR_QKEY);
Packit 13e616
Packit 13e616
	/* If I do not set this mask, I get an error from HH. QPM should catch it */
Packit 13e616
	ret =
Packit 13e616
	    VAPI_modify_qp(res->hca_hndl, res->qp_hndl, &qp_attr, &qp_attr_mask,
Packit 13e616
			   &qp_cap);
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
Packit 13e616
	return (ret);
Packit 13e616
Packit 13e616
}
Packit 13e616
Packit 13e616
VAPI_ret_t osmt_mtl_qp_2_rtr_rts(osmt_mtl_mad_res_t * res)
Packit 13e616
{
Packit 13e616
	VAPI_ret_t ret;
Packit 13e616
Packit 13e616
	VAPI_qp_attr_t qp_attr;
Packit 13e616
	VAPI_qp_attr_mask_t qp_attr_mask;
Packit 13e616
	VAPI_qp_cap_t qp_cap;
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 *  Change QP to RTR
Packit 13e616
	 *
Packit 13e616
	 */
Packit 13e616
	QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
Packit 13e616
	qp_attr.qp_state = VAPI_RTR;
Packit 13e616
	QP_ATTR_MASK_SET(qp_attr_mask, QP_ATTR_QP_STATE);
Packit 13e616
	/*   qp_attr.rq_psn   = 0;                */
Packit 13e616
	/*   QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_RQ_PSN); */
Packit 13e616
Packit 13e616
	ret =
Packit 13e616
	    VAPI_modify_qp(res->hca_hndl, res->qp_hndl, &qp_attr, &qp_attr_mask,
Packit 13e616
			   &qp_cap);
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * Change QP to RTS
Packit 13e616
	 *
Packit 13e616
	 */
Packit 13e616
	QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
Packit 13e616
	qp_attr.qp_state = VAPI_RTS;
Packit 13e616
	QP_ATTR_MASK_SET(qp_attr_mask, QP_ATTR_QP_STATE);
Packit 13e616
	qp_attr.sq_psn = 0;
Packit 13e616
	QP_ATTR_MASK_SET(qp_attr_mask, QP_ATTR_SQ_PSN);
Packit 13e616
Packit 13e616
	ret =
Packit 13e616
	    VAPI_modify_qp(res->hca_hndl, res->qp_hndl, &qp_attr, &qp_attr_mask,
Packit 13e616
			   &qp_cap);
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
Packit 13e616
	return (ret);
Packit 13e616
}
Packit 13e616
Packit 13e616
VAPI_ret_t osmt_mtl_mad_create_mr(osmt_mtl_mad_res_t * res)
Packit 13e616
{
Packit 13e616
Packit 13e616
	VAPI_ret_t ret;
Packit 13e616
Packit 13e616
	VAPI_mrw_t mr_in, mr_out;
Packit 13e616
Packit 13e616
	res->buf_size =
Packit 13e616
	    (MAD_SIZE + GRH_LEN) * (res->max_outs_sq + res->max_outs_rq + 1);
Packit 13e616
Packit 13e616
	/* Register single memory address region for all buffers */
Packit 13e616
	res->buf_ptr = VMALLOC(res->buf_size);
Packit 13e616
Packit 13e616
	if (res->buf_ptr == ((VAPI_virt_addr_t) NULL)) {
Packit 13e616
		ret = VAPI_EAGAIN;
Packit 13e616
		VAPI_CHECK_RET;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	/* Enable local and remote access to memory region */
Packit 13e616
	mr_in.acl = VAPI_EN_LOCAL_WRITE | VAPI_EN_REMOTE_WRITE;
Packit 13e616
	mr_in.l_key = 0;
Packit 13e616
	mr_in.pd_hndl = res->pd_hndl;
Packit 13e616
	mr_in.r_key = 0;
Packit 13e616
	mr_in.size = res->buf_size;
Packit 13e616
	ASSERT_VOIDP2UINTN(res->buf_ptr);
Packit 13e616
	mr_in.start = (VAPI_virt_addr_t) (res->buf_ptr);
Packit 13e616
	mr_in.type = VAPI_MR;
Packit 13e616
Packit 13e616
	ret = VAPI_register_mr(res->hca_hndl, &mr_in, &(res->mr_hndl), &mr_out);
Packit 13e616
	VAPI_CHECK_RET;
Packit 13e616
Packit 13e616
	res->l_key = mr_out.l_key;
Packit 13e616
Packit 13e616
	return (ret);
Packit 13e616
}
Packit 13e616
Packit 13e616
VAPI_ret_t osmt_mtl_init_opened_hca(osmt_mtl_mad_res_t * res)
Packit 13e616
{
Packit 13e616
	VAPI_ret_t ret;
Packit 13e616
Packit 13e616
	res->pd_hndl = VAPI_INVAL_HNDL;
Packit 13e616
	res->rq_cq_hndl = VAPI_INVAL_HNDL;
Packit 13e616
	res->sq_cq_hndl = VAPI_INVAL_HNDL;
Packit 13e616
	res->sq_cq_eventh = VAPI_INVAL_HNDL;
Packit 13e616
	res->rq_cq_eventh = VAPI_INVAL_HNDL;
Packit 13e616
	res->qp_hndl = VAPI_INVAL_HNDL;
Packit 13e616
	res->mr_hndl = VAPI_INVAL_HNDL;
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * Create QP
Packit 13e616
	 *
Packit 13e616
	 */
Packit 13e616
	ret = osmt_mtl_get_qp_resources(res);
Packit 13e616
	if (ret != VAPI_OK) {
Packit 13e616
		return ret;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * Move to init
Packit 13e616
	 *
Packit 13e616
	 */
Packit 13e616
	ret = osmt_mtl_qp_init(res);
Packit 13e616
	if (ret != VAPI_OK) {
Packit 13e616
		return ret;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * Initialize memory regions
Packit 13e616
	 *
Packit 13e616
	 */
Packit 13e616
	ret = osmt_mtl_mad_create_mr(res);
Packit 13e616
	if (ret != VAPI_OK) {
Packit 13e616
		return ret;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	/* only now move to RTR and RTS */
Packit 13e616
	ret = osmt_mtl_qp_2_rtr_rts(res);
Packit 13e616
	if (ret != VAPI_OK) {
Packit 13e616
		return ret;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	return VAPI_OK;
Packit 13e616
}
Packit 13e616
Packit 13e616
VAPI_ret_t osmt_mtl_mad_cleanup(osmt_mtl_mad_res_t * res)
Packit 13e616
{
Packit 13e616
	if (res->qp_hndl != VAPI_INVAL_HNDL) {
Packit 13e616
		VAPI_destroy_qp(res->hca_hndl, res->qp_hndl);
Packit 13e616
	}
Packit 13e616
	if (res->sq_cq_eventh != VAPI_INVAL_HNDL) {
Packit 13e616
		EVAPI_clear_comp_eventh(res->hca_hndl, res->sq_cq_eventh);
Packit 13e616
	}
Packit 13e616
	if (res->rq_cq_eventh != VAPI_INVAL_HNDL) {
Packit 13e616
		EVAPI_clear_comp_eventh(res->hca_hndl, res->rq_cq_eventh);
Packit 13e616
	}
Packit 13e616
	if (res->rq_cq_hndl != VAPI_INVAL_HNDL) {
Packit 13e616
		VAPI_destroy_cq(res->hca_hndl, res->rq_cq_hndl);
Packit 13e616
	}
Packit 13e616
	if (res->sq_cq_hndl != VAPI_INVAL_HNDL) {
Packit 13e616
		VAPI_destroy_cq(res->hca_hndl, res->sq_cq_hndl);
Packit 13e616
	}
Packit 13e616
	if (res->mr_hndl != VAPI_INVAL_HNDL) {
Packit 13e616
		VAPI_deregister_mr(res->hca_hndl, res->mr_hndl);
Packit 13e616
	}
Packit 13e616
	if (res->pd_hndl != VAPI_INVAL_HNDL) {
Packit 13e616
		VAPI_dealloc_pd(res->hca_hndl, res->pd_hndl);
Packit 13e616
	}
Packit 13e616
#if 0
Packit 13e616
	/* open/close of HCA should be done system wide - not per application */
Packit 13e616
	if (res->hca_hndl != VAPI_INVAL_HNDL) {
Packit 13e616
		VAPI_close_hca(res->hca_hndl);	/* TBD: HCA_open/close should be done on a system wide basis */
Packit 13e616
	}
Packit 13e616
#endif
Packit 13e616
	return VAPI_OK;
Packit 13e616
}
Packit 13e616
Packit 13e616
VAPI_ret_t osmt_mtl_create_av(osmt_mtl_mad_res_t * res, int16_t dlid,
Packit 13e616
			      VAPI_ud_av_hndl_t * avh_p)
Packit 13e616
{
Packit 13e616
	VAPI_ud_av_t av;
Packit 13e616
	VAPI_ret_t ret;
Packit 13e616
Packit 13e616
	av.dlid = dlid;
Packit 13e616
	av.port = res->port_num;
Packit 13e616
	av.sl = 0;		/* dest->sl; */
Packit 13e616
	av.src_path_bits = 0;	/*  dest->ee_dlid.dst_path_bits; */
Packit 13e616
	av.static_rate = 0;
Packit 13e616
	/* GRH ? */
Packit 13e616
	av.grh_flag = 0;
Packit 13e616
Packit 13e616
	ret = VAPI_create_addr_hndl(res->hca_hndl, res->pd_hndl, &av, avh_p);
Packit 13e616
	if (ret != VAPI_OK) {
Packit 13e616
		MTL_ERROR1("%s: failed VAPI_create_addr_hndl (%s)\n", __func__,
Packit 13e616
			   VAPI_strerror_sym(ret));
Packit 13e616
		return ret;
Packit 13e616
	}
Packit 13e616
	return VAPI_OK;
Packit 13e616
}
Packit 13e616
Packit 13e616
VAPI_ret_t osmt_mtl_mad_send(osmt_mtl_mad_res_t * res, VAPI_wr_id_t id,
Packit 13e616
			     void *mad, VAPI_qp_num_t dest_qp, IB_sl_t sl,
Packit 13e616
			     u_int32_t dest_qkey, VAPI_ud_av_hndl_t avh)
Packit 13e616
{
Packit 13e616
	VAPI_sr_desc_t sr;
Packit 13e616
	VAPI_sg_lst_entry_t sg_entry;
Packit 13e616
	VAPI_ret_t ret;
Packit 13e616
Packit 13e616
	/* building SEND request */
Packit 13e616
	sr.opcode = VAPI_SEND;
Packit 13e616
	sr.remote_ah = avh;
Packit 13e616
	sr.remote_qp = dest_qp;
Packit 13e616
	sr.remote_qkey = dest_qkey;
Packit 13e616
Packit 13e616
	sr.id = id;
Packit 13e616
	sr.set_se = FALSE;
Packit 13e616
	sr.fence = FALSE;
Packit 13e616
	sr.comp_type = VAPI_SIGNALED;
Packit 13e616
	sr.sg_lst_len = 1;
Packit 13e616
	sr.sg_lst_p = &sg_entry;
Packit 13e616
	ASSERT_VOIDP2UINTN(mad);
Packit 13e616
	sg_entry.addr = (VAPI_virt_addr_t) (mad);
Packit 13e616
	sg_entry.len = MAD_SIZE;
Packit 13e616
	sg_entry.lkey = res->l_key;
Packit 13e616
Packit 13e616
	ret = VAPI_post_sr(res->hca_hndl, res->qp_hndl, &sr);
Packit 13e616
	if (ret != VAPI_OK) {
Packit 13e616
		MTL_ERROR1(__FUNCTION__ ": failed VAPI_post_sr (%s)\n",
Packit 13e616
			   VAPI_strerror_sym(ret));
Packit 13e616
		return ret;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	return VAPI_OK;
Packit 13e616
}
Packit 13e616
Packit 13e616
int osmt_mtl_mad_post_recv_bufs(osmt_mtl_mad_res_t * res, void *buf_array,
Packit 13e616
				u_int32_t num_o_bufs, u_int32_t size,
Packit 13e616
				VAPI_wr_id_t start_id)
Packit 13e616
{
Packit 13e616
	uint32_t i;
Packit 13e616
	void *cur_buf;
Packit 13e616
	VAPI_rr_desc_t rr;
Packit 13e616
	VAPI_sg_lst_entry_t sg_entry;
Packit 13e616
	VAPI_ret_t ret;
Packit 13e616
Packit 13e616
	rr.opcode = VAPI_RECEIVE;
Packit 13e616
	rr.comp_type = VAPI_SIGNALED;	/* All with CQE (IB compliant) */
Packit 13e616
	rr.sg_lst_len = 1;	/* single buffers */
Packit 13e616
	rr.sg_lst_p = &sg_entry;
Packit 13e616
	sg_entry.lkey = res->l_key;
Packit 13e616
	cur_buf = buf_array;
Packit 13e616
	for (i = 0; i < num_o_bufs; i++) {
Packit 13e616
		rr.id = start_id + i;	/* WQE id used is the index to buffers ptr array */
Packit 13e616
		ASSERT_VOIDP2UINTN(cur_buf);
Packit 13e616
		sg_entry.addr = (VAPI_virt_addr_t) cur_buf;
Packit 13e616
		sg_entry.len = size;
Packit 13e616
		memset(cur_buf, 0x00, size);	/* fill with 0 */
Packit 13e616
		ret = VAPI_post_rr(res->hca_hndl, res->qp_hndl, &rr);
Packit 13e616
		if (ret != VAPI_OK) {
Packit 13e616
			MTL_ERROR1(__FUNCTION__
Packit 13e616
				   ": failed posting RQ WQE (%s)\n",
Packit 13e616
				   VAPI_strerror_sym(ret));
Packit 13e616
			return i;
Packit 13e616
		}
Packit 13e616
		MTL_DEBUG4(__FUNCTION__ ": posted buf at %p\n", cur_buf);
Packit 13e616
		cur_buf += size;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	return i;		/* num of buffers posted */
Packit 13e616
}
Packit 13e616
Packit 13e616
VAPI_ret_t osmt_mtl_mad_poll4cqe(VAPI_hca_hndl_t hca, VAPI_cq_hndl_t cq,
Packit 13e616
				 VAPI_wc_desc_t * wc_desc_p,
Packit 13e616
				 u_int32_t max_poll, u_int32_t poll_sleep,
Packit 13e616
				 VAPI_ud_av_hndl_t * avh_p)
Packit 13e616
{
Packit 13e616
	VAPI_ret_t ret = VAPI_CQ_EMPTY;
Packit 13e616
	u_int32_t poll_cnt = 0;
Packit 13e616
Packit 13e616
	/* wait for something to arrive */
Packit 13e616
	while ((ret == VAPI_CQ_EMPTY) && (poll_cnt < max_poll)) {
Packit 13e616
		ret = VAPI_poll_cq(hca, cq, wc_desc_p);
Packit 13e616
		/* don't sleep if we already succeeded) */
Packit 13e616
		if (ret != VAPI_CQ_EMPTY) {
Packit 13e616
			break;
Packit 13e616
		}
Packit 13e616
		usleep(poll_sleep);
Packit 13e616
		poll_cnt++;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	/* if passed an AVH to destory - do it */
Packit 13e616
	if (avh_p != NULL) {
Packit 13e616
		VAPI_destroy_addr_hndl(hca, *avh_p);
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if ((poll_cnt == max_poll) && (ret == VAPI_CQ_EMPTY)) {
Packit 13e616
		MTL_DEBUG1(__FUNCTION__
Packit 13e616
			   ": Failed to get completion on wq after %d polls.\n",
Packit 13e616
			   max_poll);
Packit 13e616
		return VAPI_CQ_EMPTY;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (ret != VAPI_OK) {
Packit 13e616
		MTL_DEBUG1(__FUNCTION__
Packit 13e616
			   ": VAPI_poll_cq failed with ret=%s on sq_cq\n",
Packit 13e616
			   mtl_strerror_sym(ret));
Packit 13e616
		return ret;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (wc_desc_p->status != VAPI_SUCCESS) {
Packit 13e616
		MTL_DEBUG1(__FUNCTION__ ": completion error (%d) detected\n",
Packit 13e616
			   wc_desc_p->status);
Packit 13e616
	}
Packit 13e616
Packit 13e616
	return VAPI_OK;
Packit 13e616
}
Packit 13e616
Packit 13e616
#endif				/*  OSM_VENDOR_INTF_MTL */