Blame opensm/osm_sa_class_port_info.c

Packit Service 54dbc3
/*
Packit Service 54dbc3
 * Copyright (c) 2004-2008 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) 2013 Oracle and/or its affiliates. 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_cpi_rcv_t.
Packit Service 54dbc3
 * This object represents the ClassPortInfo Receiver 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 <iba/ib_types.h>
Packit Service 54dbc3
#include <complib/cl_qmap.h>
Packit Service 54dbc3
#include <complib/cl_passivelock.h>
Packit Service 54dbc3
#include <complib/cl_debug.h>
Packit Service 54dbc3
#include <complib/cl_qlist.h>
Packit Service 54dbc3
#include <opensm/osm_file_ids.h>
Packit Service 54dbc3
#define FILE_ID OSM_FILE_SA_CLASS_PORT_INFO_C
Packit Service 54dbc3
#include <vendor/osm_vendor_api.h>
Packit Service 54dbc3
#include <opensm/osm_helper.h>
Packit Service 54dbc3
#include <opensm/osm_sa.h>
Packit Service 54dbc3
Packit Service 54dbc3
#define MAX_MSECS_TO_RTV 24
Packit Service 54dbc3
/* Precalculated table in msec (index is related to encoded value) */
Packit Service 54dbc3
/* 4.096 usec * 2 ** n (where n = 8 - 31) */
Packit Service 54dbc3
const static uint32_t msecs_to_rtv_table[MAX_MSECS_TO_RTV] = {
Packit Service 54dbc3
	1, 2, 4, 8,
Packit Service 54dbc3
	16, 33, 67, 134,
Packit Service 54dbc3
	268, 536, 1073, 2147,
Packit Service 54dbc3
	4294, 8589, 17179, 34359,
Packit Service 54dbc3
	68719, 137438, 274877, 549755,
Packit Service 54dbc3
	1099511, 2199023, 4398046, 8796093
Packit Service 54dbc3
};
Packit Service 54dbc3
Packit Service 54dbc3
static void cpi_rcv_respond(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_madw_t *p_resp_madw;
Packit Service 54dbc3
	const ib_sa_mad_t *p_sa_mad;
Packit Service 54dbc3
	ib_sa_mad_t *p_resp_sa_mad;
Packit Service 54dbc3
	ib_class_port_info_t *p_resp_cpi;
Packit Service 54dbc3
	ib_gid_t zero_gid;
Packit Service 54dbc3
	uint32_t cap_mask2;
Packit Service 54dbc3
	uint8_t rtv;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(sa->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	memset(&zero_gid, 0, sizeof(ib_gid_t));
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Get a MAD to reply. Address of Mad is in the received mad_wrapper
Packit Service 54dbc3
	 */
Packit Service 54dbc3
	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
Packit Service 54dbc3
				       MAD_BLOCK_SIZE, &p_madw->mad_addr);
Packit Service 54dbc3
	if (!p_resp_madw) {
Packit Service 54dbc3
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1408: "
Packit Service 54dbc3
			"Unable to allocate MAD\n");
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
Packit Service 54dbc3
	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE);
Packit Service 54dbc3
	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
Packit Service 54dbc3
	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
Packit Service 54dbc3
	p_resp_sa_mad->sm_key = 0;
Packit Service 54dbc3
Packit Service 54dbc3
	p_resp_cpi =
