Ejemplo n.º 1
0
/**********************************************************************
 The plock must be held before calling this function.
**********************************************************************/
static void pi_rcv_process_switch_port0(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;
	osm_madw_context_t context;
	uint8_t port, num_ports;

	OSM_LOG_ENTER(sm->p_log);

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

	pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp);

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

	/* Determine if base switch port 0 */
	if (p_node->sw &&
	    !ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info))
		/* PortState is not used on BSP0 but just in case it is DOWN */
		p_physp->port_info = *p_pi;

	/* Now, query PortInfo for the switch external ports */
	num_ports = osm_node_get_num_physp(p_node);

	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;

	for (port = 1; port < num_ports; port++) {
		status = osm_req_get(sm, osm_physp_get_dr_path_ptr(p_physp),
				     IB_MAD_ATTR_PORT_INFO, cl_hton32(port),
				     FALSE,
				     ib_port_info_get_m_key(&p_physp->port_info),
				     CL_DISP_MSGID_NONE, &context);
		if (status != IB_SUCCESS)
			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F16: "
				"Failure initiating PortInfo request (%s)\n",
				ib_get_err_str(status));
	}

	pi_rcv_process_endport(sm, p_physp, p_pi);
	OSM_LOG_EXIT(sm->p_log);
}
Ejemplo n.º 2
0
static void pi_rcv_process_ca_or_router_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)
{
	OSM_LOG_ENTER(sm->p_log);

	UNUSED_PARAM(p_node);

	pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp);

	osm_physp_set_port_info(p_physp, p_pi, sm);

	pi_rcv_process_endport(sm, p_physp, p_pi);

	OSM_LOG_EXIT(sm->p_log);
}
Ejemplo n.º 3
0
/**********************************************************************
 The plock must be held before calling this function.
**********************************************************************/
static void
__osm_pi_rcv_process_switch_port(IN osm_sm_t * sm,
				 IN osm_node_t * const p_node,
				 IN osm_physp_t * const p_physp,
				 IN ib_port_info_t * const p_pi)
{
	ib_api_status_t status = IB_SUCCESS;
	osm_madw_context_t context;
	osm_physp_t *p_remote_physp;
	osm_node_t *p_remote_node;
	uint8_t port_num;
	uint8_t remote_port_num;
	osm_dr_path_t path;

	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 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. */
	if (port_num != 0 && sm->p_subn->in_sweep_hop_0 == FALSE) {
		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:
			/*
			   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);

				osm_dr_path_extend(&path,
						   osm_physp_get_port_num
						   (p_physp));

				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,
						     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 &&
	    p_node->sw->need_update == 1)
		p_node->sw->need_update = 0;

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

	if (port_num == 0)
		pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp);

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

	if (port_num == 0) {
		/* Determine if base switch port 0 */
		if (p_node->sw &&
		    !ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info))
			/* PortState is not used on BSP0 but just in case it is DOWN */
			p_physp->port_info = *p_pi;
		__osm_pi_rcv_process_endport(sm, p_physp, p_pi);
	}

	OSM_LOG_EXIT(sm->p_log);
}