Blame opensm/osm_sm_mad_ctrl.c

Packit Service 54dbc3
/*
Packit Service 54dbc3
 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
Packit Service 54dbc3
 * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
Packit Service 54dbc3
 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
Packit Service 54dbc3
 * Copyright (c) 2009 HNR Consulting. All rights reserved.
Packit Service 54dbc3
 * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * This software is available to you under a choice of one of two
Packit Service 54dbc3
 * licenses.  You may choose to be licensed under the terms of the GNU
Packit Service 54dbc3
 * General Public License (GPL) Version 2, available from the file
Packit Service 54dbc3
 * COPYING in the main directory of this source tree, or the
Packit Service 54dbc3
 * OpenIB.org BSD license below:
Packit Service 54dbc3
 *
Packit Service 54dbc3
 *     Redistribution and use in source and binary forms, with or
Packit Service 54dbc3
 *     without modification, are permitted provided that the following
Packit Service 54dbc3
 *     conditions are met:
Packit Service 54dbc3
 *
Packit Service 54dbc3
 *      - Redistributions of source code must retain the above
Packit Service 54dbc3
 *        copyright notice, this list of conditions and the following
Packit Service 54dbc3
 *        disclaimer.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 *      - Redistributions in binary form must reproduce the above
Packit Service 54dbc3
 *        copyright notice, this list of conditions and the following
Packit Service 54dbc3
 *        disclaimer in the documentation and/or other materials
Packit Service 54dbc3
 *        provided with the distribution.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Packit Service 54dbc3
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit Service 54dbc3
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Packit Service 54dbc3
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
Packit Service 54dbc3
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
Packit Service 54dbc3
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit Service 54dbc3
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
Packit Service 54dbc3
 * SOFTWARE.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 */
Packit Service 54dbc3
Packit Service 54dbc3
/*
Packit Service 54dbc3
 * Abstract:
Packit Service 54dbc3
 *    Implementation of osm_sm_mad_ctrl_t.
Packit Service 54dbc3
 * This object represents the SM MAD request controller object.
Packit Service 54dbc3
 * This object is part of the opensm family of objects.
Packit Service 54dbc3
 */
Packit Service 54dbc3
Packit Service 54dbc3
#if HAVE_CONFIG_H
Packit Service 54dbc3
#  include <config.h>
Packit Service 54dbc3
#endif				/* HAVE_CONFIG_H */
Packit Service 54dbc3
Packit Service 54dbc3
#include <string.h>
Packit Service 54dbc3
#include <complib/cl_debug.h>
Packit Service 54dbc3
#include <iba/ib_types.h>
Packit Service 54dbc3
#include <opensm/osm_file_ids.h>
Packit Service 54dbc3
#define FILE_ID OSM_FILE_SM_MAD_CTRL_C
Packit Service 54dbc3
#include <opensm/osm_sm_mad_ctrl.h>
Packit Service 54dbc3
#include <vendor/osm_vendor_api.h>
Packit Service 54dbc3
#include <opensm/osm_madw.h>
Packit Service 54dbc3
#include <opensm/osm_msgdef.h>
Packit Service 54dbc3
#include <opensm/osm_helper.h>
Packit Service 54dbc3
#include <opensm/osm_opensm.h>
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_retire_trans_mad
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_retire_trans_mad
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This function handles clean-up of MADs associated with the SM's
Packit Service 54dbc3
 * outstanding transactions on the wire.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
Packit Service 54dbc3
static void sm_mad_ctrl_retire_trans_mad(IN osm_sm_mad_ctrl_t * p_ctrl,
Packit Service 54dbc3
					 IN osm_madw_t * p_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	uint32_t outstanding;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(p_madw);
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Return the MAD & wrapper to the pool.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
		"Retiring MAD with TID 0x%" PRIx64 "\n",
Packit Service 54dbc3
		cl_ntoh64(osm_madw_get_smp_ptr(p_madw)->trans_id));
Packit Service 54dbc3
Packit Service 54dbc3
	osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	outstanding = osm_stats_dec_qp0_outstanding(p_ctrl->p_stats);
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "%u QP0 MADs outstanding%s\n",
Packit Service 54dbc3
		p_ctrl->p_stats->qp0_mads_outstanding,
Packit Service 54dbc3
		outstanding ? "" : ": wire is clean.");
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/************/
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_disp_done_callback
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_disp_done_callback
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This function is the Dispatcher callback that indicates
Packit Service 54dbc3
 * a received MAD has been processed by the recipient.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_disp_done_callback(IN void *context, IN void *p_data)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_sm_mad_ctrl_t *p_ctrl = context;
