| /* | |
| * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved. | |
| * | |
| * This software is available to you under a choice of one of two | |
| * licenses. You may choose to be licensed under the terms of the GNU | |
| * General Public License (GPL) Version 2, available from the file | |
| * COPYING in the main directory of this source tree, or the | |
| * OpenIB.org BSD license below: | |
| * | |
| * Redistribution and use in source and binary forms, with or | |
| * without modification, are permitted provided that the following | |
| * conditions are met: | |
| * | |
| * - Redistributions of source code must retain the above | |
| * copyright notice, this list of conditions and the following | |
| * disclaimer. | |
| * | |
| * - Redistributions in binary form must reproduce the above | |
| * copyright notice, this list of conditions and the following | |
| * disclaimer in the documentation and/or other materials | |
| * provided with the distribution. | |
| * | |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| * SOFTWARE. | |
| * | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <errno.h> | |
| #include <infiniband/umad.h> | |
| #include <infiniband/mad.h> | |
| #include "mad_internal.h" | |
| #undef DEBUG | |
| #define DEBUG if (ibdebug) IBWARN | |
| static int mgmt_class_vers(int mgmt_class) | |
| { | |
| if ((mgmt_class >= IB_VENDOR_RANGE1_START_CLASS && | |
| mgmt_class <= IB_VENDOR_RANGE1_END_CLASS) || | |
| (mgmt_class >= IB_VENDOR_RANGE2_START_CLASS && | |
| mgmt_class <= IB_VENDOR_RANGE2_END_CLASS)) | |
| return 1; | |
| switch (mgmt_class) { | |
| case IB_SMI_CLASS: | |
| case IB_SMI_DIRECT_CLASS: | |
| return 1; | |
| case IB_SA_CLASS: | |
| return 2; | |
| case IB_PERFORMANCE_CLASS: | |
| return 1; | |
| case IB_DEVICE_MGMT_CLASS: | |
| return 1; | |
| case IB_CC_CLASS: | |
| return 2; | |
| case IB_BOARD_MGMT_CLASS: | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| int mad_class_agent(int mgmt) | |
| { | |
| if (mgmt < 1 || mgmt >= MAX_CLASS) | |
| return -1; | |
| return ibmp->class_agents[mgmt]; | |
| } | |
| static int mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version) | |
| { | |
| int vers, agent; | |
| if ((vers = mgmt_class_vers(mgmt)) <= 0) { | |
| DEBUG("Unknown class %d mgmt_class", mgmt); | |
| return -1; | |
| } | |
| agent = umad_register(port_id, mgmt, vers, rmpp_version, NULL); | |
| if (agent < 0) | |
| DEBUG("Can't register agent for class %d", mgmt); | |
| return agent; | |
| } | |
| int mad_register_client(int mgmt, uint8_t rmpp_version) | |
| { | |
| return mad_register_client_via(mgmt, rmpp_version, ibmp); | |
| } | |
| int mad_register_client_via(int mgmt, uint8_t rmpp_version, | |
| struct ibmad_port *srcport) | |
| { | |
| int agent; | |
| if (!srcport) | |
| return -1; | |
| agent = mad_register_port_client(mad_rpc_portid(srcport), mgmt, | |
| rmpp_version); | |
| if (agent < 0) | |
| return agent; | |
| srcport->class_agents[mgmt] = agent; | |
| return 0; | |
| } | |
| int mad_register_server(int mgmt, uint8_t rmpp_version, | |
| long method_mask[16 / sizeof(long)], uint32_t class_oui) | |
| { | |
| return mad_register_server_via(mgmt, rmpp_version, method_mask, | |
| class_oui, ibmp); | |
| } | |
| int mad_register_server_via(int mgmt, uint8_t rmpp_version, | |
| long method_mask[16 / sizeof(long)], | |
| uint32_t class_oui, struct ibmad_port *srcport) | |
| { | |
| long class_method_mask[16 / sizeof(long)]; | |
| uint8_t oui[3]; | |
| int agent, vers; | |
| if (method_mask) | |
| memcpy(class_method_mask, method_mask, | |
| sizeof class_method_mask); | |
| else | |
| memset(class_method_mask, 0xff, sizeof(class_method_mask)); | |
| if (!srcport) | |
| return -1; | |
| if (srcport->class_agents[mgmt] >= 0) { | |
| DEBUG("Class 0x%x already registered %d", | |
| mgmt, srcport->class_agents[mgmt]); | |
| return -1; | |
| } | |
| if ((vers = mgmt_class_vers(mgmt)) <= 0) { | |
| DEBUG("Unknown class 0x%x mgmt_class", mgmt); | |
| return -1; | |
| } | |
| if (mgmt >= IB_VENDOR_RANGE2_START_CLASS && | |
| mgmt <= IB_VENDOR_RANGE2_END_CLASS) { | |
| oui[0] = (class_oui >> 16) & 0xff; | |
| oui[1] = (class_oui >> 8) & 0xff; | |
| oui[2] = class_oui & 0xff; | |
| if ((agent = | |
| umad_register_oui(srcport->port_id, mgmt, rmpp_version, | |
| oui, class_method_mask)) < 0) { | |
| DEBUG("Can't register agent for class %d", mgmt); | |
| return -1; | |
| } | |
| } else | |
| if ((agent = | |
| umad_register(srcport->port_id, mgmt, vers, rmpp_version, | |
| class_method_mask)) < 0) { | |
| DEBUG("Can't register agent for class %d", mgmt); | |
| return -1; | |
| } | |
| srcport->class_agents[mgmt] = agent; | |
| return agent; | |
| } |