1/* 2 * Copyright (c) 2004-2008 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 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 * 34 */ 35 36/* 37 * Abstract: 38 * Implementation of osm_req_t. 39 * This object represents the generic attribute requester. 40 * This object is part of the opensm family of objects. 41 */ 42 43#if HAVE_CONFIG_H 44# include <config.h> 45#endif /* HAVE_CONFIG_H */ 46 47#include <string.h> 48#include <iba/ib_types.h> 49#include <complib/cl_debug.h> 50#include <opensm/osm_madw.h> 51#include <opensm/osm_attrib_req.h> 52#include <opensm/osm_log.h> 53#include <opensm/osm_helper.h> 54#include <opensm/osm_mad_pool.h> 55#include <opensm/osm_vl15intf.h> 56#include <opensm/osm_msgdef.h> 57#include <opensm/osm_opensm.h> 58 59/********************************************************************** 60 The plock MAY or MAY NOT be held before calling this function. 61**********************************************************************/ 62ib_api_status_t 63osm_req_get(IN osm_sm_t * sm, 64 IN const osm_dr_path_t * const p_path, 65 IN const uint16_t attr_id, 66 IN const uint32_t attr_mod, 67 IN const cl_disp_msgid_t err_msg, 68 IN const osm_madw_context_t * const p_context) 69{ 70 osm_madw_t *p_madw; 71 ib_api_status_t status = IB_SUCCESS; 72 ib_net64_t tid; 73 74 CL_ASSERT(sm); 75 76 OSM_LOG_ENTER(sm->p_log); 77 78 CL_ASSERT(p_path); 79 CL_ASSERT(attr_id); 80 81 /* do nothing if we are exiting ... */ 82 if (osm_exit_flag) 83 goto Exit; 84 85 /* p_context may be NULL. */ 86 87 p_madw = osm_mad_pool_get(sm->p_mad_pool, 88 p_path->h_bind, MAD_BLOCK_SIZE, NULL); 89 90 if (p_madw == NULL) { 91 OSM_LOG(sm->p_log, OSM_LOG_ERROR, 92 "ERR 1101: Unable to acquire MAD\n"); 93 status = IB_INSUFFICIENT_RESOURCES; 94 goto Exit; 95 } 96 97 tid = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)); 98 99 OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 100 "Getting %s (0x%X), modifier 0x%X, TID 0x%" PRIx64 "\n", 101 ib_get_sm_attr_str(attr_id), cl_ntoh16(attr_id), 102 cl_ntoh32(attr_mod), cl_ntoh64(tid)); 103 104 ib_smp_init_new(osm_madw_get_smp_ptr(p_madw), 105 IB_MAD_METHOD_GET, 106 tid, 107 attr_id, 108 attr_mod, 109 p_path->hop_count, 110 sm->p_subn->opt.m_key, 111 p_path->path, IB_LID_PERMISSIVE, IB_LID_PERMISSIVE); 112 113 p_madw->mad_addr.dest_lid = IB_LID_PERMISSIVE; 114 p_madw->mad_addr.addr_type.smi.source_lid = IB_LID_PERMISSIVE; 115 p_madw->resp_expected = TRUE; 116 p_madw->fail_msg = err_msg; 117 118 /* 119 Fill in the mad wrapper context for the recipient. 120 In this case, the only thing the recipient needs is the 121 guid value. 122 */ 123 124 if (p_context) 125 p_madw->context = *p_context; 126 127 osm_vl15_post(sm->p_vl15, p_madw); 128 129Exit: 130 OSM_LOG_EXIT(sm->p_log); 131 return (status); 132} 133 134/********************************************************************** 135 The plock MAY or MAY NOT be held before calling this function. 136**********************************************************************/ 137ib_api_status_t 138osm_req_set(IN osm_sm_t * sm, 139 IN const osm_dr_path_t * const p_path, 140 IN const uint8_t * const p_payload, 141 IN const size_t payload_size, 142 IN const uint16_t attr_id, 143 IN const uint32_t attr_mod, 144 IN const cl_disp_msgid_t err_msg, 145 IN const osm_madw_context_t * const p_context) 146{ 147 osm_madw_t *p_madw; 148 ib_api_status_t status = IB_SUCCESS; 149 ib_net64_t tid; 150 151 CL_ASSERT(sm); 152 153 OSM_LOG_ENTER(sm->p_log); 154 155 CL_ASSERT(p_path); 156 CL_ASSERT(attr_id); 157 CL_ASSERT(p_payload); 158 159 /* do nothing if we are exiting ... */ 160 if (osm_exit_flag) 161 goto Exit; 162 163 /* p_context may be NULL. */ 164 165 p_madw = osm_mad_pool_get(sm->p_mad_pool, 166 p_path->h_bind, MAD_BLOCK_SIZE, NULL); 167 168 if (p_madw == NULL) { 169 OSM_LOG(sm->p_log, OSM_LOG_ERROR, 170 "ERR 1102: Unable to acquire MAD\n"); 171 status = IB_INSUFFICIENT_RESOURCES; 172 goto Exit; 173 } 174 175 tid = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)); 176 177 OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 178 "Setting %s (0x%X), modifier 0x%X, TID 0x%" PRIx64 "\n", 179 ib_get_sm_attr_str(attr_id), cl_ntoh16(attr_id), 180 cl_ntoh32(attr_mod), cl_ntoh64(tid)); 181 182 ib_smp_init_new(osm_madw_get_smp_ptr(p_madw), 183 IB_MAD_METHOD_SET, 184 tid, 185 attr_id, 186 attr_mod, 187 p_path->hop_count, 188 sm->p_subn->opt.m_key, 189 p_path->path, IB_LID_PERMISSIVE, IB_LID_PERMISSIVE); 190 191 p_madw->mad_addr.dest_lid = IB_LID_PERMISSIVE; 192 p_madw->mad_addr.addr_type.smi.source_lid = IB_LID_PERMISSIVE; 193 p_madw->resp_expected = TRUE; 194 p_madw->fail_msg = err_msg; 195 196 /* 197 Fill in the mad wrapper context for the recipient. 198 In this case, the only thing the recipient needs is the 199 guid value. 200 */ 201 202 if (p_context) 203 p_madw->context = *p_context; 204 205 memcpy(osm_madw_get_smp_ptr(p_madw)->data, p_payload, payload_size); 206 207 osm_vl15_post(sm->p_vl15, p_madw); 208 209Exit: 210 OSM_LOG_EXIT(sm->p_log); 211 return (status); 212} 213 214int osm_send_trap144(osm_sm_t *sm, ib_net16_t local) 215{ 216 osm_madw_t *madw; 217 ib_smp_t *smp; 218 ib_mad_notice_attr_t *ntc; 219 osm_port_t *port; 220 ib_port_info_t *pi; 221 222 port = osm_get_port_by_guid(sm->p_subn, sm->p_subn->sm_port_guid); 223 if (!port) { 224 OSM_LOG(sm->p_log, OSM_LOG_ERROR, 225 "ERR 1104: cannot find SM port by guid 0x%" PRIx64 "\n", 226 cl_ntoh64(sm->p_subn->sm_port_guid)); 227 return -1; 228 } 229 230 pi = &port->p_physp->port_info; 231 232 /* don't bother with sending trap when SMA supports this */ 233 if (!local && 234 pi->capability_mask&(IB_PORT_CAP_HAS_TRAP|IB_PORT_CAP_HAS_CAP_NTC)) 235 return 0; 236 237 madw = osm_mad_pool_get(sm->p_mad_pool, 238 osm_sm_mad_ctrl_get_bind_handle(&sm->mad_ctrl), 239 MAD_BLOCK_SIZE, NULL); 240 if (madw == NULL) { 241 OSM_LOG(sm->p_log, OSM_LOG_ERROR, 242 "ERR 1105: Unable to acquire MAD\n"); 243 return -1; 244 } 245 246 madw->mad_addr.dest_lid = pi->master_sm_base_lid; 247 madw->mad_addr.addr_type.smi.source_lid = pi->base_lid; 248 madw->fail_msg = CL_DISP_MSGID_NONE; 249 250 smp = osm_madw_get_smp_ptr(madw); 251 memset(smp, 0, sizeof(*smp)); 252 253 smp->base_ver = 1; 254 smp->mgmt_class = IB_MCLASS_SUBN_LID; 255 smp->class_ver = 1; 256 smp->method = IB_MAD_METHOD_TRAP; 257 smp->trans_id = cl_hton64((uint64_t)cl_atomic_inc(&sm->sm_trans_id)); 258 smp->attr_id = IB_MAD_ATTR_NOTICE; 259 smp->m_key = sm->p_subn->opt.m_key; 260 261 ntc = (ib_mad_notice_attr_t *)smp->data; 262 263 ntc->generic_type = 0x80 | IB_NOTICE_TYPE_INFO; 264 ib_notice_set_prod_type_ho(ntc, IB_NODE_TYPE_CA); 265 ntc->g_or_v.generic.trap_num = cl_hton16(144); 266 ntc->issuer_lid = pi->base_lid; 267 ntc->data_details.ntc_144.lid = pi->base_lid; 268 ntc->data_details.ntc_144.local_changes = local ? 269 TRAP_144_MASK_OTHER_LOCAL_CHANGES : 0; 270 ntc->data_details.ntc_144.new_cap_mask = pi->capability_mask; 271 ntc->data_details.ntc_144.change_flgs = local; 272 273 OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 274 "Sending Trap 144, TID 0x%" PRIx64 " to SM lid %u\n", 275 cl_ntoh64(smp->trans_id), cl_ntoh16(pi->master_sm_base_lid)); 276 277 osm_vl15_post(sm->p_vl15, madw); 278 279 return 0; 280} 281