Blame opensm/osm_sa_class_port_info.c

Packit 13e616
/*
Packit 13e616
 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
Packit 13e616
 * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
Packit 13e616
 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
Packit 13e616
 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
Packit 13e616
 *
Packit 13e616
 * This software is available to you under a choice of one of two
Packit 13e616
 * licenses.  You may choose to be licensed under the terms of the GNU
Packit 13e616
 * General Public License (GPL) Version 2, available from the file
Packit 13e616
 * COPYING in the main directory of this source tree, or the
Packit 13e616
 * OpenIB.org BSD license below:
Packit 13e616
 *
Packit 13e616
 *     Redistribution and use in source and binary forms, with or
Packit 13e616
 *     without modification, are permitted provided that the following
Packit 13e616
 *     conditions are met:
Packit 13e616
 *
Packit 13e616
 *      - Redistributions of source code must retain the above
Packit 13e616
 *        copyright notice, this list of conditions and the following
Packit 13e616
 *        disclaimer.
Packit 13e616
 *
Packit 13e616
 *      - Redistributions in binary form must reproduce the above
Packit 13e616
 *        copyright notice, this list of conditions and the following
Packit 13e616
 *        disclaimer in the documentation and/or other materials
Packit 13e616
 *        provided with the distribution.
Packit 13e616
 *
Packit 13e616
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Packit 13e616
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit 13e616
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Packit 13e616
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
Packit 13e616
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
Packit 13e616
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit 13e616
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
Packit 13e616
 * SOFTWARE.
Packit 13e616
 *
Packit 13e616
 */
Packit 13e616
Packit 13e616
/*
Packit 13e616
 * Abstract:
Packit 13e616
 *    Implementation of osm_cpi_rcv_t.
Packit 13e616
 * This object represents the ClassPortInfo Receiver object.
Packit 13e616
 * This object is part of the opensm family of objects.
Packit 13e616
 */
Packit 13e616
Packit 13e616
#if HAVE_CONFIG_H
Packit 13e616
#  include <config.h>
Packit 13e616
#endif				/* HAVE_CONFIG_H */
Packit 13e616
Packit 13e616
#include <string.h>
Packit 13e616
#include <iba/ib_types.h>
Packit 13e616
#include <complib/cl_qmap.h>
Packit 13e616
#include <complib/cl_passivelock.h>
Packit 13e616
#include <complib/cl_debug.h>
Packit 13e616
#include <complib/cl_qlist.h>
Packit 13e616
#include <opensm/osm_file_ids.h>
Packit 13e616
#define FILE_ID OSM_FILE_SA_CLASS_PORT_INFO_C
Packit 13e616
#include <vendor/osm_vendor_api.h>
Packit 13e616
#include <opensm/osm_helper.h>
Packit 13e616
#include <opensm/osm_sa.h>
Packit 13e616
Packit 13e616
#define MAX_MSECS_TO_RTV 24
Packit 13e616
/* Precalculated table in msec (index is related to encoded value) */
Packit 13e616
/* 4.096 usec * 2 ** n (where n = 8 - 31) */
Packit 13e616
const static uint32_t msecs_to_rtv_table[MAX_MSECS_TO_RTV] = {
Packit 13e616
	1, 2, 4, 8,
Packit 13e616
	16, 33, 67, 134,
Packit 13e616
	268, 536, 1073, 2147,
Packit 13e616
	4294, 8589, 17179, 34359,
Packit 13e616
	68719, 137438, 274877, 549755,
Packit 13e616
	1099511, 2199023, 4398046, 8796093
Packit 13e616
};
Packit 13e616
Packit 13e616
static void cpi_rcv_respond(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
Packit 13e616
{
Packit 13e616
	osm_madw_t *p_resp_madw;
Packit 13e616
	const ib_sa_mad_t *p_sa_mad;
Packit 13e616
	ib_sa_mad_t *p_resp_sa_mad;
Packit 13e616
	ib_class_port_info_t *p_resp_cpi;
Packit 13e616
	ib_gid_t zero_gid;
Packit 13e616
	uint32_t cap_mask2;
Packit 13e616
	uint8_t rtv;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(sa->p_log);
Packit 13e616
Packit 13e616
	memset(&zero_gid, 0, sizeof(ib_gid_t));
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	   Get a MAD to reply. Address of Mad is in the received mad_wrapper
Packit 13e616
	 */
Packit 13e616
	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
Packit 13e616
				       MAD_BLOCK_SIZE, &p_madw->mad_addr);
Packit 13e616
	if (!p_resp_madw) {
Packit 13e616
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1408: "
Packit 13e616
			"Unable to allocate MAD\n");
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
Packit 13e616
	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
Packit 13e616
Packit 13e616
	memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE);
Packit 13e616
	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
Packit 13e616
	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
Packit 13e616
	p_resp_sa_mad->sm_key = 0;
Packit 13e616
Packit 13e616
	p_resp_cpi =