Packit Service 54dbc3
	osm_madw_t *p_madw = p_data;
Packit Service 54dbc3
	ib_smp_t *p_smp;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   If the MAD that just finished processing was a response,
Packit Service 54dbc3
	   then retire the transaction, since we must have generated
Packit Service 54dbc3
	   the request.
Packit Service 54dbc3
Packit Service 54dbc3
	   Otherwise, retire the transaction if a response was expected,
Packit Service 54dbc3
	   as in the case of a send failure. If a response was not expected,
Packit Service 54dbc3
	   just put the MAD back in the pool, because the MAD was a query
Packit Service 54dbc3
	   from some outside agent, e.g. Get(SMInfo) from another SM.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	p_smp = osm_madw_get_smp_ptr(p_madw);
Packit Service 54dbc3
	if (ib_smp_is_response(p_smp)) {
Packit Service 54dbc3
		CL_ASSERT(p_madw->resp_expected == FALSE);
Packit Service 54dbc3
		sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
Packit Service 54dbc3
	} else if (p_madw->resp_expected == TRUE)
Packit Service 54dbc3
		sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
Packit Service 54dbc3
	else
Packit Service 54dbc3
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/************/
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_update_wire_stats
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_update_wire_stats
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * Updates wire stats for outstanding MADs and calls the VL15 poller.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_update_wire_stats(IN osm_sm_mad_ctrl_t * p_ctrl)
Packit Service 54dbc3
{
Packit Service 54dbc3
	uint32_t mads_on_wire;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	mads_on_wire =
Packit Service 54dbc3
	    cl_atomic_dec(&p_ctrl->p_stats->qp0_mads_outstanding_on_wire);
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
		"%u SMPs on the wire, %u outstanding\n", mads_on_wire,
Packit Service 54dbc3
		p_ctrl->p_stats->qp0_mads_outstanding);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   We can signal the VL15 controller to send another MAD
Packit Service 54dbc3
	   if any are waiting for transmission.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	osm_vl15_poll(p_ctrl->p_vl15);
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_process_get_resp
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_process_get_resp
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This function handles method GetResp() for received MADs.
Packit Service 54dbc3
 * This is the most common path for QP0 MADs.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_process_get_resp(IN osm_sm_mad_ctrl_t * p_ctrl,
Packit Service 54dbc3
					 IN osm_madw_t * p_madw,
Packit Service 54dbc3
					 IN void *transaction_context)
Packit Service 54dbc3
{
Packit Service 54dbc3
	ib_smp_t *p_smp;
Packit Service 54dbc3
	cl_status_t status;
Packit Service 54dbc3
	osm_madw_t *p_old_madw;
Packit Service 54dbc3
	cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(p_madw);
Packit Service 54dbc3
	CL_ASSERT(transaction_context);
Packit Service 54dbc3
Packit Service 54dbc3
	p_smp = osm_madw_get_smp_ptr(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR && !ib_smp_is_d(p_smp)) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3102: "
Packit Service 54dbc3
			"'D' bit not set in returned SMP\n");
Packit Service 54dbc3
		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	p_old_madw = transaction_context;
