libibmad: updated based on merge feedback
[mirror/winof/.git] / ulp / libibmad / src / register.c
1 /*
2  * Copyright (c) 2004,2005 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 "mad.h"
45
46 #undef DEBUG
47 #define DEBUG   if (ibdebug)    IBWARN
48
49 #define MAX_CLASS       256
50 #define MAX_AGENTS      256
51
52 static int class_agent[MAX_CLASS];
53 static int agent_class[MAX_AGENTS];
54
55 static int
56 register_agent(int agent, int mclass)
57 {
58         static int initialized;
59
60         if (!initialized) {
61                 initialized++;
62                 memset(class_agent, 0xff, sizeof class_agent);
63                 memset(agent_class, 0xff, sizeof agent_class);
64         }
65
66         if (mclass < 0 || mclass >= MAX_CLASS ||
67             agent < 0 || agent >= MAX_AGENTS) {
68                 DEBUG("bad mgmt class %d or agent %d", mclass, agent);
69                 return -1;
70         }
71
72         class_agent[mclass] = agent;
73         agent_class[agent] = mclass;
74
75         return 0;
76 }
77
78 static int
79 mgmt_class_vers(int mgmt_class)
80 {
81         if ((mgmt_class >= IB_VENDOR_RANGE1_START_CLASS &&
82              mgmt_class <= IB_VENDOR_RANGE1_END_CLASS) ||
83             (mgmt_class >= IB_VENDOR_RANGE2_START_CLASS &&
84              mgmt_class <= IB_VENDOR_RANGE2_END_CLASS))
85                 return 1;
86
87         switch(mgmt_class) {
88                 case IB_SMI_CLASS:
89                 case IB_SMI_DIRECT_CLASS:
90                         return 1;
91                 case IB_SA_CLASS:
92                         return 2;
93                 case IB_PERFORMANCE_CLASS:
94                         return 1;
95                 case IB_DEVICE_MGMT_CLASS:
96                         return 1;
97                 case IB_CC_CLASS:
98                         return 2;
99         }
100
101         return 0;
102 }
103
104 int
105 mad_class_agent(int mgmt)
106 {
107         if (mgmt < 1 || mgmt > MAX_CLASS)
108                 return -1;
109         return class_agent[mgmt];
110 }
111
112 int
113 mad_agent_class(int agent)
114 {
115         if (agent < 1 || agent > MAX_AGENTS)
116                 return -1;
117         return agent_class[agent];
118 }
119
120 int
121 mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version)
122 {
123         int vers, agent;
124
125         if ((vers = mgmt_class_vers(mgmt)) <= 0) {
126                 DEBUG("Unknown class %d mgmt_class", mgmt);
127                 return -1;
128         }
129         if ((agent = umad_register(port_id, mgmt,
130                                    vers, rmpp_version, 0)) < 0) {
131                 DEBUG("Can't register agent for class %d", mgmt);
132                 return -1;
133         }
134
135         if (mgmt < 0 || mgmt >= MAX_CLASS || agent >= MAX_AGENTS) {
136                 DEBUG("bad mgmt class %d or agent %d", mgmt, agent);
137                 return -1;
138         }
139
140         return agent;
141 }
142
143 int
144 mad_register_client(int mgmt, uint8_t rmpp_version)
145 {
146         int agent;
147
148         agent = mad_register_port_client(madrpc_portid(), mgmt, rmpp_version);
149         if (agent < 0)
150                 return agent;
151
152         return register_agent(agent, mgmt);
153 }
154
155 int
156 mad_register_server(int mgmt, uint8_t rmpp_version,
157                     long method_mask[], uint32_t class_oui)
158 {
159         long class_method_mask[16/sizeof(long)];
160         uint8_t oui[3];
161         int agent, vers, mad_portid;
162
163         if (method_mask)
164                 memcpy(class_method_mask, method_mask, sizeof class_method_mask);
165         else
166                 memset(class_method_mask, 0xff, sizeof(class_method_mask));
167
168         if ((mad_portid = madrpc_portid()) < 0)
169                 return -1;
170
171         if (class_agent[mgmt] >= 0) {
172                 DEBUG("Class 0x%x already registered", mgmt);
173                 return -1;
174         }
175         if ((vers = mgmt_class_vers(mgmt)) <= 0) {
176                 DEBUG("Unknown class 0x%x mgmt_class", mgmt);
177                 return -1;
178         }
179         if (mgmt >= IB_VENDOR_RANGE2_START_CLASS &&
180             mgmt <= IB_VENDOR_RANGE2_END_CLASS) {
181                 oui[0] = (class_oui >> 16) & 0xff;
182                 oui[1] = (class_oui >> 8) & 0xff;
183                 oui[2] = class_oui & 0xff;
184                 if ((agent = umad_register_oui(mad_portid, mgmt, rmpp_version,
185                                                oui, class_method_mask)) < 0) {
186                         DEBUG("Can't register agent for class %d", mgmt);
187                         return -1;
188                 }
189         } else if ((agent = umad_register(mad_portid, mgmt, vers, rmpp_version,
190                                           class_method_mask)) < 0) {
191                 DEBUG("Can't register agent for class %d", mgmt);
192                 return -1;
193         }
194
195         if (register_agent(agent, mgmt) < 0)
196                 return -1;
197
198         return agent;
199 }