1321936Shselasky/* 2321936Shselasky * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 3321936Shselasky * Copyright (c) 2002-2005,2008 Mellanox Technologies LTD. All rights reserved. 4321936Shselasky * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5321936Shselasky * Copyright (c) 2009 HNR Consulting. All rights reserved. 6321936Shselasky * 7321936Shselasky * This software is available to you under a choice of one of two 8321936Shselasky * licenses. You may choose to be licensed under the terms of the GNU 9321936Shselasky * General Public License (GPL) Version 2, available from the file 10321936Shselasky * COPYING in the main directory of this source tree, or the 11321936Shselasky * OpenIB.org BSD license below: 12321936Shselasky * 13321936Shselasky * Redistribution and use in source and binary forms, with or 14321936Shselasky * without modification, are permitted provided that the following 15321936Shselasky * conditions are met: 16321936Shselasky * 17321936Shselasky * - Redistributions of source code must retain the above 18321936Shselasky * copyright notice, this list of conditions and the following 19321936Shselasky * disclaimer. 20321936Shselasky * 21321936Shselasky * - Redistributions in binary form must reproduce the above 22321936Shselasky * copyright notice, this list of conditions and the following 23321936Shselasky * disclaimer in the documentation and/or other materials 24321936Shselasky * provided with the distribution. 25321936Shselasky * 26321936Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27321936Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28321936Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29321936Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30321936Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31321936Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32321936Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33321936Shselasky * SOFTWARE. 34321936Shselasky * 35321936Shselasky */ 36321936Shselasky 37321936Shselasky/* 38321936Shselasky * Abstract: 39321936Shselasky * Implementation of osm_si_rcv_t. 40321936Shselasky * This object represents the SwitchInfo Receiver object. 41321936Shselasky * This object is part of the opensm family of objects. 42321936Shselasky */ 43321936Shselasky 44321936Shselasky#if HAVE_CONFIG_H 45321936Shselasky# include <config.h> 46321936Shselasky#endif /* HAVE_CONFIG_H */ 47321936Shselasky 48321936Shselasky#include <string.h> 49321936Shselasky#include <iba/ib_types.h> 50321936Shselasky#include <complib/cl_qmap.h> 51321936Shselasky#include <complib/cl_passivelock.h> 52321936Shselasky#include <complib/cl_debug.h> 53321936Shselasky#include <opensm/osm_file_ids.h> 54321936Shselasky#define FILE_ID OSM_FILE_SW_INFO_RCV_C 55321936Shselasky#include <opensm/osm_log.h> 56321936Shselasky#include <opensm/osm_switch.h> 57321936Shselasky#include <opensm/osm_subnet.h> 58321936Shselasky#include <opensm/osm_helper.h> 59321936Shselasky#include <opensm/osm_opensm.h> 60321936Shselasky 61321936Shselasky#if 0 62321936Shselasky/********************************************************************** 63321936Shselasky The plock must be held before calling this function. 64321936Shselasky**********************************************************************/ 65321936Shselaskystatic void si_rcv_get_fwd_tbl(IN osm_sm_t * sm, IN osm_switch_t * p_sw) 66321936Shselasky{ 67321936Shselasky osm_madw_context_t context; 68321936Shselasky osm_dr_path_t *p_dr_path; 69321936Shselasky osm_physp_t *p_physp; 70321936Shselasky osm_node_t *p_node; 71321936Shselasky uint32_t block_id_ho; 72321936Shselasky uint32_t max_block_id_ho; 73321936Shselasky ib_api_status_t status = IB_SUCCESS; 74321936Shselasky 75321936Shselasky OSM_LOG_ENTER(sm->p_log); 76321936Shselasky 77321936Shselasky CL_ASSERT(p_sw); 78321936Shselasky 79321936Shselasky p_node = p_sw->p_node; 80321936Shselasky 81321936Shselasky CL_ASSERT(osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH); 82321936Shselasky 83321936Shselasky context.lft_context.node_guid = osm_node_get_node_guid(p_node); 84321936Shselasky context.lft_context.set_method = FALSE; 85321936Shselasky 86321936Shselasky max_block_id_ho = osm_switch_get_max_block_id_in_use(p_sw); 87321936Shselasky 88321936Shselasky p_physp = osm_node_get_physp_ptr(p_node, 0); 89321936Shselasky p_dr_path = osm_physp_get_dr_path_ptr(p_physp); 90321936Shselasky 91321936Shselasky for (block_id_ho = 0; block_id_ho <= max_block_id_ho; block_id_ho++) { 92321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 93321936Shselasky "Retrieving FT block %u\n", block_id_ho); 94321936Shselasky 95321936Shselasky status = osm_req_get(sm, p_dr_path, IB_MAD_ATTR_LIN_FWD_TBL, 96321936Shselasky cl_hton32(block_id_ho), TRUE, 0, 97321936Shselasky CL_DISP_MSGID_NONE, &context); 98321936Shselasky if (status != IB_SUCCESS) 99321936Shselasky /* continue the loop despite the error */ 100321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3603: " 101321936Shselasky "Failure initiating PortInfo request (%s)\n", 102321936Shselasky ib_get_err_str(status)); 103321936Shselasky } 104321936Shselasky 105321936Shselasky OSM_LOG_EXIT(sm->p_log); 106321936Shselasky} 107321936Shselasky 108321936Shselasky/********************************************************************** 109321936Shselasky The plock must be held before calling this function. 110321936Shselasky**********************************************************************/ 111321936Shselaskystatic void si_rcv_get_mcast_fwd_tbl(IN osm_sm_t * sm, IN osm_switch_t * p_sw) 112321936Shselasky{ 113321936Shselasky osm_madw_context_t context; 114321936Shselasky osm_dr_path_t *p_dr_path; 115321936Shselasky osm_physp_t *p_physp; 116321936Shselasky osm_node_t *p_node; 117321936Shselasky osm_mcast_tbl_t *p_tbl; 118321936Shselasky uint32_t block_id_ho; 119321936Shselasky uint32_t max_block_id_ho; 120321936Shselasky uint32_t position; 121321936Shselasky uint32_t max_position; 122321936Shselasky uint32_t attr_mod_ho; 123321936Shselasky ib_api_status_t status = IB_SUCCESS; 124321936Shselasky 125321936Shselasky OSM_LOG_ENTER(sm->p_log); 126321936Shselasky 127321936Shselasky CL_ASSERT(p_sw); 128321936Shselasky 129321936Shselasky p_node = p_sw->p_node; 130321936Shselasky 131321936Shselasky CL_ASSERT(osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH); 132321936Shselasky 133321936Shselasky if (osm_switch_get_mcast_fwd_tbl_size(p_sw) == 0) { 134321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 135321936Shselasky "Multicast not supported by switch 0x%016" PRIx64 "\n", 136321936Shselasky cl_ntoh64(osm_node_get_node_guid(p_node))); 137321936Shselasky goto Exit; 138321936Shselasky } 139321936Shselasky 140321936Shselasky context.mft_context.node_guid = osm_node_get_node_guid(p_node); 141321936Shselasky context.mft_context.set_method = FALSE; 142321936Shselasky 143321936Shselasky p_tbl = osm_switch_get_mcast_tbl_ptr(p_sw); 144321936Shselasky max_block_id_ho = osm_mcast_tbl_get_max_block(p_tbl); 145321936Shselasky 146321936Shselasky if (max_block_id_ho > IB_MCAST_MAX_BLOCK_ID) { 147321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3609: " 148321936Shselasky "Out-of-range mcast block size = %u on switch 0x%016" 149321936Shselasky PRIx64 "\n", max_block_id_ho, 150321936Shselasky cl_ntoh64(osm_node_get_node_guid(p_node))); 151321936Shselasky goto Exit; 152321936Shselasky } 153321936Shselasky 154321936Shselasky max_position = osm_mcast_tbl_get_max_position(p_tbl); 155321936Shselasky 156321936Shselasky CL_ASSERT(max_position <= IB_MCAST_POSITION_MAX); 157321936Shselasky 158321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 159321936Shselasky "Max MFT block = %u, Max position = %u\n", max_block_id_ho, 160321936Shselasky max_position); 161321936Shselasky 162321936Shselasky p_physp = osm_node_get_physp_ptr(p_node, 0); 163321936Shselasky p_dr_path = osm_physp_get_dr_path_ptr(p_physp); 164321936Shselasky 165321936Shselasky for (block_id_ho = 0; block_id_ho <= max_block_id_ho; block_id_ho++) { 166321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 167321936Shselasky "Retrieving MFT block %u\n", block_id_ho); 168321936Shselasky 169321936Shselasky for (position = 0; position <= max_position; position++) { 170321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 171321936Shselasky "Retrieving MFT position %u\n", position); 172321936Shselasky 173321936Shselasky attr_mod_ho = 174321936Shselasky block_id_ho | position << IB_MCAST_POSITION_SHIFT; 175321936Shselasky status = 176321936Shselasky osm_req_get(sm, p_dr_path, 177321936Shselasky IB_MAD_ATTR_MCAST_FWD_TBL, 178321936Shselasky cl_hton32(attr_mod_ho), TRUE, 0, 179321936Shselasky CL_DISP_MSGID_NONE, &context); 180321936Shselasky if (status != IB_SUCCESS) 181321936Shselasky /* continue the loop despite the error */ 182321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3607: " 183321936Shselasky "Failure initiating PortInfo request (%s)\n", 184321936Shselasky ib_get_err_str(status)); 185321936Shselasky } 186321936Shselasky } 187321936Shselasky 188321936ShselaskyExit: 189321936Shselasky OSM_LOG_EXIT(sm->p_log); 190321936Shselasky} 191321936Shselasky#endif 192321936Shselasky 193321936Shselasky/********************************************************************** 194321936Shselasky Lock must be held on entry to this function. 195321936Shselasky**********************************************************************/ 196321936Shselaskystatic void si_rcv_process_new(IN osm_sm_t * sm, IN osm_node_t * p_node, 197321936Shselasky IN const osm_madw_t * p_madw) 198321936Shselasky{ 199321936Shselasky osm_switch_t *p_sw; 200321936Shselasky osm_switch_t *p_check; 201321936Shselasky ib_switch_info_t *p_si; 202321936Shselasky ib_smp_t *p_smp; 203321936Shselasky cl_qmap_t *p_sw_guid_tbl; 204321936Shselasky 205321936Shselasky CL_ASSERT(sm); 206321936Shselasky 207321936Shselasky OSM_LOG_ENTER(sm->p_log); 208321936Shselasky 209321936Shselasky CL_ASSERT(p_madw); 210321936Shselasky 211321936Shselasky p_sw_guid_tbl = &sm->p_subn->sw_guid_tbl; 212321936Shselasky p_smp = osm_madw_get_smp_ptr(p_madw); 213321936Shselasky p_si = ib_smp_get_payload_ptr(p_smp); 214321936Shselasky 215321936Shselasky osm_dump_switch_info_v2(sm->p_log, p_si, FILE_ID, OSM_LOG_DEBUG); 216321936Shselasky 217321936Shselasky p_sw = osm_switch_new(p_node, p_madw); 218321936Shselasky if (p_sw == NULL) { 219321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3608: " 220321936Shselasky "Unable to allocate new switch object\n"); 221321936Shselasky goto Exit; 222321936Shselasky } 223321936Shselasky 224321936Shselasky /* set subnet max mlid to the minimum MulticastFDBCap of all switches */ 225321936Shselasky if (p_si->mcast_cap && 226321936Shselasky cl_ntoh16(p_si->mcast_cap) + IB_LID_MCAST_START_HO - 1 < 227321936Shselasky sm->p_subn->max_mcast_lid_ho) { 228321936Shselasky sm->p_subn->max_mcast_lid_ho = cl_ntoh16(p_si->mcast_cap) + 229321936Shselasky IB_LID_MCAST_START_HO - 1; 230321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_VERBOSE, 231321936Shselasky "Subnet max multicast lid is 0x%X\n", 232321936Shselasky sm->p_subn->max_mcast_lid_ho); 233321936Shselasky } 234321936Shselasky 235321936Shselasky /* set subnet max unicast lid to the minimum LinearFDBCap of all switches */ 236321936Shselasky if (cl_ntoh16(p_si->lin_cap) < sm->p_subn->max_ucast_lid_ho) { 237321936Shselasky sm->p_subn->max_ucast_lid_ho = cl_ntoh16(p_si->lin_cap); 238321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_VERBOSE, 239321936Shselasky "Subnet max unicast lid is 0x%X\n", 240321936Shselasky sm->p_subn->max_ucast_lid_ho); 241321936Shselasky } 242321936Shselasky 243321936Shselasky p_check = (osm_switch_t *) cl_qmap_insert(p_sw_guid_tbl, 244321936Shselasky osm_node_get_node_guid 245321936Shselasky (p_node), &p_sw->map_item); 246321936Shselasky if (p_check != p_sw) { 247321936Shselasky /* This shouldn't happen since we hold the lock! */ 248321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3605: " 249321936Shselasky "Unable to add new switch object to database\n"); 250321936Shselasky osm_switch_delete(&p_sw); 251321936Shselasky goto Exit; 252321936Shselasky } 253321936Shselasky 254321936Shselasky p_node->sw = p_sw; 255321936Shselasky 256321936Shselasky /* Update the switch info according to the info we just received. */ 257321936Shselasky osm_switch_set_switch_info(p_sw, p_si); 258321936Shselasky 259321936Shselasky#if 0 260321936Shselasky /* Don't bother retrieving the current unicast and multicast tables 261321936Shselasky from the switches. The current version of SM does 262321936Shselasky not support silent take-over of an existing multicast 263321936Shselasky configuration. 264321936Shselasky 265321936Shselasky Gathering the multicast tables can also generate large amounts 266321936Shselasky of extra subnet-init traffic. 267321936Shselasky 268321936Shselasky The code to retrieve the tables was fully debugged. */ 269321936Shselasky 270321936Shselasky si_rcv_get_fwd_tbl(sm, p_sw); 271321936Shselasky if (!sm->p_subn->opt.disable_multicast) 272321936Shselasky si_rcv_get_mcast_fwd_tbl(sm, p_sw); 273321936Shselasky#endif 274321936Shselasky 275321936ShselaskyExit: 276321936Shselasky OSM_LOG_EXIT(sm->p_log); 277321936Shselasky} 278321936Shselasky 279321936Shselasky/********************************************************************** 280321936Shselasky Lock must be held on entry to this function. 281321936Shselasky Return 1 if the caller is expected to send a change_detected event. 282321936Shselasky this can not be done internally as the event needs the lock... 283321936Shselasky**********************************************************************/ 284321936Shselaskystatic boolean_t si_rcv_process_existing(IN osm_sm_t * sm, 285321936Shselasky IN osm_node_t * p_node, 286321936Shselasky IN const osm_madw_t * p_madw) 287321936Shselasky{ 288321936Shselasky osm_switch_t *p_sw = p_node->sw; 289321936Shselasky ib_switch_info_t *p_si; 290321936Shselasky osm_si_context_t *p_si_context; 291321936Shselasky ib_smp_t *p_smp; 292321936Shselasky osm_epi_lft_change_event_t lft_change; 293321936Shselasky boolean_t is_change_detected = FALSE; 294321936Shselasky 295321936Shselasky OSM_LOG_ENTER(sm->p_log); 296321936Shselasky 297321936Shselasky CL_ASSERT(p_madw); 298321936Shselasky 299321936Shselasky p_smp = osm_madw_get_smp_ptr(p_madw); 300321936Shselasky p_si = ib_smp_get_payload_ptr(p_smp); 301321936Shselasky p_si_context = osm_madw_get_si_context_ptr(p_madw); 302321936Shselasky 303321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Received logical %cetResp()\n", 304321936Shselasky p_si_context->set_method ? 'S' : 'G'); 305321936Shselasky 306321936Shselasky osm_switch_set_switch_info(p_sw, p_si); 307321936Shselasky 308321936Shselasky if (p_si_context->light_sweep == TRUE && !p_si_context->set_method) { 309321936Shselasky /* If state changed bit is on the mad was returned with an 310321936Shselasky error - signal a change to the state manager. */ 311321936Shselasky if (ib_smp_get_status(p_smp) != 0) { 312321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_VERBOSE, 313321936Shselasky "GetResp() received with error in light sweep. " 314321936Shselasky "Commencing heavy sweep\n"); 315321936Shselasky is_change_detected = TRUE; 316321936Shselasky } else if (ib_switch_info_get_state_change(p_si)) { 317321936Shselasky osm_dump_switch_info_v2(sm->p_log, p_si, FILE_ID, OSM_LOG_DEBUG); 318321936Shselasky is_change_detected = TRUE; 319321936Shselasky } 320321936Shselasky } 321321936Shselasky 322321936Shselasky if (sm->p_subn->first_time_master_sweep == FALSE && 323321936Shselasky p_si_context->set_method && p_si_context->lft_top_change) { 324321936Shselasky lft_change.p_sw = p_sw; 325321936Shselasky lft_change.flags = LFT_CHANGED_LFT_TOP; 326321936Shselasky lft_change.lft_top = cl_ntoh16(p_si->lin_top); 327321936Shselasky lft_change.block_num = 0; 328321936Shselasky osm_opensm_report_event(sm->p_subn->p_osm, 329321936Shselasky OSM_EVENT_ID_LFT_CHANGE, 330321936Shselasky &lft_change); 331321936Shselasky } 332321936Shselasky 333321936Shselasky OSM_LOG_EXIT(sm->p_log); 334321936Shselasky return is_change_detected; 335321936Shselasky} 336321936Shselasky 337321936Shselaskystatic void si_rcv_get_sp0_info(IN osm_sm_t * sm, IN osm_node_t * node) 338321936Shselasky{ 339321936Shselasky osm_madw_context_t context; 340321936Shselasky osm_physp_t *physp; 341321936Shselasky ib_api_status_t status; 342321936Shselasky int mlnx_epi_supported = 0; 343321936Shselasky 344321936Shselasky physp = osm_node_get_physp_ptr(node, 0); 345321936Shselasky 346321936Shselasky context.pi_context.node_guid = osm_node_get_node_guid(node); 347321936Shselasky context.pi_context.port_guid = osm_physp_get_port_guid(physp); 348321936Shselasky context.pi_context.set_method = FALSE; 349321936Shselasky context.pi_context.light_sweep = FALSE; 350321936Shselasky context.pi_context.active_transition = FALSE; 351321936Shselasky context.pi_context.client_rereg = FALSE; 352321936Shselasky 353321936Shselasky status = osm_req_get(sm, osm_physp_get_dr_path_ptr(physp), 354321936Shselasky IB_MAD_ATTR_PORT_INFO, 0, TRUE, 0, 355321936Shselasky CL_DISP_MSGID_NONE, &context); 356321936Shselasky if (status != IB_SUCCESS) 357321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3611: " 358321936Shselasky "Failure initiating PortInfo request (%s)\n", 359321936Shselasky ib_get_err_str(status)); 360321936Shselasky 361321936Shselasky if (ib_switch_info_is_enhanced_port0(&node->sw->switch_info) && 362321936Shselasky sm->p_subn->opt.fdr10) { 363321936Shselasky mlnx_epi_supported = is_mlnx_ext_port_info_supported( 364321936Shselasky ib_node_info_get_vendor_id(&node->node_info), 365321936Shselasky node->node_info.device_id); 366321936Shselasky if (mlnx_epi_supported) { 367321936Shselasky status = osm_req_get(sm, 368321936Shselasky osm_physp_get_dr_path_ptr(physp), 369321936Shselasky IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO, 370321936Shselasky 0, TRUE, 0, 371321936Shselasky CL_DISP_MSGID_NONE, &context); 372321936Shselasky if (status != IB_SUCCESS) 373321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3616: " 374321936Shselasky "Failure initiating MLNX ExtPortInfo request (%s)\n", 375321936Shselasky ib_get_err_str(status)); 376321936Shselasky } 377321936Shselasky } 378321936Shselasky 379321936Shselasky} 380321936Shselasky 381321936Shselaskyvoid osm_si_rcv_process(IN void *context, IN void *data) 382321936Shselasky{ 383321936Shselasky osm_sm_t *sm = context; 384321936Shselasky osm_madw_t *p_madw = data; 385321936Shselasky ib_switch_info_t *p_si; 386321936Shselasky ib_smp_t *p_smp; 387321936Shselasky osm_node_t *p_node; 388321936Shselasky ib_net64_t node_guid; 389321936Shselasky osm_si_context_t *p_context; 390321936Shselasky 391321936Shselasky CL_ASSERT(sm); 392321936Shselasky 393321936Shselasky OSM_LOG_ENTER(sm->p_log); 394321936Shselasky 395321936Shselasky CL_ASSERT(p_madw); 396321936Shselasky 397321936Shselasky p_smp = osm_madw_get_smp_ptr(p_madw); 398321936Shselasky p_si = ib_smp_get_payload_ptr(p_smp); 399321936Shselasky p_context = osm_madw_get_si_context_ptr(p_madw); 400321936Shselasky node_guid = p_context->node_guid; 401321936Shselasky 402321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 403321936Shselasky "Switch GUID 0x%016" PRIx64 ", TID 0x%" PRIx64 "\n", 404321936Shselasky cl_ntoh64(node_guid), cl_ntoh64(p_smp->trans_id)); 405321936Shselasky 406321936Shselasky if (ib_smp_get_status(p_smp)) { 407321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 408321936Shselasky "MAD status 0x%x received\n", 409321936Shselasky cl_ntoh16(ib_smp_get_status(p_smp))); 410321936Shselasky goto Exit2; 411321936Shselasky } 412321936Shselasky 413321936Shselasky CL_PLOCK_EXCL_ACQUIRE(sm->p_lock); 414321936Shselasky 415321936Shselasky p_node = osm_get_node_by_guid(sm->p_subn, node_guid); 416321936Shselasky if (!p_node) { 417321936Shselasky CL_PLOCK_RELEASE(sm->p_lock); 418321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3606: " 419321936Shselasky "SwitchInfo received for nonexistent node " 420321936Shselasky "with GUID 0x%" PRIx64 "\n", cl_ntoh64(node_guid)); 421321936Shselasky goto Exit; 422321936Shselasky } 423321936Shselasky 424321936Shselasky /* Hack for bad value in Mellanox switch */ 425321936Shselasky if (cl_ntoh16(p_si->lin_top) > IB_LID_UCAST_END_HO) { 426321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3610: " 427321936Shselasky "\n\t\t\t\tBad LinearFDBTop value = 0x%X " 428321936Shselasky "on switch 0x%" PRIx64 429321936Shselasky "\n\t\t\t\tForcing internal correction to 0x%X\n", 430321936Shselasky cl_ntoh16(p_si->lin_top), 431321936Shselasky cl_ntoh64(osm_node_get_node_guid(p_node)), 0); 432321936Shselasky p_si->lin_top = 0; 433321936Shselasky } 434321936Shselasky 435321936Shselasky /* Acquire the switch object for this switch. */ 436321936Shselasky if (!p_node->sw) { 437321936Shselasky si_rcv_process_new(sm, p_node, p_madw); 438321936Shselasky /* A new switch was found during the sweep so we need 439321936Shselasky to ignore the current LFT settings. */ 440321936Shselasky sm->p_subn->ignore_existing_lfts = TRUE; 441321936Shselasky } else if (si_rcv_process_existing(sm, p_node, p_madw)) 442321936Shselasky /* we might get back a request for signaling change was detected */ 443321936Shselasky sm->p_subn->force_heavy_sweep = TRUE; 444321936Shselasky 445321936Shselasky if (p_context->light_sweep || p_context->set_method) 446321936Shselasky goto Exit; 447321936Shselasky 448321936Shselasky si_rcv_get_sp0_info(sm, p_node); 449321936Shselasky 450321936ShselaskyExit: 451321936Shselasky CL_PLOCK_RELEASE(sm->p_lock); 452321936ShselaskyExit2: 453321936Shselasky OSM_LOG_EXIT(sm->p_log); 454321936Shselasky} 455