Packit Service 54dbc3
Packit Service 54dbc3
	sm_mad_ctrl_update_wire_stats(p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Copy the MAD Wrapper context from the requesting MAD
Packit Service 54dbc3
	   to the new MAD.  This mechanism allows the recipient
Packit Service 54dbc3
	   controller to recover its own context regarding this
Packit Service 54dbc3
	   MAD transaction.  Once we've copied the context, we
Packit Service 54dbc3
	   can return the original MAD to the pool.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	osm_madw_copy_context(p_madw, p_old_madw);
Packit Service 54dbc3
	osm_mad_pool_put(p_ctrl->p_mad_pool, p_old_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Note that attr_id (like the rest of the MAD) is in
Packit Service 54dbc3
	   network byte order.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	switch (p_smp->attr_id) {
Packit Service 54dbc3
	case IB_MAD_ATTR_NODE_DESC:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_NODE_DESC;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_NODE_INFO:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_NODE_INFO;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_GUID_INFO:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_GUID_INFO;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_SWITCH_INFO:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_SWITCH_INFO;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_PORT_INFO:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_PORT_INFO;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_LIN_FWD_TBL:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_LFT;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_MCAST_FWD_TBL:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_MFT;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_SM_INFO:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_SM_INFO;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_SLVL_TABLE:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_SLVL;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_VL_ARBITRATION:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_VL_ARB;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_P_KEY_TABLE:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_PKEY;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_MLNX_EXT_PORT_INFO;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_ATTR_CLASS_PORT_INFO:
Packit Service 54dbc3
	case IB_MAD_ATTR_NOTICE:
Packit Service 54dbc3
	case IB_MAD_ATTR_INFORM_INFO:
Packit Service 54dbc3
	default:
Packit Service 54dbc3
		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3103: "
Packit Service 54dbc3
			"Unsupported attribute 0x%X (%s)\n",
Packit Service 54dbc3
			cl_ntoh16(p_smp->attr_id),
Packit Service 54dbc3
			ib_get_sm_attr_str(p_smp->attr_id));
Packit Service 54dbc3
		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
Packit Service 54dbc3
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Post this MAD to the dispatcher for asynchronous
Packit Service 54dbc3
	   processing by the appropriate controller.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "Posting Dispatcher message %s\n",
Packit Service 54dbc3
		osm_get_disp_msg_str(msg_id));
Packit Service 54dbc3
Packit Service 54dbc3
	status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
Packit Service 54dbc3
			      sm_mad_ctrl_disp_done_callback, p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	if (status != CL_SUCCESS) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3104: "
Packit Service 54dbc3
			"Dispatcher post message failed (%s) for attribute 0x%X (%s)\n",
Packit Service 54dbc3
			CL_STATUS_MSG(status), cl_ntoh16(p_smp->attr_id),
Packit Service 54dbc3
			ib_get_sm_attr_str(p_smp->attr_id));
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_process_get
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_process_get
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This function handles method Get() for received MADs.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_process_get(IN osm_sm_mad_ctrl_t * p_ctrl,
Packit Service 54dbc3
				    IN osm_madw_t * p_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	ib_smp_t *p_smp;
Packit Service 54dbc3
	cl_status_t status;
Packit Service 54dbc3
	cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	p_smp = osm_madw_get_smp_ptr(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Note that attr_id (like the rest of the MAD) is in
Packit Service 54dbc3
	   network byte order.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	switch (p_smp->attr_id) {
Packit Service 54dbc3
	case IB_MAD_ATTR_SM_INFO:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_SM_INFO;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	default:
Packit Service 54dbc3
		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
Packit Service 54dbc3
			"Ignoring SubnGet MAD - unsupported attribute 0x%X\n",
Packit Service 54dbc3
			cl_ntoh16(p_smp->attr_id));
Packit Service 54dbc3
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Post this MAD to the dispatcher for asynchronous
Packit Service 54dbc3
	   processing by the appropriate controller.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "Posting Dispatcher message %s\n",
Packit Service 54dbc3
		osm_get_disp_msg_str(msg_id));
Packit Service 54dbc3
Packit Service 54dbc3
	status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
Packit Service 54dbc3
			      sm_mad_ctrl_disp_done_callback, p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	if (status != CL_SUCCESS) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3106: "
Packit Service 54dbc3
			"Dispatcher post message failed (%s)\n",
Packit Service 54dbc3
			CL_STATUS_MSG(status));
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/*
Packit Service 54dbc3
 * PARAMETERS
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * RETURN VALUES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * NOTES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SEE ALSO
Packit Service 54dbc3
 *********/
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_process_set
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_process_set
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This function handles method Set() for received MADs.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_process_set(IN osm_sm_mad_ctrl_t * p_ctrl,
Packit Service 54dbc3
				    IN osm_madw_t * p_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	ib_smp_t *p_smp;
Packit Service 54dbc3
	cl_status_t status;
Packit Service 54dbc3
	cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	p_smp = osm_madw_get_smp_ptr(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Note that attr_id (like the rest of the MAD) is in
Packit Service 54dbc3
	   network byte order.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	switch (p_smp->attr_id) {
Packit Service 54dbc3
	case IB_MAD_ATTR_SM_INFO:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_SM_INFO;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	default:
Packit Service 54dbc3
		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3107: "
Packit Service 54dbc3
			"Unsupported attribute 0x%X (%s)\n",
Packit Service 54dbc3
			cl_ntoh16(p_smp->attr_id),
Packit Service 54dbc3
			ib_get_sm_attr_str(p_smp->attr_id));
Packit Service 54dbc3
		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
Packit Service 54dbc3
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Post this MAD to the dispatcher for asynchronous
Packit Service 54dbc3
	   processing by the appropriate controller.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "Posting Dispatcher message %s\n",
Packit Service 54dbc3
		osm_get_disp_msg_str(msg_id));
Packit Service 54dbc3
Packit Service 54dbc3
	status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
Packit Service 54dbc3
			      sm_mad_ctrl_disp_done_callback, p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	if (status != CL_SUCCESS) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3108: "
Packit Service 54dbc3
			"Dispatcher post message failed (%s)\n",
Packit Service 54dbc3
			CL_STATUS_MSG(status));
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/*
Packit Service 54dbc3
 * PARAMETERS
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * RETURN VALUES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * NOTES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SEE ALSO
Packit Service 54dbc3
 *********/
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_process_trap
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_process_trap
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This function handles method Trap() for received MADs.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_process_trap(IN osm_sm_mad_ctrl_t * p_ctrl,
Packit Service 54dbc3
				     IN osm_madw_t * p_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	ib_smp_t *p_smp;
Packit Service 54dbc3
	cl_status_t status;
Packit Service 54dbc3
	cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	p_smp = osm_madw_get_smp_ptr(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	/* Make sure OpenSM is master. If not - then we should not process the trap */
Packit Service 54dbc3
	if (p_ctrl->p_subn->sm_state != IB_SMINFO_STATE_MASTER) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
			"Received trap but OpenSM is not in MASTER state. "
Packit Service 54dbc3
			"Dropping mad\n");
Packit Service 54dbc3
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Note that attr_id (like the rest of the MAD) is in
Packit Service 54dbc3
	   network byte order.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	switch (p_smp->attr_id) {
Packit Service 54dbc3
	case IB_MAD_ATTR_NOTICE:
Packit Service 54dbc3
		msg_id = OSM_MSG_MAD_NOTICE;
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	default:
Packit Service 54dbc3
		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3109: "
Packit Service 54dbc3
			"Unsupported attribute 0x%X (%s)\n",
Packit Service 54dbc3
			cl_ntoh16(p_smp->attr_id),
Packit Service 54dbc3
			ib_get_sm_attr_str(p_smp->attr_id));
Packit Service 54dbc3
		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
Packit Service 54dbc3
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Post this MAD to the dispatcher for asynchronous
Packit Service 54dbc3
	   processing by the appropriate controller.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "Posting Dispatcher message %s\n",
Packit Service 54dbc3
		osm_get_disp_msg_str(msg_id));
