static boolean_t sa_multipath_rec_is_tavor_port(IN const osm_port_t * p_port)
{
	osm_node_t const *p_node;
	ib_net32_t vend_id;

	p_node = p_port->p_node;
	vend_id = ib_node_info_get_vendor_id(&p_node->node_info);

	return ((p_node->node_info.device_id == CL_HTON16(23108)) &&
		((vend_id == CL_HTON32(OSM_VENDOR_ID_MELLANOX)) ||
		 (vend_id == CL_HTON32(OSM_VENDOR_ID_TOPSPIN)) ||
		 (vend_id == CL_HTON32(OSM_VENDOR_ID_SILVERSTORM)) ||
		 (vend_id == CL_HTON32(OSM_VENDOR_ID_VOLTAIRE))));
}
static void get_pkey_table(IN osm_log_t * p_log, IN osm_sm_t * sm,
			   IN osm_node_t * p_node, IN osm_physp_t * p_physp)
{

	osm_madw_context_t context;
	ib_api_status_t status;
	osm_dr_path_t path;
	osm_physp_t *physp0;
	ib_net64_t m_key;
	uint8_t port_num;
	uint16_t block_num, max_blocks;
	uint32_t attr_mod_ho;

	OSM_LOG_ENTER(p_log);

	path = *osm_physp_get_dr_path_ptr(p_physp);

	context.pkey_context.node_guid = osm_node_get_node_guid(p_node);
	context.pkey_context.port_guid = osm_physp_get_port_guid(p_physp);
	context.pkey_context.set_method = FALSE;

	port_num = p_physp->port_num;

	if (!p_node->sw || port_num == 0)
		/* The maximum blocks is defined by the node info partition cap
		   for CA, router, and switch management ports. */
		max_blocks =
		    (cl_ntoh16(p_node->node_info.partition_cap) +
		     IB_NUM_PKEY_ELEMENTS_IN_BLOCK - 1)
		    / IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
	else {
		/* This is a switch, and not a management port. The maximum blocks
		   is defined in the switch info partition enforcement cap. */

		/* Check for IBM eHCA firmware defect in reporting partition enforcement cap */
		if (cl_ntoh32(ib_node_info_get_vendor_id(&p_node->node_info)) ==
		    IBM_VENDOR_ID)
			p_node->sw->switch_info.enforce_cap = 0;

		/* Bail out if this is a switch with no partition enforcement capability */
		if (cl_ntoh16(p_node->sw->switch_info.enforce_cap) == 0)
			goto Exit;

		max_blocks = (cl_ntoh16(p_node->sw->switch_info.enforce_cap) +
			      IB_NUM_PKEY_ELEMENTS_IN_BLOCK -
			      1) / IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
	}

	p_physp->pkeys.rcv_blocks_cnt = max_blocks;
	for (block_num = 0; block_num < max_blocks; block_num++) {
		if (osm_node_get_type(p_node) != IB_NODE_TYPE_SWITCH ||
		    osm_physp_get_port_num(p_physp) == 0) {
			attr_mod_ho = block_num;
			m_key = ib_port_info_get_m_key(&p_physp->port_info);
		} else {
			attr_mod_ho = block_num | (port_num << 16);
			physp0 = osm_node_get_physp_ptr(p_node, 0);
			m_key = ib_port_info_get_m_key(&physp0->port_info);
		}
		status = osm_req_get(sm, &path, IB_MAD_ATTR_P_KEY_TABLE,
				     cl_hton32(attr_mod_ho), FALSE,
				     m_key, CL_DISP_MSGID_NONE, &context);

		if (status != IB_SUCCESS) {
			OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0F12: "
				"Failure initiating PKeyTable request (%s)\n",
				ib_get_err_str(status));
			goto Exit;
		}
	}

