1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff * 34219820Sjeff */ 35219820Sjeff 36219820Sjeff/* 37219820Sjeff * Abstract: 38219820Sjeff * Implementation of osm_req_t. 39219820Sjeff * This object represents the generic attribute requester. 40219820Sjeff * This object is part of the opensm family of objects. 41219820Sjeff */ 42219820Sjeff 43219820Sjeff#if HAVE_CONFIG_H 44219820Sjeff# include <config.h> 45219820Sjeff#endif /* HAVE_CONFIG_H */ 46219820Sjeff 47219820Sjeff#include <string.h> 48219820Sjeff#include <iba/ib_types.h> 49219820Sjeff#include <complib/cl_debug.h> 50219820Sjeff#include <opensm/osm_madw.h> 51219820Sjeff#include <opensm/osm_attrib_req.h> 52219820Sjeff#include <opensm/osm_log.h> 53219820Sjeff#include <opensm/osm_helper.h> 54219820Sjeff#include <opensm/osm_mad_pool.h> 55219820Sjeff#include <opensm/osm_vl15intf.h> 56219820Sjeff#include <opensm/osm_msgdef.h> 57219820Sjeff#include <opensm/osm_opensm.h> 58219820Sjeff 59219820Sjeff/********************************************************************** 60219820Sjeff The plock MAY or MAY NOT be held before calling this function. 61219820Sjeff**********************************************************************/ 62219820Sjeffib_api_status_t 63219820Sjeffosm_req_get(IN osm_sm_t * sm, 64219820Sjeff IN const osm_dr_path_t * const p_path, 65219820Sjeff IN const uint16_t attr_id, 66219820Sjeff IN const uint32_t attr_mod, 67219820Sjeff IN const cl_disp_msgid_t err_msg, 68219820Sjeff IN const osm_madw_context_t * const p_context) 69219820Sjeff{ 70219820Sjeff osm_madw_t *p_madw; 71219820Sjeff ib_api_status_t status = IB_SUCCESS; 72219820Sjeff ib_net64_t tid; 73219820Sjeff 74219820Sjeff CL_ASSERT(sm); 75219820Sjeff 76219820Sjeff OSM_LOG_ENTER(sm->p_log); 77219820Sjeff 78219820Sjeff CL_ASSERT(p_path); 79219820Sjeff CL_ASSERT(attr_id); 80219820Sjeff 81219820Sjeff /* do nothing if we are exiting ... */ 82219820Sjeff if (osm_exit_flag) 83219820Sjeff goto Exit; 84219820Sjeff 85219820Sjeff /* p_context may be NULL. */ 86219820Sjeff 87219820Sjeff p_madw = osm_mad_pool_get(sm->p_mad_pool, 88219820Sjeff p_path->h_bind, MAD_BLOCK_SIZE, NULL); 89219820Sjeff 90219820Sjeff if (p_madw == NULL) { 91219820Sjeff OSM_LOG(sm->p_log, OSM_LOG_ERROR, 92219820Sjeff "ERR 1101: Unable to acquire MAD\n"); 93219820Sjeff status = IB_INSUFFICIENT_RESOURCES; 94219820Sjeff goto Exit; 95219820Sjeff } 96219820Sjeff 97219820Sjeff tid = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)); 98219820Sjeff 99219820Sjeff OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 100219820Sjeff "Getting %s (0x%X), modifier 0x%X, TID 0x%" PRIx64 "\n", 101219820Sjeff ib_get_sm_attr_str(attr_id), cl_ntoh16(attr_id), 102219820Sjeff cl_ntoh32(attr_mod), cl_ntoh64(tid)); 103219820Sjeff 104219820Sjeff ib_smp_init_new(osm_madw_get_smp_ptr(p_madw), 105219820Sjeff IB_MAD_METHOD_GET, 106219820Sjeff tid, 107219820Sjeff attr_id, 108219820Sjeff attr_mod, 109219820Sjeff p_path->hop_count, 110219820Sjeff sm->p_subn->opt.m_key, 111219820Sjeff p_path->path, IB_LID_PERMISSIVE, IB_LID_PERMISSIVE); 112219820Sjeff 113219820Sjeff p_madw->mad_addr.dest_lid = IB_LID_PERMISSIVE; 114219820Sjeff p_madw->mad_addr.addr_type.smi.source_lid = IB_LID_PERMISSIVE; 115219820Sjeff p_madw->resp_expected = TRUE; 116219820Sjeff p_madw->fail_msg = err_msg; 117219820Sjeff 118219820Sjeff /* 119219820Sjeff Fill in the mad wrapper context for the recipient. 120219820Sjeff In this case, the only thing the recipient needs is the 121219820Sjeff guid value. 122219820Sjeff */ 123219820Sjeff 124219820Sjeff if (p_context) 125219820Sjeff p_madw->context = *p_context; 126219820Sjeff 127219820Sjeff osm_vl15_post(sm->p_vl15, p_madw); 128219820Sjeff 129219820SjeffExit: 130219820Sjeff OSM_LOG_EXIT(sm->p_log); 131219820Sjeff return (status); 132219820Sjeff} 133219820Sjeff 134219820Sjeff/********************************************************************** 135219820Sjeff The plock MAY or MAY NOT be held before calling this function. 136219820Sjeff**********************************************************************/ 137219820Sjeffib_api_status_t 138219820Sjeffosm_req_set(IN osm_sm_t * sm, 139219820Sjeff IN const osm_dr_path_t * const p_path, 140219820Sjeff IN const uint8_t * const p_payload, 141219820Sjeff IN const size_t payload_size, 142219820Sjeff IN const uint16_t attr_id, 143219820Sjeff IN const uint32_t attr_mod, 144219820Sjeff IN const cl_disp_msgid_t err_msg, 145219820Sjeff IN const osm_madw_context_t * const p_context) 146219820Sjeff{ 147219820Sjeff osm_madw_t *p_madw; 148219820Sjeff ib_api_status_t status = IB_SUCCESS; 149219820Sjeff ib_net64_t tid; 150219820Sjeff 151219820Sjeff CL_ASSERT(sm); 152219820Sjeff 153219820Sjeff OSM_LOG_ENTER(sm->p_log); 154219820Sjeff 155219820Sjeff CL_ASSERT(p_path); 156219820Sjeff CL_ASSERT(attr_id); 157219820Sjeff CL_ASSERT(p_payload); 158219820Sjeff 159219820Sjeff /* do nothing if we are exiting ... */ 160219820Sjeff if (osm_exit_flag) 161219820Sjeff goto Exit; 162219820Sjeff 163219820Sjeff /* p_context may be NULL. */ 164219820Sjeff 165219820Sjeff p_madw = osm_mad_pool_get(sm->p_mad_pool, 166219820Sjeff p_path->h_bind, MAD_BLOCK_SIZE, NULL); 167219820Sjeff 168219820Sjeff if (p_madw == NULL) { 169219820Sjeff OSM_LOG(sm->p_log, OSM_LOG_ERROR, 170219820Sjeff "ERR 1102: Unable to acquire MAD\n"); 171219820Sjeff status = IB_INSUFFICIENT_RESOURCES; 172219820Sjeff goto Exit; 173219820Sjeff } 174219820Sjeff 175219820Sjeff tid = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)); 176219820Sjeff 177219820Sjeff OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 178219820Sjeff "Setting %s (0x%X), modifier 0x%X, TID 0x%" PRIx64 "\n", 179219820Sjeff ib_get_sm_attr_str(attr_id), cl_ntoh16(attr_id), 180219820Sjeff cl_ntoh32(attr_mod), cl_ntoh64(tid)); 181219820Sjeff 182219820Sjeff ib_smp_init_new(osm_madw_get_smp_ptr(p_madw), 183219820Sjeff IB_MAD_METHOD_SET, 184219820Sjeff tid, 185219820Sjeff attr_id, 186219820Sjeff attr_mod, 187219820Sjeff p_path->hop_count, 188219820Sjeff sm->p_subn->opt.m_key, 189219820Sjeff p_path->path, IB_LID_PERMISSIVE, IB_LID_PERMISSIVE); 190219820Sjeff 191219820Sjeff p_madw->mad_addr.dest_lid = IB_LID_PERMISSIVE; 192219820Sjeff p_madw->mad_addr.addr_type.smi.source_lid = IB_LID_PERMISSIVE; 193219820Sjeff p_madw->resp_expected = TRUE; 194219820Sjeff p_madw->fail_msg = err_msg; 195219820Sjeff 196219820Sjeff /* 197219820Sjeff Fill in the mad wrapper context for the recipient. 198219820Sjeff In this case, the only thing the recipient needs is the 199219820Sjeff guid value. 200219820Sjeff */ 201219820Sjeff 202219820Sjeff if (p_context) 203219820Sjeff p_madw->context = *p_context; 204219820Sjeff 205219820Sjeff memcpy(osm_madw_get_smp_ptr(p_madw)->data, p_payload, payload_size); 206219820Sjeff 207219820Sjeff osm_vl15_post(sm->p_vl15, p_madw); 208219820Sjeff 209219820SjeffExit: 210219820Sjeff OSM_LOG_EXIT(sm->p_log); 211219820Sjeff return (status); 212219820Sjeff} 213219820Sjeff 214219820Sjeffint osm_send_trap144(osm_sm_t *sm, ib_net16_t local) 215219820Sjeff{ 216219820Sjeff osm_madw_t *madw; 217219820Sjeff ib_smp_t *smp; 218219820Sjeff ib_mad_notice_attr_t *ntc; 219219820Sjeff osm_port_t *port; 220219820Sjeff ib_port_info_t *pi; 221219820Sjeff 222219820Sjeff port = osm_get_port_by_guid(sm->p_subn, sm->p_subn->sm_port_guid); 223219820Sjeff if (!port) { 224219820Sjeff OSM_LOG(sm->p_log, OSM_LOG_ERROR, 225219820Sjeff "ERR 1104: cannot find SM port by guid 0x%" PRIx64 "\n", 226219820Sjeff cl_ntoh64(sm->p_subn->sm_port_guid)); 227219820Sjeff return -1; 228219820Sjeff } 229219820Sjeff 230219820Sjeff pi = &port->p_physp->port_info; 231219820Sjeff 232219820Sjeff /* don't bother with sending trap when SMA supports this */ 233219820Sjeff if (!local && 234219820Sjeff pi->capability_mask&(IB_PORT_CAP_HAS_TRAP|IB_PORT_CAP_HAS_CAP_NTC)) 235219820Sjeff return 0; 236219820Sjeff 237219820Sjeff madw = osm_mad_pool_get(sm->p_mad_pool, 238219820Sjeff osm_sm_mad_ctrl_get_bind_handle(&sm->mad_ctrl), 239219820Sjeff MAD_BLOCK_SIZE, NULL); 240219820Sjeff if (madw == NULL) { 241219820Sjeff OSM_LOG(sm->p_log, OSM_LOG_ERROR, 242219820Sjeff "ERR 1105: Unable to acquire MAD\n"); 243219820Sjeff return -1; 244219820Sjeff } 245219820Sjeff 246219820Sjeff madw->mad_addr.dest_lid = pi->master_sm_base_lid; 247219820Sjeff madw->mad_addr.addr_type.smi.source_lid = pi->base_lid; 248219820Sjeff madw->fail_msg = CL_DISP_MSGID_NONE; 249219820Sjeff 250219820Sjeff smp = osm_madw_get_smp_ptr(madw); 251219820Sjeff memset(smp, 0, sizeof(*smp)); 252219820Sjeff 253219820Sjeff smp->base_ver = 1; 254219820Sjeff smp->mgmt_class = IB_MCLASS_SUBN_LID; 255219820Sjeff smp->class_ver = 1; 256219820Sjeff smp->method = IB_MAD_METHOD_TRAP; 257219820Sjeff smp->trans_id = cl_hton64((uint64_t)cl_atomic_inc(&sm->sm_trans_id)); 258219820Sjeff smp->attr_id = IB_MAD_ATTR_NOTICE; 259219820Sjeff smp->m_key = sm->p_subn->opt.m_key; 260219820Sjeff 261219820Sjeff ntc = (ib_mad_notice_attr_t *)smp->data; 262219820Sjeff 263219820Sjeff ntc->generic_type = 0x80 | IB_NOTICE_TYPE_INFO; 264219820Sjeff ib_notice_set_prod_type_ho(ntc, IB_NODE_TYPE_CA); 265219820Sjeff ntc->g_or_v.generic.trap_num = cl_hton16(144); 266219820Sjeff ntc->issuer_lid = pi->base_lid; 267219820Sjeff ntc->data_details.ntc_144.lid = pi->base_lid; 268219820Sjeff ntc->data_details.ntc_144.local_changes = local ? 269219820Sjeff TRAP_144_MASK_OTHER_LOCAL_CHANGES : 0; 270219820Sjeff ntc->data_details.ntc_144.new_cap_mask = pi->capability_mask; 271219820Sjeff ntc->data_details.ntc_144.change_flgs = local; 272219820Sjeff 273219820Sjeff OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 274219820Sjeff "Sending Trap 144, TID 0x%" PRIx64 " to SM lid %u\n", 275219820Sjeff cl_ntoh64(smp->trans_id), cl_ntoh16(pi->master_sm_base_lid)); 276219820Sjeff 277219820Sjeff osm_vl15_post(sm->p_vl15, madw); 278219820Sjeff 279219820Sjeff return 0; 280219820Sjeff} 281