Packit Service 54dbc3
Packit Service 54dbc3
	status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
Packit Service 54dbc3
			      sm_mad_ctrl_disp_done_callback, p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	if (status != CL_SUCCESS) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3110: "
Packit Service 54dbc3
			"Dispatcher post message failed (%s)\n",
Packit Service 54dbc3
			CL_STATUS_MSG(status));
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/*
Packit Service 54dbc3
 * PARAMETERS
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * RETURN VALUES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * NOTES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SEE ALSO
Packit Service 54dbc3
 *********/
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_process_trap_repress
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_process_trap_repress
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This function handles method TrapRepress() for received MADs.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_process_trap_repress(IN osm_sm_mad_ctrl_t * p_ctrl,
Packit Service 54dbc3
					     IN osm_madw_t * p_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	ib_smp_t *p_smp;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	p_smp = osm_madw_get_smp_ptr(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Note that attr_id (like the rest of the MAD) is in
Packit Service 54dbc3
	   network byte order.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	switch (p_smp->attr_id) {
Packit Service 54dbc3
	case IB_MAD_ATTR_NOTICE:
Packit Service 54dbc3
		sm_mad_ctrl_update_wire_stats(p_ctrl);
Packit Service 54dbc3
		sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	default:
Packit Service 54dbc3
		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3105: "
Packit Service 54dbc3
			"Unsupported attribute 0x%X (%s)\n",
Packit Service 54dbc3
			cl_ntoh16(p_smp->attr_id),
Packit Service 54dbc3
			ib_get_sm_attr_str(p_smp->attr_id));
Packit Service 54dbc3
		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
Packit Service 54dbc3
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
static void log_rcv_cb_error(osm_log_t *p_log, ib_smp_t *p_smp, ib_net16_t status)
Packit Service 54dbc3
{
Packit Service 54dbc3
	char buf[BUF_SIZE];
Packit Service 54dbc3
	uint32_t i;
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR) {
Packit Service 54dbc3
		char ipath[IB_SUBNET_PATH_HOPS_MAX * 4];
Packit Service 54dbc3
		char rpath[IB_SUBNET_PATH_HOPS_MAX * 4];
Packit Service 54dbc3
		int ni = sprintf(ipath, "%d", p_smp->initial_path[0]);
Packit Service 54dbc3
		int nr = sprintf(rpath, "%d", p_smp->return_path[0]);
Packit Service 54dbc3
		for (i = 1; i <= p_smp->hop_count; i++) {
Packit Service 54dbc3
			ni += sprintf(ipath + ni, ",%d", p_smp->initial_path[i]);
Packit Service 54dbc3
			nr += sprintf(rpath + nr, ",%d", p_smp->return_path[i]);
Packit Service 54dbc3
		}
Packit Service 54dbc3
		snprintf(buf, sizeof(buf),
Packit Service 54dbc3
			 "\n\t\t\tInitial path: %s Return path: %s",
Packit Service 54dbc3
			 ipath, rpath);
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 3111: "
Packit Service 54dbc3
		"Received MAD with error status = 0x%X\n"
Packit Service 54dbc3
		"\t\t\t%s(%s), attr_mod 0x%x, TID 0x%" PRIx64 "%s\n",
Packit Service 54dbc3
		cl_ntoh16(status), ib_get_sm_method_str(p_smp->method),
Packit Service 54dbc3
		ib_get_sm_attr_str(p_smp->attr_id), cl_ntoh32(p_smp->attr_mod),
Packit Service 54dbc3
		cl_ntoh64(p_smp->trans_id),
Packit Service 54dbc3
		p_smp->mgmt_class == IB_MCLASS_SUBN_DIR ? buf : "");
Packit Service 54dbc3
Packit Service 54dbc3
	osm_dump_dr_smp_v2(p_log, p_smp, FILE_ID, OSM_LOG_VERBOSE);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/*
Packit Service 54dbc3
 * PARAMETERS
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * RETURN VALUES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * NOTES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SEE ALSO
Packit Service 54dbc3
 *********/
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_rcv_callback
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_rcv_callback
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This is the callback from the transport layer for received MADs.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw,
Packit Service 54dbc3
				     IN void *bind_context,
Packit Service 54dbc3
				     IN osm_madw_t * p_req_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_sm_mad_ctrl_t *p_ctrl = bind_context;
Packit Service 54dbc3
	ib_smp_t *p_smp;
Packit Service 54dbc3
	ib_net16_t status;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   A MAD was received from the wire, possibly in response to a request.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd);
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "%u QP0 MADs received\n",
Packit Service 54dbc3
		p_ctrl->p_stats->qp0_mads_rcvd);
