1321936Shselasky/* 2321936Shselasky * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved. 3321936Shselasky * Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved. 4321936Shselasky * 5321936Shselasky * This software is available to you under a choice of one of two 6321936Shselasky * licenses. You may choose to be licensed under the terms of the GNU 7321936Shselasky * General Public License (GPL) Version 2, available from the file 8321936Shselasky * COPYING in the main directory of this source tree, or the 9321936Shselasky * OpenIB.org BSD license below: 10321936Shselasky * 11321936Shselasky * Redistribution and use in source and binary forms, with or 12321936Shselasky * without modification, are permitted provided that the following 13321936Shselasky * conditions are met: 14321936Shselasky * 15321936Shselasky * - Redistributions of source code must retain the above 16321936Shselasky * copyright notice, this list of conditions and the following 17321936Shselasky * disclaimer. 18321936Shselasky * 19321936Shselasky * - Redistributions in binary form must reproduce the above 20321936Shselasky * copyright notice, this list of conditions and the following 21321936Shselasky * disclaimer in the documentation and/or other materials 22321936Shselasky * provided with the distribution. 23321936Shselasky * 24321936Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25321936Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26321936Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27321936Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28321936Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29321936Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30321936Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31321936Shselasky * SOFTWARE. 32321936Shselasky * 33321936Shselasky */ 34321936Shselasky 35321936Shselasky#if HAVE_CONFIG_H 36321936Shselasky# include <config.h> 37321936Shselasky#endif /* HAVE_CONFIG_H */ 38321936Shselasky 39321936Shselasky#include <stdio.h> 40321936Shselasky#include <stdlib.h> 41321936Shselasky#include <string.h> 42321936Shselasky#include <errno.h> 43321936Shselasky 44321936Shselasky#include <infiniband/umad.h> 45321936Shselasky#include <infiniband/mad.h> 46321936Shselasky#include "mad_internal.h" 47321936Shselasky 48321936Shselasky#undef DEBUG 49321936Shselasky#define DEBUG if (ibdebug) IBWARN 50321936Shselasky 51321936Shselaskystatic inline int response_expected(int method) 52321936Shselasky{ 53321936Shselasky return method == IB_MAD_METHOD_GET || 54321936Shselasky method == IB_MAD_METHOD_SET || method == IB_MAD_METHOD_TRAP; 55321936Shselasky} 56321936Shselasky 57321936Shselaskyuint8_t *ib_vendor_call(void *data, ib_portid_t * portid, 58321936Shselasky ib_vendor_call_t * call) 59321936Shselasky{ 60321936Shselasky return ib_vendor_call_via(data, portid, call, ibmp); 61321936Shselasky} 62321936Shselasky 63321936Shselaskyuint8_t *ib_vendor_call_via(void *data, ib_portid_t * portid, 64321936Shselasky ib_vendor_call_t * call, 65321936Shselasky struct ibmad_port * srcport) 66321936Shselasky{ 67321936Shselasky ib_rpc_v1_t rpc = { 0 }; 68321936Shselasky ib_rpc_t *rpcold = (ib_rpc_t *)(void *)&rpc; 69321936Shselasky int range1 = 0, resp_expected; 70321936Shselasky void *p_ret; 71321936Shselasky 72321936Shselasky DEBUG("route %s data %p", portid2str(portid), data); 73321936Shselasky if (portid->lid <= 0) 74321936Shselasky return NULL; /* no direct SMI */ 75321936Shselasky 76321936Shselasky if (!(range1 = mad_is_vendor_range1(call->mgmt_class)) && 77321936Shselasky !(mad_is_vendor_range2(call->mgmt_class))) 78321936Shselasky return NULL; 79321936Shselasky 80321936Shselasky resp_expected = response_expected(call->method); 81321936Shselasky 82321936Shselasky rpc.mgtclass = call->mgmt_class | IB_MAD_RPC_VERSION1; 83321936Shselasky 84321936Shselasky rpc.method = call->method; 85321936Shselasky rpc.attr.id = call->attrid; 86321936Shselasky rpc.attr.mod = call->mod; 87321936Shselasky rpc.timeout = resp_expected ? call->timeout : 0; 88321936Shselasky rpc.datasz = 89321936Shselasky range1 ? IB_VENDOR_RANGE1_DATA_SIZE : IB_VENDOR_RANGE2_DATA_SIZE; 90321936Shselasky rpc.dataoffs = 91321936Shselasky range1 ? IB_VENDOR_RANGE1_DATA_OFFS : IB_VENDOR_RANGE2_DATA_OFFS; 92321936Shselasky 93321936Shselasky if (!range1) 94321936Shselasky rpc.oui = call->oui; 95321936Shselasky 96321936Shselasky DEBUG 97321936Shselasky ("class 0x%x method 0x%x attr 0x%x mod 0x%x datasz %d off %d res_ex %d", 98321936Shselasky rpc.mgtclass, rpc.method, rpc.attr.id, rpc.attr.mod, rpc.datasz, 99321936Shselasky rpc.dataoffs, resp_expected); 100321936Shselasky 101321936Shselasky portid->qp = 1; 102321936Shselasky if (!portid->qkey) 103321936Shselasky portid->qkey = IB_DEFAULT_QP1_QKEY; 104321936Shselasky 105321936Shselasky if (resp_expected) { 106321936Shselasky p_ret = mad_rpc_rmpp(srcport, rpcold, portid, 0, data); /* FIXME: no RMPP for now */ 107321936Shselasky errno = rpc.error; 108321936Shselasky return p_ret; 109321936Shselasky } 110321936Shselasky 111321936Shselasky return mad_send_via(rpcold, portid, 0, data, srcport) < 0 ? 0 : data; /* FIXME: no RMPP for now */ 112321936Shselasky} 113