1/* 2 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5 * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved. 6 * 7 * This software is available to you under a choice of one of two 8 * licenses. You may choose to be licensed under the terms of the GNU 9 * General Public License (GPL) Version 2, available from the file 10 * COPYING in the main directory of this source tree, or the 11 * OpenIB.org BSD license below: 12 * 13 * Redistribution and use in source and binary forms, with or 14 * without modification, are permitted provided that the following 15 * conditions are met: 16 * 17 * - Redistributions of source code must retain the above 18 * copyright notice, this list of conditions and the following 19 * disclaimer. 20 * 21 * - Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials 24 * provided with the distribution. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 * SOFTWARE. 34 * 35 */ 36 37/* 38 * Abstract: 39 * Implementation of osm_mft_rcv_t. 40 * This object represents the Multicast Forwarding Table Receiver object. 41 * This object is part of the opensm family of objects. 42 */ 43 44#if HAVE_CONFIG_H 45# include <config.h> 46#endif /* HAVE_CONFIG_H */ 47 48#include <string.h> 49#include <iba/ib_types.h> 50#include <complib/cl_qmap.h> 51#include <complib/cl_passivelock.h> 52#include <complib/cl_debug.h> 53#include <opensm/osm_file_ids.h> 54#define FILE_ID OSM_FILE_MCAST_FWD_RCV_C 55#include <opensm/osm_madw.h> 56#include <opensm/osm_log.h> 57#include <opensm/osm_switch.h> 58#include <opensm/osm_subnet.h> 59#include <opensm/osm_sm.h> 60 61void osm_mft_rcv_process(IN void *context, IN void *data) 62{ 63 osm_sm_t *sm = context; 64 osm_madw_t *p_madw = data; 65 ib_smp_t *p_smp; 66 uint32_t block_num; 67 uint8_t position; 68 osm_switch_t *p_sw; 69 osm_mft_context_t *p_mft_context; 70 uint16_t *p_block; 71 ib_net64_t node_guid; 72 ib_api_status_t status; 73 74 CL_ASSERT(sm); 75 76 OSM_LOG_ENTER(sm->p_log); 77 78 CL_ASSERT(p_madw); 79 80 p_smp = osm_madw_get_smp_ptr(p_madw); 81 p_block = ib_smp_get_payload_ptr(p_smp); 82 block_num = cl_ntoh32(p_smp->attr_mod) & IB_MCAST_BLOCK_ID_MASK_HO; 83 position = (uint8_t) ((cl_ntoh32(p_smp->attr_mod) & 84 IB_MCAST_POSITION_MASK_HO) >> 85 IB_MCAST_POSITION_SHIFT); 86 87 /* 88 Acquire the switch object for this switch. 89 */ 90 p_mft_context = osm_madw_get_mft_context_ptr(p_madw); 91 node_guid = p_mft_context->node_guid; 92 93 OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 94 "Setting MFT block %u, position %u, " 95 "Switch 0x%016" PRIx64 ", TID 0x%" PRIx64 "\n", 96 block_num, position, cl_ntoh64(node_guid), 97 cl_ntoh64(p_smp->trans_id)); 98 99 if (ib_smp_get_status(p_smp)) { 100 OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 101 "MAD status 0x%x received\n", 102 cl_ntoh16(ib_smp_get_status(p_smp))); 103 goto Exit; 104 } 105 106 CL_PLOCK_EXCL_ACQUIRE(sm->p_lock); 107 p_sw = osm_get_switch_by_guid(sm->p_subn, node_guid); 108 109 if (!p_sw) { 110 OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0801: " 111 "MFT received for nonexistent node " 112 "0x%016" PRIx64 "\n", cl_ntoh64(node_guid)); 113 } else { 114 status = osm_switch_set_mft_block(p_sw, p_block, 115 (uint16_t) block_num, 116 position); 117 if (status != IB_SUCCESS) { 118 OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0802: " 119 "Setting MFT block failed (%s)" 120 ", Switch 0x%016" PRIx64 121 " (%s), block %u, position %u\n", 122 ib_get_err_str(status), cl_ntoh64(node_guid), 123 p_sw->p_node->print_desc, block_num, position); 124 } 125 } 126 127 CL_PLOCK_RELEASE(sm->p_lock); 128Exit: 129 OSM_LOG_EXIT(sm->p_log); 130} 131