Packit Service 54dbc3
Packit Service 54dbc3
	p_smp = osm_madw_get_smp_ptr(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	/* if we are closing down simply do nothing */
Packit Service 54dbc3
	if (osm_exit_flag) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR,
Packit Service 54dbc3
			"Ignoring received mad - since we are exiting\n");
Packit Service 54dbc3
Packit Service 54dbc3
		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_DEBUG);
Packit Service 54dbc3
Packit Service 54dbc3
		/* retire the mad or put it back */
Packit Service 54dbc3
		if (ib_smp_is_response(p_smp)) {
Packit Service 54dbc3
			CL_ASSERT(p_madw->resp_expected == FALSE);
Packit Service 54dbc3
			sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
Packit Service 54dbc3
		} else if (p_madw->resp_expected == TRUE)
Packit Service 54dbc3
			sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
Packit Service 54dbc3
		else
Packit Service 54dbc3
			osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	if (OSM_LOG_IS_ACTIVE_V2(p_ctrl->p_log, OSM_LOG_FRAMES))
Packit Service 54dbc3
		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_FRAMES);
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR)
Packit Service 54dbc3
		status = ib_smp_get_status(p_smp);
Packit Service 54dbc3
	else
Packit Service 54dbc3
		status = p_smp->status;
Packit Service 54dbc3
Packit Service 54dbc3
	if (status != 0)
Packit Service 54dbc3
		log_rcv_cb_error(p_ctrl->p_log, p_smp, status);
