/**********************************************************************
 The plock must be held before calling this function.
**********************************************************************/
static void si_rcv_get_mcast_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;
	osm_mcast_tbl_t *p_tbl;
	uint32_t block_id_ho;
	uint32_t max_block_id_ho;
	uint32_t position;
	uint32_t max_position;
	uint32_t attr_mod_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);

	if (osm_switch_get_mcast_fwd_tbl_size(p_sw) == 0) {
		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
			"Multicast not supported by switch 0x%016" PRIx64 "\n",
			cl_ntoh64(osm_node_get_node_guid(p_node)));
		goto Exit;
	}

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

	p_tbl = osm_switch_get_mcast_tbl_ptr(p_sw);
	max_block_id_ho = osm_mcast_tbl_get_max_block(p_tbl);

	if (max_block_id_ho > IB_MCAST_MAX_BLOCK_ID) {
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3609: "
			"Out-of-range mcast block size = %u on switch 0x%016"
			PRIx64 "\n", max_block_id_ho,
			cl_ntoh64(osm_node_get_node_guid(p_node)));
		goto Exit;
	}

	max_position = osm_mcast_tbl_get_max_position(p_tbl);

	CL_ASSERT(max_position <= IB_MCAST_POSITION_MAX);

	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
		"Max MFT block = %u, Max position = %u\n", max_block_id_ho,
		max_position);

	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 MFT block %u\n", block_id_ho);

		for (position = 0; position <= max_position; position++) {
			OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
				"Retrieving MFT position %u\n", position);

			attr_mod_ho =
			    block_id_ho | position << IB_MCAST_POSITION_SHIFT;
			status =
			    osm_req_get(sm, p_dr_path,
					IB_MAD_ATTR_MCAST_FWD_TBL,
					cl_hton32(attr_mod_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 3607: "
					"Failure initiating PortInfo request (%s)\n",
					ib_get_err_str(status));
		}
	}

Exit:
	OSM_LOG_EXIT(sm->p_log);
}
Example #2
0
static void dump_mcast_routes(cl_map_item_t * item, FILE * file, void *cxt)
{
	osm_switch_t *p_sw = (osm_switch_t *) item;
	osm_mcast_tbl_t *p_tbl;
	int16_t mlid_ho = 0;
	int16_t mlid_start_ho;
	uint8_t position = 0;
	int16_t block_num = 0;
	boolean_t first_mlid;
	boolean_t first_port;
	const osm_node_t *p_node;
	uint16_t i, j;
	uint16_t mask_entry;
	char sw_hdr[256];
	char mlid_hdr[32];

	p_node = p_sw->p_node;

	p_tbl = osm_switch_get_mcast_tbl_ptr(p_sw);

	sprintf(sw_hdr, "\nSwitch 0x%016" PRIx64 "\nLID    : Out Port(s)\n",
		cl_ntoh64(osm_node_get_node_guid(p_node)));
	first_mlid = TRUE;
	while (block_num <= p_tbl->max_block_in_use) {
		mlid_start_ho = (uint16_t) (block_num * IB_MCAST_BLOCK_SIZE);
		for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++) {
			mlid_ho = mlid_start_ho + i;
			position = 0;
			first_port = TRUE;
			sprintf(mlid_hdr, "0x%04X :",
				mlid_ho + IB_LID_MCAST_START_HO);
			while (position <= p_tbl->max_position) {
				mask_entry =
				    cl_ntoh16((*p_tbl->
					       p_mask_tbl)[mlid_ho][position]);
				if (mask_entry == 0) {
					position++;
					continue;
				}
				for (j = 0; j < 16; j++) {
					if ((1 << j) & mask_entry) {
						if (first_mlid) {
							fprintf(file, "%s",
								sw_hdr);
							first_mlid = FALSE;
						}
						if (first_port) {
							fprintf(file, "%s",
								mlid_hdr);
							first_port = FALSE;
						}
						fprintf(file, " 0x%03X ",
							j + (position * 16));
					}
				}
				position++;
			}
			if (first_port == FALSE)
				fprintf(file, "\n");
		}
		block_num++;
	}
}