1321936Shselasky/* 2321936Shselasky * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved. 3321936Shselasky * 4321936Shselasky * This software is available to you under a choice of one of two 5321936Shselasky * licenses. You may choose to be licensed under the terms of the GNU 6321936Shselasky * General Public License (GPL) Version 2, available from the file 7321936Shselasky * COPYING in the main directory of this source tree, or the 8321936Shselasky * OpenIB.org BSD license below: 9321936Shselasky * 10321936Shselasky * Redistribution and use in source and binary forms, with or 11321936Shselasky * without modification, are permitted provided that the following 12321936Shselasky * conditions are met: 13321936Shselasky * 14321936Shselasky * - Redistributions of source code must retain the above 15321936Shselasky * copyright notice, this list of conditions and the following 16321936Shselasky * disclaimer. 17321936Shselasky * 18321936Shselasky * - Redistributions in binary form must reproduce the above 19321936Shselasky * copyright notice, this list of conditions and the following 20321936Shselasky * disclaimer in the documentation and/or other materials 21321936Shselasky * provided with the distribution. 22321936Shselasky * 23321936Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24321936Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25321936Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26321936Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27321936Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28321936Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29321936Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30321936Shselasky * SOFTWARE. 31321936Shselasky * 32321936Shselasky */ 33321936Shselasky 34321936Shselasky#if HAVE_CONFIG_H 35321936Shselasky# include <config.h> 36321936Shselasky#endif /* HAVE_CONFIG_H */ 37321936Shselasky 38321936Shselasky#include <stdio.h> 39321936Shselasky#include <stdlib.h> 40321936Shselasky#include <string.h> 41321936Shselasky#include <errno.h> 42321936Shselasky 43321936Shselasky#include <infiniband/umad.h> 44321936Shselasky#include <infiniband/mad.h> 45321936Shselasky 46321936Shselasky#include "mad_internal.h" 47321936Shselasky 48321936Shselasky#undef DEBUG 49321936Shselasky#define DEBUG if (ibdebug) IBWARN 50321936Shselasky 51321936Shselaskystatic int mgmt_class_vers(int mgmt_class) 52321936Shselasky{ 53321936Shselasky if ((mgmt_class >= IB_VENDOR_RANGE1_START_CLASS && 54321936Shselasky mgmt_class <= IB_VENDOR_RANGE1_END_CLASS) || 55321936Shselasky (mgmt_class >= IB_VENDOR_RANGE2_START_CLASS && 56321936Shselasky mgmt_class <= IB_VENDOR_RANGE2_END_CLASS)) 57321936Shselasky return 1; 58321936Shselasky 59321936Shselasky switch (mgmt_class) { 60321936Shselasky case IB_SMI_CLASS: 61321936Shselasky case IB_SMI_DIRECT_CLASS: 62321936Shselasky return 1; 63321936Shselasky case IB_SA_CLASS: 64321936Shselasky return 2; 65321936Shselasky case IB_PERFORMANCE_CLASS: 66321936Shselasky return 1; 67321936Shselasky case IB_DEVICE_MGMT_CLASS: 68321936Shselasky return 1; 69321936Shselasky case IB_CC_CLASS: 70321936Shselasky return 2; 71321936Shselasky case IB_BOARD_MGMT_CLASS: 72321936Shselasky return 1; 73321936Shselasky } 74321936Shselasky 75321936Shselasky return 0; 76321936Shselasky} 77321936Shselasky 78321936Shselaskyint mad_class_agent(int mgmt) 79321936Shselasky{ 80321936Shselasky if (mgmt < 1 || mgmt >= MAX_CLASS) 81321936Shselasky return -1; 82321936Shselasky return ibmp->class_agents[mgmt]; 83321936Shselasky} 84321936Shselasky 85321936Shselaskyint mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version) 86321936Shselasky{ 87321936Shselasky int vers, agent; 88321936Shselasky 89321936Shselasky if ((vers = mgmt_class_vers(mgmt)) <= 0) { 90321936Shselasky DEBUG("Unknown class %d mgmt_class", mgmt); 91321936Shselasky return -1; 92321936Shselasky } 93321936Shselasky 94321936Shselasky agent = umad_register(port_id, mgmt, vers, rmpp_version, 0); 95321936Shselasky if (agent < 0) 96321936Shselasky DEBUG("Can't register agent for class %d", mgmt); 97321936Shselasky 98321936Shselasky return agent; 99321936Shselasky} 100321936Shselasky 101321936Shselaskyint mad_register_client(int mgmt, uint8_t rmpp_version) 102321936Shselasky{ 103321936Shselasky return mad_register_client_via(mgmt, rmpp_version, ibmp); 104321936Shselasky} 105321936Shselasky 106321936Shselaskyint mad_register_client_via(int mgmt, uint8_t rmpp_version, 107321936Shselasky struct ibmad_port *srcport) 108321936Shselasky{ 109321936Shselasky int agent; 110321936Shselasky 111321936Shselasky if (!srcport) 112321936Shselasky return -1; 113321936Shselasky 114321936Shselasky agent = mad_register_port_client(mad_rpc_portid(srcport), mgmt, 115321936Shselasky rmpp_version); 116321936Shselasky if (agent < 0) 117321936Shselasky return agent; 118321936Shselasky 119321936Shselasky srcport->class_agents[mgmt] = agent; 120321936Shselasky return 0; 121321936Shselasky} 122321936Shselasky 123321936Shselaskyint mad_register_server(int mgmt, uint8_t rmpp_version, 124321936Shselasky long method_mask[], uint32_t class_oui) 125321936Shselasky{ 126321936Shselasky return mad_register_server_via(mgmt, rmpp_version, method_mask, 127321936Shselasky class_oui, ibmp); 128321936Shselasky} 129321936Shselasky 130321936Shselaskyint mad_register_server_via(int mgmt, uint8_t rmpp_version, 131321936Shselasky long method_mask[], uint32_t class_oui, 132321936Shselasky struct ibmad_port *srcport) 133321936Shselasky{ 134321936Shselasky long class_method_mask[16 / sizeof(long)]; 135321936Shselasky uint8_t oui[3]; 136321936Shselasky int agent, vers; 137321936Shselasky 138321936Shselasky if (method_mask) 139321936Shselasky memcpy(class_method_mask, method_mask, 140321936Shselasky sizeof class_method_mask); 141321936Shselasky else 142321936Shselasky memset(class_method_mask, 0xff, sizeof(class_method_mask)); 143321936Shselasky 144321936Shselasky if (!srcport) 145321936Shselasky return -1; 146321936Shselasky 147321936Shselasky if (srcport->class_agents[mgmt] >= 0) { 148321936Shselasky DEBUG("Class 0x%x already registered %d", 149321936Shselasky mgmt, srcport->class_agents[mgmt]); 150321936Shselasky return -1; 151321936Shselasky } 152321936Shselasky if ((vers = mgmt_class_vers(mgmt)) <= 0) { 153321936Shselasky DEBUG("Unknown class 0x%x mgmt_class", mgmt); 154321936Shselasky return -1; 155321936Shselasky } 156321936Shselasky if (mgmt >= IB_VENDOR_RANGE2_START_CLASS && 157321936Shselasky mgmt <= IB_VENDOR_RANGE2_END_CLASS) { 158321936Shselasky oui[0] = (class_oui >> 16) & 0xff; 159321936Shselasky oui[1] = (class_oui >> 8) & 0xff; 160321936Shselasky oui[2] = class_oui & 0xff; 161321936Shselasky if ((agent = 162321936Shselasky umad_register_oui(srcport->port_id, mgmt, rmpp_version, 163321936Shselasky oui, class_method_mask)) < 0) { 164321936Shselasky DEBUG("Can't register agent for class %d", mgmt); 165321936Shselasky return -1; 166321936Shselasky } 167321936Shselasky } else 168321936Shselasky if ((agent = 169321936Shselasky umad_register(srcport->port_id, mgmt, vers, rmpp_version, 170321936Shselasky class_method_mask)) < 0) { 171321936Shselasky DEBUG("Can't register agent for class %d", mgmt); 172321936Shselasky return -1; 173321936Shselasky } 174321936Shselasky 175321936Shselasky srcport->class_agents[mgmt] = agent; 176321936Shselasky 177321936Shselasky return agent; 178321936Shselasky} 179