/**********************************************************************
 The plock must be held before calling this function.
**********************************************************************/
static void si_rcv_get_fwd_tbl(IN osm_sm_t * sm, IN osm_switch_t * p_sw)
{
	osm_madw_context_t context;
	osm_dr_path_t *p_dr_path;
	osm_physp_t *p_physp;
	osm_node_t *p_node;
	uint32_t block_id_ho;
	uint32_t max_block_id_ho;
	ib_api_status_t status = IB_SUCCESS;

	OSM_LOG_ENTER(sm->p_log);

	CL_ASSERT(p_sw);

	p_node = p_sw->p_node;

	CL_ASSERT(osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH);

	context.lft_context.node_guid = osm_node_get_node_guid(p_node);
	context.lft_context.set_method = FALSE;

	max_block_id_ho = osm_switch_get_max_block_id_in_use(p_sw);

	p_physp = osm_node_get_physp_ptr(p_node, 0);
	p_dr_path = osm_physp_get_dr_path_ptr(p_physp);

	for (block_id_ho = 0; block_id_ho <= max_block_id_ho; block_id_ho++) {
		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
			"Retrieving FT block %u\n", block_id_ho);

		status = osm_req_get(sm, p_dr_path, IB_MAD_ATTR_LIN_FWD_TBL,
				     cl_hton32(block_id_ho),
				     CL_DISP_MSGID_NONE, &context);
		if (status != IB_SUCCESS)
			/* continue the loop despite the error */
			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3603: "
				"Failure initiating PortInfo request (%s)\n",
				ib_get_err_str(status));
	}

	OSM_LOG_EXIT(sm->p_log);
}
Exemplo n.º 2
0
static void lftr_rcv_by_comp_mask(IN cl_map_item_t * p_map_item, IN void *cxt)
{
	const osm_lftr_search_ctxt_t *p_ctxt = cxt;
	const osm_switch_t *p_sw = (osm_switch_t *) p_map_item;
	const ib_lft_record_t *const p_rcvd_rec = p_ctxt->p_rcvd_rec;
	osm_sa_t *sa = p_ctxt->sa;
	ib_net64_t const comp_mask = p_ctxt->comp_mask;
	const osm_physp_t *const p_req_physp = p_ctxt->p_req_physp;
	osm_port_t *p_port;
	uint16_t min_lid_ho, max_lid_ho;
	uint16_t min_block, max_block, block;
	const osm_physp_t *p_physp;

	/* In switches, the port guid is the node guid. */
	p_port = osm_get_port_by_guid(sa->p_subn,
				      p_sw->p_node->node_info.port_guid);
	if (!p_port) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4405: "
			"Failed to find Port by Node Guid:0x%016" PRIx64
			"\n", cl_ntoh64(p_sw->p_node->node_info.node_guid));
		return;
	}

	/* check that the requester physp and the current physp are under
	   the same partition. */
	p_physp = p_port->p_physp;
	if (!p_physp) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4406: "
			"Failed to find default physical Port by Node Guid:0x%016"
			PRIx64 "\n",
			cl_ntoh64(p_sw->p_node->node_info.node_guid));
		return;
	}
	if (!osm_physp_share_pkey(sa->p_log, p_req_physp,
				  p_physp, sa->p_subn->opt.allow_both_pkeys))
		return;

	/* get the port 0 of the switch */
	osm_port_get_lid_range_ho(p_port, &min_lid_ho, &max_lid_ho);

	/* compare the lids - if required */
	if (comp_mask & IB_LFTR_COMPMASK_LID) {
		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"Comparing lid:%u to port lid range: %u .. %u\n",
			cl_ntoh16(p_rcvd_rec->lid), min_lid_ho, max_lid_ho);
		/* ok we are ready for range check */
		if (min_lid_ho > cl_ntoh16(p_rcvd_rec->lid) ||
		    max_lid_ho < cl_ntoh16(p_rcvd_rec->lid))
			return;
	}

	/* now we need to decide which blocks to output */
	max_block = osm_switch_get_max_block_id_in_use(p_sw);
	if (comp_mask & IB_LFTR_COMPMASK_BLOCK) {
		min_block = cl_ntoh16(p_rcvd_rec->block_num);
		if (min_block > max_block)
			return;
		max_block = min_block;
	} else			/* use as many blocks as "in use" */
		min_block = 0;

	/* so we can add these blocks one by one ... */
	for (block = min_block; block <= max_block; block++)
		lftr_rcv_new_lftr(sa, p_sw, p_ctxt->p_list,
				  osm_port_get_base_lid(p_port), block);
}