Packit Service 54dbc3
Packit Service 54dbc3
	switch (p_smp->method) {
Packit Service 54dbc3
	case IB_MAD_METHOD_GET_RESP:
Packit Service 54dbc3
		CL_ASSERT(p_req_madw != NULL);
Packit Service 54dbc3
		sm_mad_ctrl_process_get_resp(p_ctrl, p_madw, p_req_madw);
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_METHOD_GET:
Packit Service 54dbc3
		CL_ASSERT(p_req_madw == NULL);
Packit Service 54dbc3
		sm_mad_ctrl_process_get(p_ctrl, p_madw);
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_METHOD_TRAP:
Packit Service 54dbc3
		CL_ASSERT(p_req_madw == NULL);
Packit Service 54dbc3
		sm_mad_ctrl_process_trap(p_ctrl, p_madw);
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_METHOD_SET:
Packit Service 54dbc3
		CL_ASSERT(p_req_madw == NULL);
Packit Service 54dbc3
		sm_mad_ctrl_process_set(p_ctrl, p_madw);
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_METHOD_TRAP_REPRESS:
Packit Service 54dbc3
		CL_ASSERT(p_req_madw != NULL);
Packit Service 54dbc3
		sm_mad_ctrl_process_trap_repress(p_ctrl, p_madw);
Packit Service 54dbc3
		break;
Packit Service 54dbc3
	case IB_MAD_METHOD_SEND:
Packit Service 54dbc3
	case IB_MAD_METHOD_REPORT:
Packit Service 54dbc3
	case IB_MAD_METHOD_REPORT_RESP:
Packit Service 54dbc3
	default:
Packit Service 54dbc3
		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3112: "
Packit Service 54dbc3
			"Unsupported method = 0x%X\n", p_smp->method);
Packit Service 54dbc3
		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
Packit Service 54dbc3
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/*
Packit Service 54dbc3
 * PARAMETERS
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * RETURN VALUES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * NOTES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SEE ALSO
Packit Service 54dbc3
 *********/
Packit Service 54dbc3
Packit Service 54dbc3
/****f* opensm: SM/sm_mad_ctrl_send_err_cb
Packit Service 54dbc3
 * NAME
Packit Service 54dbc3
 * sm_mad_ctrl_send_err_cb
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * DESCRIPTION
Packit Service 54dbc3
 * This is the callback from the transport layer for send errors
Packit Service 54dbc3
 * on MADs that were expecting a response.
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SYNOPSIS
Packit Service 54dbc3
 */
Packit Service 54dbc3
static void sm_mad_ctrl_send_err_cb(IN void *context, IN osm_madw_t * p_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_sm_mad_ctrl_t *p_ctrl = context;
Packit Service 54dbc3
	ib_api_status_t status;
Packit Service 54dbc3
	ib_smp_t *p_smp;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	p_smp = osm_madw_get_smp_ptr(p_madw);
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3113: "
Packit Service 54dbc3
		"MAD completed in error (%s): "
Packit Service 54dbc3
		"%s(%s), attr_mod 0x%x, TID 0x%" PRIx64 "\n",
Packit Service 54dbc3
		ib_get_err_str(p_madw->status),
Packit Service 54dbc3
		ib_get_sm_method_str(p_smp->method),
Packit Service 54dbc3
		ib_get_sm_attr_str(p_smp->attr_id), cl_ntoh32(p_smp->attr_mod),
Packit Service 54dbc3
		cl_ntoh64(p_smp->trans_id));
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   If this was a SubnSet MAD, then this error might indicate a problem
Packit Service 54dbc3
	   in configuring the subnet. In this case - need to mark that there was
Packit Service 54dbc3
	   such a problem. The subnet will not be up, and the next sweep should
Packit Service 54dbc3
	   be a heavy sweep as well.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	if (p_smp->method == IB_MAD_METHOD_SET &&
Packit Service 54dbc3
	    (p_smp->attr_id == IB_MAD_ATTR_PORT_INFO ||
Packit Service 54dbc3
	     p_smp->attr_id == IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO ||
Packit Service 54dbc3
	     p_smp->attr_id == IB_MAD_ATTR_MCAST_FWD_TBL ||
Packit Service 54dbc3
	     p_smp->attr_id == IB_MAD_ATTR_SWITCH_INFO ||
Packit Service 54dbc3
	     p_smp->attr_id == IB_MAD_ATTR_LIN_FWD_TBL ||
Packit Service 54dbc3
	     p_smp->attr_id == IB_MAD_ATTR_P_KEY_TABLE)) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3119: "
Packit Service 54dbc3
			"Set method failed for attribute 0x%X (%s)\n",
Packit Service 54dbc3
			cl_ntoh16(p_smp->attr_id),
Packit Service 54dbc3
			ib_get_sm_attr_str(p_smp->attr_id));
Packit Service 54dbc3
		p_ctrl->p_subn->subnet_initialization_error = TRUE;
