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