Packit Service 54dbc3
	    (ib_class_port_info_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
Packit Service 54dbc3
Packit Service 54dbc3
	/* finally do it (the job) man ! */
Packit Service 54dbc3
	p_resp_cpi->base_ver = 1;
Packit Service 54dbc3
	p_resp_cpi->class_ver = 2;
Packit Service 54dbc3
	/* Calculate encoded response time value */
Packit Service 54dbc3
	/* transaction timeout is in msec */
Packit Service 54dbc3
	if (sa->p_subn->opt.transaction_timeout >
Packit Service 54dbc3
	    msecs_to_rtv_table[MAX_MSECS_TO_RTV - 1])
Packit Service 54dbc3
		rtv = MAX_MSECS_TO_RTV - 1;
Packit Service 54dbc3
	else {
Packit Service 54dbc3
		for (rtv = 0; rtv < MAX_MSECS_TO_RTV; rtv++) {
Packit Service 54dbc3
			if (sa->p_subn->opt.transaction_timeout <=
Packit Service 54dbc3
			    msecs_to_rtv_table[rtv])
Packit Service 54dbc3
				break;
Packit Service 54dbc3
		}
Packit Service 54dbc3
	}
Packit Service 54dbc3
	rtv += 8;
Packit Service 54dbc3
	ib_class_set_resp_time_val(p_resp_cpi, rtv);
Packit Service 54dbc3
	p_resp_cpi->redir_gid = zero_gid;
Packit Service 54dbc3
	p_resp_cpi->redir_tc_sl_fl = 0;
Packit Service 54dbc3
	p_resp_cpi->redir_lid = 0;
Packit Service 54dbc3
	p_resp_cpi->redir_pkey = 0;
Packit Service 54dbc3
	p_resp_cpi->redir_qp = CL_NTOH32(1);
Packit Service 54dbc3
	p_resp_cpi->redir_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
Packit Service 54dbc3
	p_resp_cpi->trap_gid = zero_gid;
Packit Service 54dbc3
	p_resp_cpi->trap_tc_sl_fl = 0;
Packit Service 54dbc3
	p_resp_cpi->trap_lid = 0;
Packit Service 54dbc3
	p_resp_cpi->trap_pkey = 0;
Packit Service 54dbc3
	p_resp_cpi->trap_hop_qp = 0;
Packit Service 54dbc3
	p_resp_cpi->trap_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
Packit Service 54dbc3
Packit Service 54dbc3
	/* set specific capability mask bits */
Packit Service 54dbc3
	/* we do not support the following options/optional records:
Packit Service 54dbc3
	   OSM_CAP_IS_SUBN_OPT_RECS_SUP :
Packit Service 54dbc3
	   RandomForwardingTableRecord,
Packit Service 54dbc3
	   ServiceAssociationRecord
Packit Service 54dbc3
	   other optional records supported "under the table"
Packit Service 54dbc3
Packit Service 54dbc3
	   OSM_CAP_IS_MULTIPATH_SUP:
Packit Service 54dbc3
	   TraceRecord
Packit Service 54dbc3
Packit Service 54dbc3
	   OSM_CAP_IS_REINIT_SUP:
Packit Service 54dbc3
	   For reinitialization functionality.
Packit Service 54dbc3
Packit Service 54dbc3
	   So not sending traps, but supporting Get(Notice) and Set(Notice).
Packit Service 54dbc3
	 */
Packit Service 54dbc3
Packit Service 54dbc3
	/* Note host notation replaced later */
Packit Service 54dbc3
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
Packit Service 54dbc3
	p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP |
Packit Service 54dbc3
	    OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED |
Packit Service 54dbc3
	    OSM_CAP_IS_MULTIPATH_SUP;
Packit Service 54dbc3
#else
Packit Service 54dbc3
	p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP |
Packit Service 54dbc3
	    OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED;
Packit Service 54dbc3
#endif
Packit Service 54dbc3
	cap_mask2 = OSM_CAP2_IS_FULL_PORTINFO_REC_SUPPORTED |
Packit Service 54dbc3
		    OSM_CAP2_IS_EXTENDED_SPEEDS_SUPPORTED |
Packit Service 54dbc3
		    OSM_CAP2_IS_ALIAS_GUIDS_SUPPORTED |
Packit Service 54dbc3
		    OSM_CAP2_IS_MULTICAST_SERVICE_RECS_SUPPORTED |
Packit Service 54dbc3
		    OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED |
Packit Service 54dbc3
		    OSM_CAP2_IS_SEND_ONLY_FULL_MEMBER_SUPPORTED |
Packit Service 54dbc3
		    OSM_CAP2_IS_LINK_WIDTH_2X_SUPPORTED |
Packit Service 54dbc3
		    OSM_CAP2_IS_LINK_SPEED_HDR_SUPPORTED;
Packit Service 54dbc3
	if (sa->p_subn->opt.use_mfttop)
Packit Service 54dbc3
		cap_mask2 |= OSM_CAP2_IS_MCAST_TOP_SUPPORTED;
Packit Service 54dbc3
	if (sa->p_subn->opt.qos)
Packit Service 54dbc3
		cap_mask2 |= OSM_CAP2_IS_QOS_SUPPORTED;
Packit Service 54dbc3
	ib_class_set_cap_mask2(p_resp_cpi, cap_mask2);
Packit Service 54dbc3
Packit Service 54dbc3
	if (!sa->p_subn->opt.disable_multicast)
Packit Service 54dbc3
		p_resp_cpi->cap_mask |= OSM_CAP_IS_UD_MCAST_SUP;
Packit Service 54dbc3
	p_resp_cpi->cap_mask = cl_hton16(p_resp_cpi->cap_mask);
Packit Service 54dbc3
Packit Service 54dbc3
	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_FRAMES))
Packit Service 54dbc3
		osm_dump_sa_mad_v2(sa->p_log, p_resp_sa_mad, FILE_ID, OSM_LOG_FRAMES);
Packit Service 54dbc3
Packit Service 54dbc3
	osm_sa_send(sa, p_resp_madw, FALSE);
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(sa->p_log);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/**********************************************************************
Packit Service 54dbc3
 * This code actually handles the call
Packit Service 54dbc3
 **********************************************************************/
Packit Service 54dbc3
void osm_cpi_rcv_process(IN void *context, IN void *data)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_sa_t *sa = context;
Packit Service 54dbc3
	osm_madw_t *p_madw = data;
Packit Service 54dbc3
	const ib_sa_mad_t *p_sa_mad;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(sa->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	/* we only support GET */
Packit Service 54dbc3
	if (p_sa_mad->method != IB_MAD_METHOD_GET) {
Packit Service 54dbc3
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1403: "
Packit Service 54dbc3
			"Unsupported Method (%s) for ClassPortInfo request\n",
Packit Service 54dbc3
			ib_get_sa_method_str(p_sa_mad->method));
Packit Service 54dbc3
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO);
Packit Service 54dbc3
Packit Service 54dbc3
	/* CLASS PORT INFO does not really look at the SMDB - no lock required. */
Packit Service 54dbc3
Packit Service 54dbc3
	cpi_rcv_respond(sa, p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(sa->p_log);
Packit Service 54dbc3
}