Packit 13e616
	    (ib_class_port_info_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
Packit 13e616
Packit 13e616
	/* finally do it (the job) man ! */
Packit 13e616
	p_resp_cpi->base_ver = 1;
Packit 13e616
	p_resp_cpi->class_ver = 2;
Packit 13e616
	/* Calculate encoded response time value */
Packit 13e616
	/* transaction timeout is in msec */
Packit 13e616
	if (sa->p_subn->opt.transaction_timeout >
Packit 13e616
	    msecs_to_rtv_table[MAX_MSECS_TO_RTV - 1])
Packit 13e616
		rtv = MAX_MSECS_TO_RTV - 1;
Packit 13e616
	else {
Packit 13e616
		for (rtv = 0; rtv < MAX_MSECS_TO_RTV; rtv++) {
Packit 13e616
			if (sa->p_subn->opt.transaction_timeout <=
Packit 13e616
			    msecs_to_rtv_table[rtv])
Packit 13e616
				break;
Packit 13e616
		}
Packit 13e616
	}
Packit 13e616
	rtv += 8;
Packit 13e616
	ib_class_set_resp_time_val(p_resp_cpi, rtv);
Packit 13e616
	p_resp_cpi->redir_gid = zero_gid;
Packit 13e616
	p_resp_cpi->redir_tc_sl_fl = 0;
Packit 13e616
	p_resp_cpi->redir_lid = 0;
Packit 13e616
	p_resp_cpi->redir_pkey = 0;
Packit 13e616
	p_resp_cpi->redir_qp = CL_NTOH32(1);
Packit 13e616
	p_resp_cpi->redir_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
Packit 13e616
	p_resp_cpi->trap_gid = zero_gid;
Packit 13e616
	p_resp_cpi->trap_tc_sl_fl = 0;
Packit 13e616
	p_resp_cpi->trap_lid = 0;
Packit 13e616
	p_resp_cpi->trap_pkey = 0;
Packit 13e616
	p_resp_cpi->trap_hop_qp = 0;
Packit 13e616
	p_resp_cpi->trap_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
Packit 13e616
Packit 13e616
	/* set specific capability mask bits */
Packit 13e616
	/* we do not support the following options/optional records:
Packit 13e616
	   OSM_CAP_IS_SUBN_OPT_RECS_SUP :
Packit 13e616
	   RandomForwardingTableRecord,
Packit 13e616
	   ServiceAssociationRecord
Packit 13e616
	   other optional records supported "under the table"
Packit 13e616
Packit 13e616
	   OSM_CAP_IS_MULTIPATH_SUP:
Packit 13e616
	   TraceRecord
Packit 13e616
Packit 13e616
	   OSM_CAP_IS_REINIT_SUP:
Packit 13e616
	   For reinitialization functionality.
Packit 13e616
Packit 13e616
	   So not sending traps, but supporting Get(Notice) and Set(Notice).
Packit 13e616
	 */
Packit 13e616
Packit 13e616
	/* Note host notation replaced later */
Packit 13e616
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
Packit 13e616
	p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP |
Packit 13e616
	    OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED |
Packit 13e616
	    OSM_CAP_IS_MULTIPATH_SUP;
Packit 13e616
#else
Packit 13e616
	p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP |
Packit 13e616
	    OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED;
Packit 13e616
#endif
Packit 13e616
	cap_mask2 = OSM_CAP2_IS_FULL_PORTINFO_REC_SUPPORTED |
Packit 13e616
		    OSM_CAP2_IS_EXTENDED_SPEEDS_SUPPORTED |
Packit 13e616
		    OSM_CAP2_IS_ALIAS_GUIDS_SUPPORTED |
Packit 13e616
		    OSM_CAP2_IS_MULTICAST_SERVICE_RECS_SUPPORTED |
Packit 13e616
		    OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED |
Packit 13e616
		    OSM_CAP2_IS_SEND_ONLY_FULL_MEMBER_SUPPORTED |
Packit 13e616
		    OSM_CAP2_IS_LINK_WIDTH_2X_SUPPORTED |
Packit 13e616
		    OSM_CAP2_IS_LINK_SPEED_HDR_SUPPORTED;
Packit 13e616
	if (sa->p_subn->opt.use_mfttop)
Packit 13e616
		cap_mask2 |= OSM_CAP2_IS_MCAST_TOP_SUPPORTED;
Packit 13e616
	if (sa->p_subn->opt.qos)
Packit 13e616
		cap_mask2 |= OSM_CAP2_IS_QOS_SUPPORTED;
Packit 13e616
	ib_class_set_cap_mask2(p_resp_cpi, cap_mask2);
Packit 13e616
Packit 13e616
	if (!sa->p_subn->opt.disable_multicast)
Packit 13e616
		p_resp_cpi->cap_mask |= OSM_CAP_IS_UD_MCAST_SUP;
Packit 13e616
	p_resp_cpi->cap_mask = cl_hton16(p_resp_cpi->cap_mask);
Packit 13e616
Packit 13e616
	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_FRAMES))
Packit 13e616
		osm_dump_sa_mad_v2(sa->p_log, p_resp_sa_mad, FILE_ID, OSM_LOG_FRAMES);
Packit 13e616
Packit 13e616
	osm_sa_send(sa, p_resp_madw, FALSE);
Packit 13e616
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(sa->p_log);
Packit 13e616
}
Packit 13e616
Packit 13e616
/**********************************************************************
Packit 13e616
 * This code actually handles the call
Packit 13e616
 **********************************************************************/
Packit 13e616
void osm_cpi_rcv_process(IN void *context, IN void *data)
Packit 13e616
{
Packit 13e616
	osm_sa_t *sa = context;
Packit 13e616
	osm_madw_t *p_madw = data;
Packit 13e616
	const ib_sa_mad_t *p_sa_mad;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(sa->p_log);
Packit 13e616
Packit 13e616
	CL_ASSERT(p_madw);
Packit 13e616
Packit 13e616
	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
Packit 13e616
Packit 13e616
	/* we only support GET */
Packit 13e616
	if (p_sa_mad->method != IB_MAD_METHOD_GET) {
Packit 13e616
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1403: "
Packit 13e616
			"Unsupported Method (%s) for ClassPortInfo request\n",
Packit 13e616
			ib_get_sa_method_str(p_sa_mad->method));
Packit 13e616
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO);
Packit 13e616
Packit 13e616
	/* CLASS PORT INFO does not really look at the SMDB - no lock required. */
Packit 13e616
Packit 13e616
	cpi_rcv_respond(sa, p_madw);
Packit 13e616
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(sa->p_log);
Packit 13e616
}