Packit Service 54dbc3
	} else if (p_madw->status == IB_TIMEOUT &&
Packit Service 54dbc3
		   p_smp->method == IB_MAD_METHOD_GET) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3120: "
Packit Service 54dbc3
			"Timeout while getting attribute 0x%X (%s); "
Packit Service 54dbc3
			"Possible mis-set mkey?\n",
Packit Service 54dbc3
			cl_ntoh16(p_smp->attr_id),
Packit Service 54dbc3
			ib_get_sm_attr_str(p_smp->attr_id));
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_VERBOSE);
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Since we did not get any response we suspect the DR path
Packit Service 54dbc3
	   used for the target port.
Packit Service 54dbc3
	   Find it and replace it with an alternate path.
Packit Service 54dbc3
	   This is true only if the destination lid is not 0xFFFF, since
Packit Service 54dbc3
	   then we are aiming for a specific path and not specific destination
Packit Service 54dbc3
	   lid.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	/* For now - do not add the alternate dr path to the release */
Packit Service 54dbc3
#if 0
Packit Service 54dbc3
	if (p_madw->mad_addr.dest_lid != 0xFFFF) {
Packit Service 54dbc3
		osm_physp_t *p_physp = osm_get_physp_by_mad_addr(p_ctrl->p_log,
Packit Service 54dbc3
								 p_ctrl->p_subn,
Packit Service 54dbc3
								 &(p_madw->
Packit Service 54dbc3
								   mad_addr));
Packit Service 54dbc3
		if (!p_physp) {
Packit Service 54dbc3
			OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3114: "
Packit Service 54dbc3
				"Failed to find the corresponding phys port\n");
Packit Service 54dbc3
		} else {
Packit Service 54dbc3
			osm_physp_replace_dr_path_with_alternate_dr_path
Packit Service 54dbc3
			    (p_ctrl->p_log, p_ctrl->p_subn, p_physp,
Packit Service 54dbc3
			     p_madw->h_bind);
Packit Service 54dbc3
		}
Packit Service 54dbc3
	}
Packit Service 54dbc3
#endif
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   An error occurred.  No response was received to a request MAD.
Packit Service 54dbc3
	   Retire the original request MAD.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	sm_mad_ctrl_update_wire_stats(p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	if (osm_madw_get_err_msg(p_madw) != CL_DISP_MSGID_NONE) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
			"Posting Dispatcher message %s\n",
Packit Service 54dbc3
			osm_get_disp_msg_str(osm_madw_get_err_msg(p_madw)));
Packit Service 54dbc3
Packit Service 54dbc3
		status = cl_disp_post(p_ctrl->h_disp,
Packit Service 54dbc3
				      osm_madw_get_err_msg(p_madw), p_madw,
Packit Service 54dbc3
				      sm_mad_ctrl_disp_done_callback, p_ctrl);
Packit Service 54dbc3
		if (status != CL_SUCCESS)
Packit Service 54dbc3
			OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3115: "
Packit Service 54dbc3
				"Dispatcher post message failed (%s)\n",
Packit Service 54dbc3
				CL_STATUS_MSG(status));
Packit Service 54dbc3
	} else
Packit Service 54dbc3
		/*
Packit Service 54dbc3
		   No error message was provided, just retire the MAD.
Packit Service 54dbc3
		 */
Packit Service 54dbc3
		sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/*
Packit Service 54dbc3
 * PARAMETERS
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * RETURN VALUES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * NOTES
Packit Service 54dbc3
 *
Packit Service 54dbc3
 * SEE ALSO
Packit Service 54dbc3
 *********/
