1 /* 2 * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 * 32 */ 33 34 #if HAVE_CONFIG_H 35 # include <config.h> 36 #endif /* HAVE_CONFIG_H */ 37 38 #include <string.h> 39 40 #include <infiniband/mad.h> 41 42 #undef DEBUG 43 #define DEBUG if (ibdebug) IBWARN 44 45 static inline int response_expected(int method) 46 { 47 return method == IB_MAD_METHOD_GET || 48 method == IB_MAD_METHOD_SET || method == IB_MAD_METHOD_TRAP; 49 } 50 51 uint8_t *bm_call_via(void *data, ib_portid_t * portid, ib_bm_call_t * call, 52 struct ibmad_port * srcport) 53 { 54 ib_rpc_t rpc = { 0 }; 55 int resp_expected; 56 struct { 57 uint64_t bkey; 58 uint8_t reserved[32]; 59 uint8_t data[IB_BM_DATA_SZ]; 60 } bm_data; 61 62 DEBUG("route %s data %p", portid2str(portid), data); 63 if (portid->lid <= 0) { 64 IBWARN("only lid routes are supported"); 65 return NULL; 66 } 67 68 resp_expected = response_expected(call->method); 69 70 rpc.mgtclass = IB_BOARD_MGMT_CLASS; 71 72 rpc.method = call->method; 73 rpc.attr.id = call->attrid; 74 rpc.attr.mod = call->mod; 75 rpc.timeout = resp_expected ? call->timeout : 0; 76 // send data and bkey 77 rpc.datasz = IB_BM_BKEY_AND_DATA_SZ; 78 rpc.dataoffs = IB_BM_BKEY_OFFS; 79 80 // copy data to a buffer which also includes the bkey 81 bm_data.bkey = htonll(call->bkey); 82 memset(bm_data.reserved, 0, sizeof(bm_data.reserved)); 83 memcpy(bm_data.data, data, IB_BM_DATA_SZ); 84 85 DEBUG 86 ("method 0x%x attr 0x%x mod 0x%x datasz %d off %d res_ex %d bkey 0x%08x%08x", 87 rpc.method, rpc.attr.id, rpc.attr.mod, rpc.datasz, rpc.dataoffs, 88 resp_expected, (int)(call->bkey >> 32), (int)call->bkey); 89 90 portid->qp = 1; 91 if (!portid->qkey) 92 portid->qkey = IB_DEFAULT_QP1_QKEY; 93 94 if (resp_expected) { 95 /* FIXME: no RMPP for now */ 96 if (mad_rpc(srcport, &rpc, portid, &bm_data, &bm_data)) 97 goto return_ok; 98 return NULL; 99 } 100 101 if (mad_send_via(&rpc, portid, 0, &bm_data, srcport) < 0) 102 return NULL; 103 104 return_ok: 105 memcpy(data, bm_data.data, IB_BM_DATA_SZ); 106 return data; 107 } 108