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