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 <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <errno.h>
42
43 #include <infiniband/umad.h>
44 #include <infiniband/mad.h>
45
46 #include "mad_internal.h"
47
48 #undef DEBUG
49 #define DEBUG if (ibdebug) IBWARN
50
mgmt_class_vers(int mgmt_class)51 static int mgmt_class_vers(int mgmt_class)
52 {
53 if ((mgmt_class >= IB_VENDOR_RANGE1_START_CLASS &&
54 mgmt_class <= IB_VENDOR_RANGE1_END_CLASS) ||
55 (mgmt_class >= IB_VENDOR_RANGE2_START_CLASS &&
56 mgmt_class <= IB_VENDOR_RANGE2_END_CLASS))
57 return 1;
58
59 switch (mgmt_class) {
60 case IB_SMI_CLASS:
61 case IB_SMI_DIRECT_CLASS:
62 return 1;
63 case IB_SA_CLASS:
64 return 2;
65 case IB_PERFORMANCE_CLASS:
66 return 1;
67 case IB_DEVICE_MGMT_CLASS:
68 return 1;
69 case IB_CC_CLASS:
70 return 2;
71 case IB_BOARD_MGMT_CLASS:
72 return 1;
73 }
74
75 return 0;
76 }
77
mad_class_agent(int mgmt)78 int mad_class_agent(int mgmt)
79 {
80 if (mgmt < 1 || mgmt >= MAX_CLASS)
81 return -1;
82 return ibmp->class_agents[mgmt];
83 }
84
mad_register_port_client(int port_id,int mgmt,uint8_t rmpp_version)85 int mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version)
86 {
87 int vers, agent;
88
89 if ((vers = mgmt_class_vers(mgmt)) <= 0) {
90 DEBUG("Unknown class %d mgmt_class", mgmt);
91 return -1;
92 }
93
94 agent = umad_register(port_id, mgmt, vers, rmpp_version, 0);
95 if (agent < 0)
96 DEBUG("Can't register agent for class %d", mgmt);
97
98 return agent;
99 }
100
mad_register_client(int mgmt,uint8_t rmpp_version)101 int mad_register_client(int mgmt, uint8_t rmpp_version)
102 {
103 return mad_register_client_via(mgmt, rmpp_version, ibmp);
104 }
105
mad_register_client_via(int mgmt,uint8_t rmpp_version,struct ibmad_port * srcport)106 int mad_register_client_via(int mgmt, uint8_t rmpp_version,
107 struct ibmad_port *srcport)
108 {
109 int agent;
110
111 if (!srcport)
112 return -1;
113
114 agent = mad_register_port_client(mad_rpc_portid(srcport), mgmt,
115 rmpp_version);
116 if (agent < 0)
117 return agent;
118
119 srcport->class_agents[mgmt] = agent;
120 return 0;
121 }
122
mad_register_server(int mgmt,uint8_t rmpp_version,long method_mask[],uint32_t class_oui)123 int mad_register_server(int mgmt, uint8_t rmpp_version,
124 long method_mask[], uint32_t class_oui)
125 {
126 return mad_register_server_via(mgmt, rmpp_version, method_mask,
127 class_oui, ibmp);
128 }
129
mad_register_server_via(int mgmt,uint8_t rmpp_version,long method_mask[],uint32_t class_oui,struct ibmad_port * srcport)130 int mad_register_server_via(int mgmt, uint8_t rmpp_version,
131 long method_mask[], uint32_t class_oui,
132 struct ibmad_port *srcport)
133 {
134 long class_method_mask[16 / sizeof(long)];
135 uint8_t oui[3];
136 int agent, vers;
137
138 if (method_mask)
139 memcpy(class_method_mask, method_mask,
140 sizeof class_method_mask);
141 else
142 memset(class_method_mask, 0xff, sizeof(class_method_mask));
143
144 if (!srcport)
145 return -1;
146
147 if (srcport->class_agents[mgmt] >= 0) {
148 DEBUG("Class 0x%x already registered %d",
149 mgmt, srcport->class_agents[mgmt]);
150 return -1;
151 }
152 if ((vers = mgmt_class_vers(mgmt)) <= 0) {
153 DEBUG("Unknown class 0x%x mgmt_class", mgmt);
154 return -1;
155 }
156 if (mgmt >= IB_VENDOR_RANGE2_START_CLASS &&
157 mgmt <= IB_VENDOR_RANGE2_END_CLASS) {
158 oui[0] = (class_oui >> 16) & 0xff;
159 oui[1] = (class_oui >> 8) & 0xff;
160 oui[2] = class_oui & 0xff;
161 if ((agent =
162 umad_register_oui(srcport->port_id, mgmt, rmpp_version,
163 oui, class_method_mask)) < 0) {
164 DEBUG("Can't register agent for class %d", mgmt);
165 return -1;
166 }
167 } else
168 if ((agent =
169 umad_register(srcport->port_id, mgmt, vers, rmpp_version,
170 class_method_mask)) < 0) {
171 DEBUG("Can't register agent for class %d", mgmt);
172 return -1;
173 }
174
175 srcport->class_agents[mgmt] = agent;
176
177 return agent;
178 }
179