/********************************************************************** 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); }
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); }