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 51static 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 78int mad_class_agent(int mgmt) 79{ 80 if (mgmt < 1 || mgmt >= MAX_CLASS) 81 return -1; 82 return ibmp->class_agents[mgmt]; 83} 84 85int 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 101int mad_register_client(int mgmt, uint8_t rmpp_version) 102{ 103 return mad_register_client_via(mgmt, rmpp_version, ibmp); 104} 105 106int 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 123int 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 130int 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