1321936Shselasky/* 2321936Shselasky * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 3321936Shselasky * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved. 4321936Shselasky * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5321936Shselasky * Copyright (c) 2008 Xsigo Systems Inc. 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_sm_t. 40321936Shselasky * This object represents the SM 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 <stdlib.h> 49321936Shselasky#include <string.h> 50321936Shselasky#include <iba/ib_types.h> 51321936Shselasky#include <complib/cl_qmap.h> 52321936Shselasky#include <complib/cl_passivelock.h> 53321936Shselasky#include <complib/cl_debug.h> 54321936Shselasky#include <complib/cl_thread.h> 55321936Shselasky#include <opensm/osm_file_ids.h> 56321936Shselasky#define FILE_ID OSM_FILE_SM_C 57321936Shselasky#include <opensm/osm_sm.h> 58321936Shselasky#include <opensm/osm_madw.h> 59321936Shselasky#include <opensm/osm_log.h> 60321936Shselasky#include <opensm/osm_node.h> 61321936Shselasky#include <opensm/osm_msgdef.h> 62321936Shselasky#include <opensm/osm_perfmgr.h> 63321936Shselasky#include <opensm/osm_opensm.h> 64321936Shselasky 65321936Shselasky#define OSM_SM_INITIAL_TID_VALUE 0x1233 66321936Shselasky 67321936Shselaskyextern void osm_lft_rcv_process(IN void *context, IN void *data); 68321936Shselaskyextern void osm_mft_rcv_process(IN void *context, IN void *data); 69321936Shselaskyextern void osm_nd_rcv_process(IN void *context, IN void *data); 70321936Shselaskyextern void osm_ni_rcv_process(IN void *context, IN void *data); 71321936Shselaskyextern void osm_pkey_rcv_process(IN void *context, IN void *data); 72321936Shselaskyextern void osm_pi_rcv_process(IN void *context, IN void *data); 73321936Shselaskyextern void osm_gi_rcv_process(IN void *context, IN void *data); 74321936Shselaskyextern void osm_slvl_rcv_process(IN void *context, IN void *p_data); 75321936Shselaskyextern void osm_sminfo_rcv_process(IN void *context, IN void *data); 76321936Shselaskyextern void osm_si_rcv_process(IN void *context, IN void *data); 77321936Shselaskyextern void osm_trap_rcv_process(IN void *context, IN void *data); 78321936Shselaskyextern void osm_vla_rcv_process(IN void *context, IN void *data); 79321936Shselaskyextern void osm_mlnx_epi_rcv_process(IN void *context, IN void *data); 80321936Shselasky 81321936Shselaskyextern void osm_state_mgr_process(IN osm_sm_t * sm, IN osm_signal_t signal); 82321936Shselaskyextern void osm_sm_state_mgr_polling_callback(IN void *context); 83321936Shselasky 84321936Shselaskystatic void sm_process(osm_sm_t * sm, osm_signal_t signal) 85321936Shselasky{ 86321936Shselasky#ifdef ENABLE_OSM_PERF_MGR 87321936Shselasky if (signal == OSM_SIGNAL_PERFMGR_SWEEP) 88321936Shselasky osm_perfmgr_process(&sm->p_subn->p_osm->perfmgr); 89321936Shselasky else 90321936Shselasky#endif 91321936Shselasky osm_state_mgr_process(sm, signal); 92321936Shselasky} 93321936Shselasky 94321936Shselaskystatic void sm_sweeper(IN void *p_ptr) 95321936Shselasky{ 96321936Shselasky ib_api_status_t status; 97321936Shselasky osm_sm_t * p_sm = p_ptr; 98321936Shselasky unsigned signals, i; 99321936Shselasky 100321936Shselasky OSM_LOG_ENTER(p_sm->p_log); 101321936Shselasky 102321936Shselasky while (p_sm->thread_state == OSM_THREAD_STATE_RUN) { 103321936Shselasky /* 104321936Shselasky * Wait on the event with a timeout. 105321936Shselasky * Sweeps may be initiated "off schedule" by simply 106321936Shselasky * signaling the event. 107321936Shselasky */ 108321936Shselasky status = cl_event_wait_on(&p_sm->signal_event, 109321936Shselasky EVENT_NO_TIMEOUT, TRUE); 110321936Shselasky 111321936Shselasky if (status == CL_SUCCESS) 112321936Shselasky OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG, 113321936Shselasky "Off schedule sweep signalled\n"); 114321936Shselasky else { 115321936Shselasky OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR 2E01: " 116321936Shselasky "Event wait failed (%s)\n", 117321936Shselasky CL_STATUS_MSG(status)); 118321936Shselasky continue; 119321936Shselasky } 120321936Shselasky 121321936Shselasky if (osm_exit_flag) 122321936Shselasky break; 123321936Shselasky 124321936Shselasky cl_spinlock_acquire(&p_sm->signal_lock); 125321936Shselasky signals = p_sm->signal_mask; 126321936Shselasky p_sm->signal_mask = 0; 127321936Shselasky cl_spinlock_release(&p_sm->signal_lock); 128321936Shselasky 129321936Shselasky for (i = 0; signals; signals >>= 1, i++) 130321936Shselasky if (signals & 1) 131321936Shselasky sm_process(p_sm, i); 132321936Shselasky } 133321936Shselasky 134321936Shselasky OSM_LOG_EXIT(p_sm->p_log); 135321936Shselasky} 136321936Shselasky 137321936Shselaskystatic void sm_sweep(void *arg) 138321936Shselasky{ 139321936Shselasky osm_sm_t *sm = arg; 140321936Shselasky 141321936Shselasky /* do the sweep only if we are in MASTER state */ 142321936Shselasky if (sm->p_subn->sm_state == IB_SMINFO_STATE_MASTER || 143321936Shselasky sm->p_subn->sm_state == IB_SMINFO_STATE_DISCOVERING) 144321936Shselasky osm_sm_signal(sm, OSM_SIGNAL_SWEEP); 145321936Shselasky cl_timer_start(&sm->sweep_timer, sm->p_subn->opt.sweep_interval * 1000); 146321936Shselasky} 147321936Shselasky 148321936Shselaskystatic void sweep_fail_process(IN void *context, IN void *p_data) 149321936Shselasky{ 150321936Shselasky osm_sm_t *sm = context; 151321936Shselasky 152321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "light sweep failed\n"); 153321936Shselasky sm->p_subn->force_heavy_sweep = TRUE; 154321936Shselasky} 155321936Shselasky 156321936Shselaskyvoid osm_sm_construct(IN osm_sm_t * p_sm) 157321936Shselasky{ 158321936Shselasky memset(p_sm, 0, sizeof(*p_sm)); 159321936Shselasky p_sm->thread_state = OSM_THREAD_STATE_NONE; 160321936Shselasky p_sm->sm_trans_id = OSM_SM_INITIAL_TID_VALUE; 161321936Shselasky cl_spinlock_construct(&p_sm->signal_lock); 162321936Shselasky cl_spinlock_construct(&p_sm->state_lock); 163321936Shselasky cl_timer_construct(&p_sm->polling_timer); 164321936Shselasky cl_event_construct(&p_sm->signal_event); 165321936Shselasky cl_event_construct(&p_sm->subnet_up_event); 166321936Shselasky cl_event_wheel_construct(&p_sm->trap_aging_tracker); 167321936Shselasky cl_thread_construct(&p_sm->sweeper); 168321936Shselasky osm_sm_mad_ctrl_construct(&p_sm->mad_ctrl); 169321936Shselasky osm_lid_mgr_construct(&p_sm->lid_mgr); 170321936Shselasky osm_ucast_mgr_construct(&p_sm->ucast_mgr); 171321936Shselasky} 172321936Shselasky 173321936Shselaskyvoid osm_sm_shutdown(IN osm_sm_t * p_sm) 174321936Shselasky{ 175321936Shselasky boolean_t signal_event = FALSE; 176321936Shselasky 177321936Shselasky OSM_LOG_ENTER(p_sm->p_log); 178321936Shselasky 179321936Shselasky /* 180321936Shselasky * Signal our threads that we're leaving. 181321936Shselasky */ 182321936Shselasky if (p_sm->thread_state != OSM_THREAD_STATE_NONE) 183321936Shselasky signal_event = TRUE; 184321936Shselasky 185321936Shselasky p_sm->thread_state = OSM_THREAD_STATE_EXIT; 186321936Shselasky 187321936Shselasky /* 188321936Shselasky * Don't trigger unless event has been initialized. 189321936Shselasky * Destroy the thread before we tear down the other objects. 190321936Shselasky */ 191321936Shselasky if (signal_event) 192321936Shselasky cl_event_signal(&p_sm->signal_event); 193321936Shselasky 194321936Shselasky cl_timer_stop(&p_sm->polling_timer); 195321936Shselasky cl_timer_stop(&p_sm->sweep_timer); 196321936Shselasky cl_thread_destroy(&p_sm->sweeper); 197321936Shselasky 198321936Shselasky /* 199321936Shselasky * Always destroy controllers before the corresponding 200321936Shselasky * receiver to guarantee that all callbacks from the 201321936Shselasky * dispatcher are complete. 202321936Shselasky */ 203321936Shselasky osm_sm_mad_ctrl_destroy(&p_sm->mad_ctrl); 204321936Shselasky cl_disp_unregister(p_sm->ni_disp_h); 205321936Shselasky cl_disp_unregister(p_sm->pi_disp_h); 206321936Shselasky cl_disp_unregister(p_sm->gi_disp_h); 207321936Shselasky cl_disp_unregister(p_sm->si_disp_h); 208321936Shselasky cl_disp_unregister(p_sm->nd_disp_h); 209321936Shselasky cl_disp_unregister(p_sm->lft_disp_h); 210321936Shselasky cl_disp_unregister(p_sm->mft_disp_h); 211321936Shselasky cl_disp_unregister(p_sm->sm_info_disp_h); 212321936Shselasky cl_disp_unregister(p_sm->trap_disp_h); 213321936Shselasky cl_disp_unregister(p_sm->slvl_disp_h); 214321936Shselasky cl_disp_unregister(p_sm->vla_disp_h); 215321936Shselasky cl_disp_unregister(p_sm->pkey_disp_h); 216321936Shselasky cl_disp_unregister(p_sm->mlnx_epi_disp_h); 217321936Shselasky cl_disp_unregister(p_sm->sweep_fail_disp_h); 218321936Shselasky 219321936Shselasky OSM_LOG_EXIT(p_sm->p_log); 220321936Shselasky} 221321936Shselasky 222321936Shselaskyvoid osm_sm_destroy(IN osm_sm_t * p_sm) 223321936Shselasky{ 224321936Shselasky OSM_LOG_ENTER(p_sm->p_log); 225321936Shselasky osm_lid_mgr_destroy(&p_sm->lid_mgr); 226321936Shselasky osm_ucast_mgr_destroy(&p_sm->ucast_mgr); 227321936Shselasky cl_event_wheel_destroy(&p_sm->trap_aging_tracker); 228321936Shselasky cl_timer_destroy(&p_sm->sweep_timer); 229321936Shselasky cl_timer_destroy(&p_sm->polling_timer); 230321936Shselasky cl_event_destroy(&p_sm->signal_event); 231321936Shselasky cl_event_destroy(&p_sm->subnet_up_event); 232321936Shselasky cl_spinlock_destroy(&p_sm->signal_lock); 233321936Shselasky cl_spinlock_destroy(&p_sm->state_lock); 234321936Shselasky free(p_sm->mlids_req); 235321936Shselasky 236321936Shselasky osm_log_v2(p_sm->p_log, OSM_LOG_SYS, FILE_ID, "Exiting SM\n"); /* Format Waived */ 237321936Shselasky OSM_LOG_EXIT(p_sm->p_log); 238321936Shselasky} 239321936Shselasky 240321936Shselaskyib_api_status_t osm_sm_init(IN osm_sm_t * p_sm, IN osm_subn_t * p_subn, 241321936Shselasky IN osm_db_t * p_db, IN osm_vendor_t * p_vendor, 242321936Shselasky IN osm_mad_pool_t * p_mad_pool, 243321936Shselasky IN osm_vl15_t * p_vl15, IN osm_log_t * p_log, 244321936Shselasky IN osm_stats_t * p_stats, 245321936Shselasky IN cl_dispatcher_t * p_disp, IN cl_plock_t * p_lock) 246321936Shselasky{ 247321936Shselasky ib_api_status_t status; 248321936Shselasky 249321936Shselasky OSM_LOG_ENTER(p_log); 250321936Shselasky 251321936Shselasky p_sm->p_subn = p_subn; 252321936Shselasky p_sm->p_db = p_db; 253321936Shselasky p_sm->p_vendor = p_vendor; 254321936Shselasky p_sm->p_mad_pool = p_mad_pool; 255321936Shselasky p_sm->p_vl15 = p_vl15; 256321936Shselasky p_sm->p_log = p_log; 257321936Shselasky p_sm->p_disp = p_disp; 258321936Shselasky p_sm->p_lock = p_lock; 259321936Shselasky 260321936Shselasky status = cl_spinlock_init(&p_sm->signal_lock); 261321936Shselasky if (status != CL_SUCCESS) 262321936Shselasky goto Exit; 263321936Shselasky 264321936Shselasky status = cl_spinlock_init(&p_sm->state_lock); 265321936Shselasky if (status != CL_SUCCESS) 266321936Shselasky goto Exit; 267321936Shselasky 268321936Shselasky status = cl_event_init(&p_sm->signal_event, FALSE); 269321936Shselasky if (status != CL_SUCCESS) 270321936Shselasky goto Exit; 271321936Shselasky 272321936Shselasky status = cl_event_init(&p_sm->subnet_up_event, FALSE); 273321936Shselasky if (status != CL_SUCCESS) 274321936Shselasky goto Exit; 275321936Shselasky 276321936Shselasky status = cl_timer_init(&p_sm->sweep_timer, sm_sweep, p_sm); 277321936Shselasky if (status != CL_SUCCESS) 278321936Shselasky goto Exit; 279321936Shselasky 280321936Shselasky status = cl_timer_init(&p_sm->polling_timer, 281321936Shselasky osm_sm_state_mgr_polling_callback, p_sm); 282321936Shselasky if (status != CL_SUCCESS) 283321936Shselasky goto Exit; 284321936Shselasky 285321936Shselasky p_sm->mlids_req_max = 0; 286321936Shselasky p_sm->mlids_req = malloc((IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO + 287321936Shselasky 1) * sizeof(p_sm->mlids_req[0])); 288321936Shselasky if (!p_sm->mlids_req) 289321936Shselasky goto Exit; 290321936Shselasky memset(p_sm->mlids_req, 0, 291321936Shselasky (IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO + 292321936Shselasky 1) * sizeof(p_sm->mlids_req[0])); 293321936Shselasky 294321936Shselasky status = osm_sm_mad_ctrl_init(&p_sm->mad_ctrl, p_sm->p_subn, 295321936Shselasky p_sm->p_mad_pool, p_sm->p_vl15, 296321936Shselasky p_sm->p_vendor, 297321936Shselasky p_log, p_stats, p_lock, p_disp); 298321936Shselasky if (status != IB_SUCCESS) 299321936Shselasky goto Exit; 300321936Shselasky 301321936Shselasky status = cl_event_wheel_init(&p_sm->trap_aging_tracker); 302321936Shselasky if (status != IB_SUCCESS) 303321936Shselasky goto Exit; 304321936Shselasky 305321936Shselasky status = osm_lid_mgr_init(&p_sm->lid_mgr, p_sm); 306321936Shselasky if (status != IB_SUCCESS) 307321936Shselasky goto Exit; 308321936Shselasky 309321936Shselasky status = osm_ucast_mgr_init(&p_sm->ucast_mgr, p_sm); 310321936Shselasky if (status != IB_SUCCESS) 311321936Shselasky goto Exit; 312321936Shselasky 313321936Shselasky status = IB_INSUFFICIENT_RESOURCES; 314321936Shselasky p_sm->sweep_fail_disp_h = cl_disp_register(p_disp, 315321936Shselasky OSM_MSG_LIGHT_SWEEP_FAIL, 316321936Shselasky sweep_fail_process, p_sm); 317321936Shselasky if (p_sm->sweep_fail_disp_h == CL_DISP_INVALID_HANDLE) 318321936Shselasky goto Exit; 319321936Shselasky 320321936Shselasky p_sm->ni_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NODE_INFO, 321321936Shselasky osm_ni_rcv_process, p_sm); 322321936Shselasky if (p_sm->ni_disp_h == CL_DISP_INVALID_HANDLE) 323321936Shselasky goto Exit; 324321936Shselasky 325321936Shselasky p_sm->pi_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PORT_INFO, 326321936Shselasky osm_pi_rcv_process, p_sm); 327321936Shselasky if (p_sm->pi_disp_h == CL_DISP_INVALID_HANDLE) 328321936Shselasky goto Exit; 329321936Shselasky 330321936Shselasky p_sm->gi_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_GUID_INFO, 331321936Shselasky osm_gi_rcv_process, p_sm); 332321936Shselasky if (p_sm->gi_disp_h == CL_DISP_INVALID_HANDLE) 333321936Shselasky goto Exit; 334321936Shselasky 335321936Shselasky p_sm->si_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SWITCH_INFO, 336321936Shselasky osm_si_rcv_process, p_sm); 337321936Shselasky if (p_sm->si_disp_h == CL_DISP_INVALID_HANDLE) 338321936Shselasky goto Exit; 339321936Shselasky 340321936Shselasky p_sm->nd_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NODE_DESC, 341321936Shselasky osm_nd_rcv_process, p_sm); 342321936Shselasky if (p_sm->nd_disp_h == CL_DISP_INVALID_HANDLE) 343321936Shselasky goto Exit; 344321936Shselasky 345321936Shselasky p_sm->lft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_LFT, 346321936Shselasky osm_lft_rcv_process, p_sm); 347321936Shselasky if (p_sm->lft_disp_h == CL_DISP_INVALID_HANDLE) 348321936Shselasky goto Exit; 349321936Shselasky 350321936Shselasky p_sm->mft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_MFT, 351321936Shselasky osm_mft_rcv_process, p_sm); 352321936Shselasky if (p_sm->mft_disp_h == CL_DISP_INVALID_HANDLE) 353321936Shselasky goto Exit; 354321936Shselasky 355321936Shselasky p_sm->sm_info_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SM_INFO, 356321936Shselasky osm_sminfo_rcv_process, p_sm); 357321936Shselasky if (p_sm->sm_info_disp_h == CL_DISP_INVALID_HANDLE) 358321936Shselasky goto Exit; 359321936Shselasky 360321936Shselasky p_sm->trap_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NOTICE, 361321936Shselasky osm_trap_rcv_process, p_sm); 362321936Shselasky if (p_sm->trap_disp_h == CL_DISP_INVALID_HANDLE) 363321936Shselasky goto Exit; 364321936Shselasky 365321936Shselasky p_sm->slvl_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SLVL, 366321936Shselasky osm_slvl_rcv_process, p_sm); 367321936Shselasky if (p_sm->slvl_disp_h == CL_DISP_INVALID_HANDLE) 368321936Shselasky goto Exit; 369321936Shselasky 370321936Shselasky p_sm->vla_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_VL_ARB, 371321936Shselasky osm_vla_rcv_process, p_sm); 372321936Shselasky if (p_sm->vla_disp_h == CL_DISP_INVALID_HANDLE) 373321936Shselasky goto Exit; 374321936Shselasky 375321936Shselasky p_sm->pkey_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PKEY, 376321936Shselasky osm_pkey_rcv_process, p_sm); 377321936Shselasky if (p_sm->pkey_disp_h == CL_DISP_INVALID_HANDLE) 378321936Shselasky goto Exit; 379321936Shselasky 380321936Shselasky p_sm->mlnx_epi_disp_h = cl_disp_register(p_disp, 381321936Shselasky OSM_MSG_MAD_MLNX_EXT_PORT_INFO, 382321936Shselasky osm_mlnx_epi_rcv_process, p_sm); 383321936Shselasky if (p_sm->mlnx_epi_disp_h == CL_DISP_INVALID_HANDLE) 384321936Shselasky goto Exit; 385321936Shselasky 386321936Shselasky p_subn->sm_state = p_subn->opt.sm_inactive ? 387321936Shselasky IB_SMINFO_STATE_NOTACTIVE : IB_SMINFO_STATE_DISCOVERING; 388321936Shselasky osm_report_sm_state(p_sm); 389321936Shselasky 390321936Shselasky /* 391321936Shselasky * Now that the component objects are initialized, start 392321936Shselasky * the sweeper thread if the user wants sweeping. 393321936Shselasky */ 394321936Shselasky p_sm->thread_state = OSM_THREAD_STATE_RUN; 395321936Shselasky status = cl_thread_init(&p_sm->sweeper, sm_sweeper, p_sm, 396321936Shselasky "opensm sweeper"); 397321936Shselasky if (status != IB_SUCCESS) 398321936Shselasky goto Exit; 399321936Shselasky 400321936Shselasky if (p_sm->p_subn->opt.sweep_interval) 401321936Shselasky cl_timer_start(&p_sm->sweep_timer, 402321936Shselasky p_sm->p_subn->opt.sweep_interval * 1000); 403321936Shselasky 404321936ShselaskyExit: 405321936Shselasky OSM_LOG_EXIT(p_log); 406321936Shselasky return status; 407321936Shselasky} 408321936Shselasky 409321936Shselaskyvoid osm_sm_signal(osm_sm_t * p_sm, osm_signal_t signal) 410321936Shselasky{ 411321936Shselasky cl_spinlock_acquire(&p_sm->signal_lock); 412321936Shselasky p_sm->signal_mask |= 1 << signal; 413321936Shselasky cl_event_signal(&p_sm->signal_event); 414321936Shselasky cl_spinlock_release(&p_sm->signal_lock); 415321936Shselasky} 416321936Shselasky 417321936Shselaskyvoid osm_sm_sweep(IN osm_sm_t * p_sm) 418321936Shselasky{ 419321936Shselasky OSM_LOG_ENTER(p_sm->p_log); 420321936Shselasky osm_sm_signal(p_sm, OSM_SIGNAL_SWEEP); 421321936Shselasky OSM_LOG_EXIT(p_sm->p_log); 422321936Shselasky} 423321936Shselasky 424321936Shselaskyib_api_status_t osm_sm_bind(IN osm_sm_t * p_sm, IN ib_net64_t port_guid) 425321936Shselasky{ 426321936Shselasky ib_api_status_t status; 427321936Shselasky 428321936Shselasky OSM_LOG_ENTER(p_sm->p_log); 429321936Shselasky 430321936Shselasky status = osm_sm_mad_ctrl_bind(&p_sm->mad_ctrl, port_guid); 431321936Shselasky 432321936Shselasky if (status != IB_SUCCESS) { 433321936Shselasky OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR 2E10: " 434321936Shselasky "SM MAD Controller bind failed (%s)\n", 435321936Shselasky ib_get_err_str(status)); 436321936Shselasky goto Exit; 437321936Shselasky } 438321936Shselasky 439321936ShselaskyExit: 440321936Shselasky OSM_LOG_EXIT(p_sm->p_log); 441321936Shselasky return status; 442321936Shselasky} 443321936Shselasky 444321936Shselaskyvoid osm_sm_reroute_mlid(osm_sm_t * sm, ib_net16_t mlid) 445321936Shselasky{ 446321936Shselasky mlid = cl_ntoh16(mlid) - IB_LID_MCAST_START_HO; 447321936Shselasky sm->mlids_req[mlid] = 1; 448321936Shselasky if (sm->mlids_req_max < mlid) 449321936Shselasky sm->mlids_req_max = mlid; 450321936Shselasky osm_sm_signal(sm, OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST); 451321936Shselasky OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "rerouting requested for MLID 0x%x\n", 452321936Shselasky mlid + IB_LID_MCAST_START_HO); 453321936Shselasky} 454321936Shselasky 455321936Shselaskyvoid osm_set_sm_priority(osm_sm_t * sm, uint8_t priority) 456321936Shselasky{ 457321936Shselasky uint8_t old_pri = sm->p_subn->opt.sm_priority; 458321936Shselasky 459321936Shselasky sm->p_subn->opt.sm_priority = priority; 460321936Shselasky 461321936Shselasky if (old_pri < priority && 462321936Shselasky sm->p_subn->sm_state == IB_SMINFO_STATE_STANDBY) 463321936Shselasky osm_send_trap144(sm, TRAP_144_MASK_SM_PRIORITY_CHANGE); 464321936Shselasky} 465