Packit Service 54dbc3
Packit Service 54dbc3
void osm_sm_mad_ctrl_construct(IN osm_sm_mad_ctrl_t * p_ctrl)
Packit Service 54dbc3
{
Packit Service 54dbc3
	CL_ASSERT(p_ctrl);
Packit Service 54dbc3
	memset(p_ctrl, 0, sizeof(*p_ctrl));
Packit Service 54dbc3
	p_ctrl->h_disp = CL_DISP_INVALID_HANDLE;
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
void osm_sm_mad_ctrl_destroy(IN osm_sm_mad_ctrl_t * p_ctrl)
Packit Service 54dbc3
{
Packit Service 54dbc3
	CL_ASSERT(p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_ctrl->h_bind != CL_DISP_INVALID_HANDLE)
Packit Service 54dbc3
		osm_vendor_unbind(p_ctrl->h_bind);
Packit Service 54dbc3
	cl_disp_unregister(p_ctrl->h_disp);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
ib_api_status_t osm_sm_mad_ctrl_init(IN osm_sm_mad_ctrl_t * p_ctrl,
Packit Service 54dbc3
				     IN osm_subn_t * p_subn,
Packit Service 54dbc3
				     IN osm_mad_pool_t * p_mad_pool,
Packit Service 54dbc3
				     IN osm_vl15_t * p_vl15,
Packit Service 54dbc3
				     IN osm_vendor_t * p_vendor,
Packit Service 54dbc3
				     IN osm_log_t * p_log,
Packit Service 54dbc3
				     IN osm_stats_t * p_stats,
Packit Service 54dbc3
				     IN cl_plock_t * p_lock,
Packit Service 54dbc3
				     IN cl_dispatcher_t * p_disp)
Packit Service 54dbc3
{
Packit Service 54dbc3
	ib_api_status_t status = IB_SUCCESS;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	osm_sm_mad_ctrl_construct(p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	p_ctrl->p_subn = p_subn;
Packit Service 54dbc3
	p_ctrl->p_log = p_log;
Packit Service 54dbc3
	p_ctrl->p_disp = p_disp;
Packit Service 54dbc3
	p_ctrl->p_mad_pool = p_mad_pool;
Packit Service 54dbc3
	p_ctrl->p_vendor = p_vendor;
Packit Service 54dbc3
	p_ctrl->p_stats = p_stats;
Packit Service 54dbc3
	p_ctrl->p_lock = p_lock;
Packit Service 54dbc3
	p_ctrl->p_vl15 = p_vl15;
Packit Service 54dbc3
Packit Service 54dbc3
	p_ctrl->h_disp = cl_disp_register(p_disp, CL_DISP_MSGID_NONE, NULL,
Packit Service 54dbc3
					  NULL);
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_ctrl->h_disp == CL_DISP_INVALID_HANDLE) {
Packit Service 54dbc3
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 3116: "
Packit Service 54dbc3
			"Dispatcher registration failed\n");
Packit Service 54dbc3
		status = IB_INSUFFICIENT_RESOURCES;
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(p_log);
Packit Service 54dbc3
	return status;
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
ib_api_status_t osm_sm_mad_ctrl_bind(IN osm_sm_mad_ctrl_t * p_ctrl,
Packit Service 54dbc3
				     IN ib_net64_t port_guid)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_bind_info_t bind_info;
Packit Service 54dbc3
	ib_api_status_t status = IB_SUCCESS;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(p_ctrl->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_ctrl->h_bind != OSM_BIND_INVALID_HANDLE) {
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3117: "
Packit Service 54dbc3
			"Multiple binds not allowed\n");
Packit Service 54dbc3
		status = IB_ERROR;
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	bind_info.class_version = 1;
Packit Service 54dbc3
	bind_info.is_report_processor = FALSE;
Packit Service 54dbc3
	bind_info.is_responder = TRUE;
Packit Service 54dbc3
	bind_info.is_trap_processor = TRUE;
Packit Service 54dbc3
	bind_info.mad_class = IB_MCLASS_SUBN_DIR;
Packit Service 54dbc3
	bind_info.port_guid = port_guid;
Packit Service 54dbc3
	bind_info.recv_q_size = OSM_SM_DEFAULT_QP0_RCV_SIZE;
Packit Service 54dbc3
	bind_info.send_q_size = OSM_SM_DEFAULT_QP0_SEND_SIZE;
Packit Service 54dbc3
	bind_info.timeout = p_ctrl->p_subn->opt.transaction_timeout;
Packit Service 54dbc3
	bind_info.retries = p_ctrl->p_subn->opt.transaction_retries;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
Packit Service 54dbc3
		"Binding to port 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
Packit Service 54dbc3
Packit Service 54dbc3
	p_ctrl->h_bind = osm_vendor_bind(p_ctrl->p_vendor, &bind_info,
Packit Service 54dbc3
					 p_ctrl->p_mad_pool,
Packit Service 54dbc3
					 sm_mad_ctrl_rcv_callback,
Packit Service 54dbc3
					 sm_mad_ctrl_send_err_cb, p_ctrl);
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_ctrl->h_bind == OSM_BIND_INVALID_HANDLE) {
Packit Service 54dbc3
		status = IB_ERROR;
Packit Service 54dbc3
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3118: "
Packit Service 54dbc3
			"Vendor specific bind failed\n");
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(p_ctrl->p_log);
Packit Service 54dbc3
	return status;
Packit Service 54dbc3
}