1219820Sjeff/*
2219820Sjeff * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.
3219820Sjeff *
4219820Sjeff * This software is available to you under a choice of one of two
5219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
6219820Sjeff * General Public License (GPL) Version 2, available from the file
7219820Sjeff * COPYING in the main directory of this source tree, or the
8219820Sjeff * OpenIB.org BSD license below:
9219820Sjeff *
10219820Sjeff *     Redistribution and use in source and binary forms, with or
11219820Sjeff *     without modification, are permitted provided that the following
12219820Sjeff *     conditions are met:
13219820Sjeff *
14219820Sjeff *      - Redistributions of source code must retain the above
15219820Sjeff *        copyright notice, this list of conditions and the following
16219820Sjeff *        disclaimer.
17219820Sjeff *
18219820Sjeff *      - Redistributions in binary form must reproduce the above
19219820Sjeff *        copyright notice, this list of conditions and the following
20219820Sjeff *        disclaimer in the documentation and/or other materials
21219820Sjeff *        provided with the distribution.
22219820Sjeff *
23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30219820Sjeff * SOFTWARE.
31219820Sjeff *
32219820Sjeff */
33219820Sjeff
34219820Sjeff#if HAVE_CONFIG_H
35219820Sjeff#  include <config.h>
36219820Sjeff#endif /* HAVE_CONFIG_H */
37219820Sjeff
38219820Sjeff#include <stdio.h>
39219820Sjeff#include <stdlib.h>
40219820Sjeff#include <unistd.h>
41219820Sjeff#include <string.h>
42219820Sjeff#include <pthread.h>
43219820Sjeff#include <sys/time.h>
44219820Sjeff
45219820Sjeff#include <mad.h>
46219820Sjeff#include <infiniband/common.h>
47219820Sjeff
48219820Sjeff#undef DEBUG
49219820Sjeff#define DEBUG 	if (ibdebug)	IBWARN
50219820Sjeff
51219820Sjeffuint8_t *
52219820Sjeffsmp_set_via(void *data, ib_portid_t *portid, unsigned attrid, unsigned mod, unsigned timeout, const void *srcport)
53219820Sjeff{
54219820Sjeff	ib_rpc_t rpc = {0};
55219820Sjeff
56219820Sjeff	DEBUG("attr 0x%x mod 0x%x route %s", attrid, mod, portid2str(portid));
57219820Sjeff	if ((portid->lid <= 0) ||
58219820Sjeff	    (portid->drpath.drslid == 0xffff) ||
59219820Sjeff	    (portid->drpath.drdlid == 0xffff))
60219820Sjeff		rpc.mgtclass = IB_SMI_DIRECT_CLASS;	/* direct SMI */
61219820Sjeff	else
62219820Sjeff		rpc.mgtclass = IB_SMI_CLASS;		/* Lid routed SMI */
63219820Sjeff
64219820Sjeff	rpc.method = IB_MAD_METHOD_SET;
65219820Sjeff	rpc.attr.id = attrid;
66219820Sjeff	rpc.attr.mod = mod;
67219820Sjeff	rpc.timeout = timeout;
68219820Sjeff	rpc.datasz = IB_SMP_DATA_SIZE;
69219820Sjeff	rpc.dataoffs = IB_SMP_DATA_OFFS;
70219820Sjeff
71219820Sjeff	portid->sl = 0;
72219820Sjeff	portid->qp = 0;
73219820Sjeff
74219820Sjeff	if (srcport) {
75219820Sjeff		return mad_rpc(srcport, &rpc, portid, data, data);
76219820Sjeff	} else {
77219820Sjeff		return madrpc(&rpc, portid, data, data);
78219820Sjeff	}
79219820Sjeff}
80219820Sjeff
81219820Sjeffuint8_t *
82219820Sjeffsmp_set(void *data, ib_portid_t *portid, unsigned attrid, unsigned mod, unsigned timeout)
83219820Sjeff{
84219820Sjeff	return smp_set_via(data, portid, attrid, mod, timeout, NULL);
85219820Sjeff}
86219820Sjeff
87219820Sjeffuint8_t *
88219820Sjeffsmp_query_via(void *rcvbuf, ib_portid_t *portid, unsigned attrid, unsigned mod,
89219820Sjeff	      unsigned timeout, const void *srcport)
90219820Sjeff{
91219820Sjeff	ib_rpc_t rpc = {0};
92219820Sjeff
93219820Sjeff	DEBUG("attr 0x%x mod 0x%x route %s", attrid, mod, portid2str(portid));
94219820Sjeff	rpc.method = IB_MAD_METHOD_GET;
95219820Sjeff	rpc.attr.id = attrid;
96219820Sjeff	rpc.attr.mod = mod;
97219820Sjeff	rpc.timeout = timeout;
98219820Sjeff	rpc.datasz = IB_SMP_DATA_SIZE;
99219820Sjeff	rpc.dataoffs = IB_SMP_DATA_OFFS;
100219820Sjeff
101219820Sjeff	if ((portid->lid <= 0) ||
102219820Sjeff	    (portid->drpath.drslid == 0xffff) ||
103219820Sjeff	    (portid->drpath.drdlid == 0xffff))
104219820Sjeff		rpc.mgtclass = IB_SMI_DIRECT_CLASS;	/* direct SMI */
105219820Sjeff	else
106219820Sjeff		rpc.mgtclass = IB_SMI_CLASS;		/* Lid routed SMI */
107219820Sjeff
108219820Sjeff	portid->sl = 0;
109219820Sjeff	portid->qp = 0;
110219820Sjeff
111219820Sjeff	if (srcport) {
112219820Sjeff		return mad_rpc(srcport, &rpc, portid, 0, rcvbuf);
113219820Sjeff	} else {
114219820Sjeff		return madrpc(&rpc, portid, 0, rcvbuf);
115219820Sjeff	}
116219820Sjeff}
117219820Sjeff
118219820Sjeffuint8_t *
119219820Sjeffsmp_query(void *rcvbuf, ib_portid_t *portid, unsigned attrid, unsigned mod,
120219820Sjeff	  unsigned timeout)
121219820Sjeff{
122219820Sjeff	return smp_query_via(rcvbuf, portid, attrid, mod, timeout, NULL);
123219820Sjeff}
124