Exit:
	OSM_LOG_EXIT(p_log);
}
Example #3
0
static void dump_topology_node(cl_map_item_t * item, FILE * file, void *cxt)
{
	osm_node_t *p_node = (osm_node_t *) item;
	uint32_t cPort;
	osm_node_t *p_nbnode;
	osm_physp_t *p_physp, *p_default_physp, *p_rphysp;
	uint8_t link_speed_act;
	const char *link_speed_act_str;

	if (!p_node->node_info.num_ports)
		return;

	for (cPort = 1; cPort < osm_node_get_num_physp(p_node); cPort++) {
		uint8_t port_state;

		p_physp = osm_node_get_physp_ptr(p_node, cPort);
		if (!p_physp)
			continue;

		p_rphysp = p_physp->p_remote_physp;
		if (!p_rphysp)
			continue;

		CL_ASSERT(cPort == p_physp->port_num);

		if (p_node->node_info.node_type == IB_NODE_TYPE_SWITCH)
			p_default_physp = osm_node_get_physp_ptr(p_node, 0);
		else
			p_default_physp = p_physp;

		fprintf(file, "{ %s%s Ports:%02X SystemGUID:%016" PRIx64
			" NodeGUID:%016" PRIx64 " PortGUID:%016" PRIx64
			" VenID:%06X DevID:%04X Rev:%08X {%s} LID:%04X PN:%02X } ",
			p_node->node_info.node_type == IB_NODE_TYPE_SWITCH ?
			"SW" : p_node->node_info.node_type ==
			IB_NODE_TYPE_CA ? "CA" : p_node->node_info.node_type ==
			IB_NODE_TYPE_ROUTER ? "Rt" : "**",
			p_default_physp->port_info.base_lid ==
			p_default_physp->port_info.
			master_sm_base_lid ? "-SM" : "",
			p_node->node_info.num_ports,
			cl_ntoh64(p_node->node_info.sys_guid),
			cl_ntoh64(p_node->node_info.node_guid),
			cl_ntoh64(p_physp->port_guid),
			cl_ntoh32(ib_node_info_get_vendor_id
				  (&p_node->node_info)),
			cl_ntoh16(p_node->node_info.device_id),
			cl_ntoh32(p_node->node_info.revision),
			p_node->print_desc,
			cl_ntoh16(p_default_physp->port_info.base_lid), cPort);

		p_nbnode = p_rphysp->p_node;

		if (p_nbnode->node_info.node_type == IB_NODE_TYPE_SWITCH)
			p_default_physp = osm_node_get_physp_ptr(p_nbnode, 0);
		else
			p_default_physp = p_rphysp;

		fprintf(file, "{ %s%s Ports:%02X SystemGUID:%016" PRIx64
			" NodeGUID:%016" PRIx64 " PortGUID:%016" PRIx64
			" VenID:%08X DevID:%04X Rev:%08X {%s} LID:%04X PN:%02X } ",
			p_nbnode->node_info.node_type == IB_NODE_TYPE_SWITCH ?
			"SW" : p_nbnode->node_info.node_type ==
			IB_NODE_TYPE_CA ? "CA" :
			p_nbnode->node_info.node_type == IB_NODE_TYPE_ROUTER ?
			"Rt" : "**",
			p_default_physp->port_info.base_lid ==
			p_default_physp->port_info.
			master_sm_base_lid ? "-SM" : "",
			p_nbnode->node_info.num_ports,
			cl_ntoh64(p_nbnode->node_info.sys_guid),
			cl_ntoh64(p_nbnode->node_info.node_guid),
			cl_ntoh64(p_rphysp->port_guid),
			cl_ntoh32(ib_node_info_get_vendor_id
				  (&p_nbnode->node_info)),
			cl_ntoh32(p_nbnode->node_info.device_id),
			cl_ntoh32(p_nbnode->node_info.revision),
			p_nbnode->print_desc,
			cl_ntoh16(p_default_physp->port_info.base_lid),
			p_rphysp->port_num);

		port_state = ib_port_info_get_port_state(&p_physp->port_info);
		link_speed_act =
		    ib_port_info_get_link_speed_active(&p_physp->port_info);
		if (link_speed_act == IB_LINK_SPEED_ACTIVE_2_5)
			link_speed_act_str = "2.5";
		else if (link_speed_act == IB_LINK_SPEED_ACTIVE_5)
			link_speed_act_str = "5";
		else if (link_speed_act == IB_LINK_SPEED_ACTIVE_10)
			link_speed_act_str = "10";
		else
			link_speed_act_str = "??";

		if (p_physp->ext_port_info.link_speed_active & FDR10)
			link_speed_act_str = "FDR10";

		if (p_default_physp->port_info.capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS) {
			link_speed_act =
			    ib_port_info_get_link_speed_ext_active(&p_physp->port_info);
			if (link_speed_act == IB_LINK_SPEED_EXT_ACTIVE_14)
				link_speed_act_str = "14";
			else if (link_speed_act == IB_LINK_SPEED_EXT_ACTIVE_25)
				link_speed_act_str = "25";
			else if (link_speed_act != IB_LINK_SPEED_EXT_ACTIVE_NONE)
				link_speed_act_str = "??";
		}

		fprintf(file, "PHY=%s LOG=%s SPD=%s\n",
			p_physp->port_info.link_width_active == 1 ? "1x" :
			p_physp->port_info.link_width_active == 2 ? "4x" :
			p_physp->port_info.link_width_active == 4 ? "8x" :
			p_physp->port_info.link_width_active == 8 ? "12x" :
			"??",
			port_state == IB_LINK_ACTIVE ? "ACT" :
			port_state == IB_LINK_ARMED ? "ARM" :
			port_state == IB_LINK_INIT ? "INI" : "DWN",
			link_speed_act_str);
	}
}
/**********************************************************************
 The plock must be held before calling this function.
**********************************************************************/
static void pi_rcv_process_switch_ext_port(IN osm_sm_t * sm,
					   IN osm_node_t * p_node,
					   IN osm_physp_t * p_physp,
					   IN ib_port_info_t * p_pi)
{
	ib_api_status_t status = IB_SUCCESS;
	osm_madw_context_t context;
	osm_physp_t *p_remote_physp, *physp0;
	osm_node_t *p_remote_node;
	ib_net64_t m_key;
	unsigned data_vls;
	uint8_t port_num;
	uint8_t remote_port_num;
	osm_dr_path_t path;
	int mlnx_epi_supported = 0;

	OSM_LOG_ENTER(sm->p_log);

	/*
	   Check the state of the physical port.
	   If there appears to be something on the other end of the wire,
	   then ask for NodeInfo.  Ignore the switch management port.
	 */
	port_num = osm_physp_get_port_num(p_physp);

	if (sm->p_subn->opt.fdr10)
		mlnx_epi_supported = is_mlnx_ext_port_info_supported(
						ib_node_info_get_vendor_id(&p_node->node_info),
						p_node->node_info.device_id);

	/* if in_sweep_hop_0 is TRUE, then this means the SM is on the switch,
	   and we got switchInfo of our local switch. Do not continue
	   probing through the switch. */
	switch (ib_port_info_get_port_state(p_pi)) {
	case IB_LINK_DOWN:
		p_remote_physp = osm_physp_get_remote(p_physp);
		if (p_remote_physp) {
			p_remote_node =
			    osm_physp_get_node_ptr(p_remote_physp);
			remote_port_num =
			    osm_physp_get_port_num(p_remote_physp);

			OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
				"Unlinking local node 0x%" PRIx64
				", port %u"
				"\n\t\t\t\tand remote node 0x%" PRIx64
				", port %u\n",
				cl_ntoh64(osm_node_get_node_guid
					  (p_node)), port_num,
				cl_ntoh64(osm_node_get_node_guid
					  (p_remote_node)),
				remote_port_num);

			if (sm->ucast_mgr.cache_valid)
				osm_ucast_cache_add_link(&sm->ucast_mgr,
							 p_physp,
							 p_remote_physp);

			osm_node_unlink(p_node, (uint8_t) port_num,
					p_remote_node,
					(uint8_t) remote_port_num);

		}
		break;

	case IB_LINK_INIT:
	case IB_LINK_ARMED:
	case IB_LINK_ACTIVE:
		physp0 = osm_node_get_physp_ptr(p_node, 0);
		if (mlnx_epi_supported) {
			m_key = ib_port_info_get_m_key(&physp0->port_info);

			context.pi_context.node_guid = osm_node_get_node_guid(p_node);
			context.pi_context.port_guid = osm_physp_get_port_guid(p_physp);
			context.pi_context.set_method = FALSE;
			context.pi_context.light_sweep = FALSE;
			context.pi_context.active_transition = FALSE;
			context.pi_context.client_rereg = FALSE;
			status = osm_req_get(sm,
					     osm_physp_get_dr_path_ptr(p_physp),
					     IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO,
					     cl_hton32(port_num), FALSE, m_key,
					     CL_DISP_MSGID_NONE, &context);
			if (status != IB_SUCCESS)
				OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F11: "
					"Failure initiating MLNX ExtPortInfo request (%s)\n",
					ib_get_err_str(status));
		}
		if (sm->p_subn->in_sweep_hop_0 == FALSE) {
			/*
			   To avoid looping forever, only probe the port if it
			   is NOT the port that responded to the SMP.

			   Request node info from the other end of this link:
			   1) Copy the current path from the parent node.
			   2) Extend the path to the next hop thru this port.
			   3) Request node info with the new path

			 */
			if (p_pi->local_port_num !=
			    osm_physp_get_port_num(p_physp)) {
				path = *osm_physp_get_dr_path_ptr(p_physp);

				if (osm_dr_path_extend(&path,
						       osm_physp_get_port_num
						       (p_physp))) {
					OSM_LOG(sm->p_log, OSM_LOG_ERROR,
						"ERR 0F08: "
						"DR path with hop count %d couldn't be extended\n",
						path.hop_count);
					break;
				}

				memset(&context, 0, sizeof(context));
				context.ni_context.node_guid =
				    osm_node_get_node_guid(p_node);
				context.ni_context.port_num =
				    osm_physp_get_port_num(p_physp);

				status = osm_req_get(sm, &path,
						     IB_MAD_ATTR_NODE_INFO, 0,
						     TRUE, 0,
						     CL_DISP_MSGID_NONE,
						     &context);

				if (status != IB_SUCCESS)
					OSM_LOG(sm->p_log, OSM_LOG_ERROR,
						"ERR 0F02: "
						"Failure initiating NodeInfo request (%s)\n",
						ib_get_err_str(status));
			} else
				OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
					"Skipping SMP responder port %u\n",
					p_pi->local_port_num);
		}
		break;

	default:
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F03: "
			"Unknown link state = %u, port = %u\n",
			ib_port_info_get_port_state(p_pi),
			p_pi->local_port_num);
		break;
	}

	if (ib_port_info_get_port_state(p_pi) > IB_LINK_INIT && p_node->sw &&
	    !ib_switch_info_get_state_change(&p_node->sw->switch_info) &&
	    p_node->sw->need_update == 1)
		p_node->sw->need_update = 0;

	if (p_physp->need_update)
		sm->p_subn->ignore_existing_lfts = TRUE;

	/*
	   Update the PortInfo attribute.
	 */
	osm_physp_set_port_info(p_physp, p_pi, sm);

	if (ib_port_info_get_port_state(p_pi) == IB_LINK_DOWN)
		goto Exit;

	p_remote_physp = osm_physp_get_remote(p_physp);
	if (p_remote_physp) {
		p_remote_node = osm_physp_get_node_ptr(p_remote_physp);
		if (p_remote_node->sw) {
			data_vls = 1U << (ib_port_info_get_vl_cap(p_pi) - 1);
			if (data_vls > 1U << (sm->p_subn->opt.max_op_vls - 1))
				data_vls = 1U << (sm->p_subn->opt.max_op_vls - 1);
			if (data_vls >= IB_MAX_NUM_VLS)
				data_vls = IB_MAX_NUM_VLS - 1;
			if ((uint8_t)data_vls < sm->p_subn->min_sw_data_vls) {
				OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
					"Setting switch port minimal data VLs "
					"to:%u defined by node:0x%"
					PRIx64 ", port:%u\n", data_vls,
					cl_ntoh64(osm_node_get_node_guid(p_node)),
					port_num);
				sm->p_subn->min_sw_data_vls = data_vls;
			}
		}
	}

Exit:
	OSM_LOG_EXIT(sm->p_log);
}