xref: /freebsd/contrib/ofed/libibmad/register.c (revision c697fb7f)
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 
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 
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 
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 
101 int mad_register_client(int mgmt, uint8_t rmpp_version)
102 {
103 	return mad_register_client_via(mgmt, rmpp_version, ibmp);
104 }
105 
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 
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 
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