static void debug_port(ib_portid_t * portid, ibnd_port_t * port) { char width[64], speed[64]; int iwidth; int ispeed, fdr10, espeed; uint8_t *info; uint32_t cap_mask; iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F); ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F); fdr10 = mad_get_field(port->ext_info, 0, IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F); if (port->node->type == IB_NODE_SWITCH) info = (uint8_t *)&port->node->ports[0]->info; else info = (uint8_t *)&port->info; cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F); if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)) espeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_ACTIVE_F); else espeed = 0; IBND_DEBUG ("portid %s portnum %d: base lid %d state %d physstate %d %s %s %s %s\n", portid2str(portid), port->portnum, port->base_lid, mad_get_field(port->info, 0, IB_PORT_STATE_F), mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F), mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth), mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed), (fdr10 & FDR10) ? "FDR10" : "", mad_dump_val(IB_PORT_LINK_SPEED_EXT_ACTIVE_F, speed, 64, &espeed)); }
void out_ca_port(ibnd_port_t * port, int group, char *out_prefix) { char *str = NULL; char *rem_nodename = NULL; uint32_t iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F); uint32_t ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F); uint32_t fdr10 = mad_get_field(port->ext_info, 0, IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F); uint32_t cap_mask, espeed; fprintf(f, "%s[%d]", out_prefix ? out_prefix : "", port->portnum); if (port->node->type != IB_NODE_SWITCH) fprintf(f, "(%" PRIx64 ") ", port->guid); fprintf(f, "\t%s[%d]", node_name(port->remoteport->node), port->remoteport->portnum); str = out_ext_port(port->remoteport, group); if (str) fprintf(f, "%s", str); if (port->remoteport->node->type != IB_NODE_SWITCH) fprintf(f, " (%" PRIx64 ") ", port->remoteport->guid); rem_nodename = remap_node_name(node_name_map, port->remoteport->node->guid, port->remoteport->node->nodedesc); cap_mask = mad_get_field(port->info, 0, IB_PORT_CAPMASK_F); if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)) espeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_ACTIVE_F); else espeed = 0; fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s", port->base_lid, port->lmc, rem_nodename, port->remoteport->node->type == IB_NODE_SWITCH ? port->remoteport->node->smalid : port->remoteport->base_lid, dump_linkwidth_compat(iwidth), (ispeed != 4 && !espeed) ? dump_linkspeed_compat(ispeed) : dump_linkspeedext_compat(espeed, ispeed, fdr10)); if (full_info) fprintf(f, " s=%d w=%d", ispeed, iwidth); fprintf(f, "\n"); free(rem_nodename); }
static int get_port_info(ib_portid_t * dest, uint8_t * data, int portnum, int is_switch) { uint8_t smp[IB_SMP_DATA_SIZE]; uint8_t *info; int cap_mask; if (is_switch) { if (!smp_query_via(smp, dest, IB_ATTR_PORT_INFO, 0, 0, srcport)) IBEXIT("smp query port 0 portinfo failed"); info = smp; } else info = data; if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport)) IBEXIT("smp query portinfo failed"); cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F); return (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)); }
void dump_ports_report(ibnd_node_t * node, void *user_data) { int p = 0; ibnd_port_t *port = NULL; char *nodename = NULL; char *rem_nodename = NULL; /* for each port */ for (p = node->numports, port = node->ports[p]; p > 0; port = node->ports[--p]) { uint32_t iwidth, ispeed, fdr10, espeed, cap_mask; uint8_t *info = NULL; if (port == NULL) continue; iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F); ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F); if (port->node->type == IB_NODE_SWITCH) { if (port->node->ports[0]) info = (uint8_t *)&port->node->ports[0]->info; } else info = (uint8_t *)&port->info; if (info) { cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F); if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)) espeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_ACTIVE_F); else espeed = 0; } else { ispeed = 0; iwidth = 0; espeed = 0; } fdr10 = mad_get_field(port->ext_info, 0, IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F); nodename = remap_node_name(node_name_map, port->node->guid, port->node->nodedesc); fprintf(stdout, "%2s %5d %2d 0x%016" PRIx64 " %s %s", ports_nt_str_compat(node), node->type == IB_NODE_SWITCH ? node->smalid : port->base_lid, port->portnum, port->guid, dump_linkwidth_compat(iwidth), (ispeed != 4 && !espeed) ? dump_linkspeed_compat(ispeed) : dump_linkspeedext_compat(espeed, ispeed, fdr10)); if (port->remoteport) { rem_nodename = remap_node_name(node_name_map, port->remoteport->node->guid, port->remoteport->node->nodedesc); fprintf(stdout, " - %2s %5d %2d 0x%016" PRIx64 " ( '%s' - '%s' )\n", ports_nt_str_compat(port->remoteport->node), port->remoteport->node->type == IB_NODE_SWITCH ? port->remoteport->node->smalid : port->remoteport->base_lid, port->remoteport->portnum, port->remoteport->guid, nodename, rem_nodename); free(rem_nodename); } else fprintf(stdout, "%36s'%s'\n", "", nodename); free(nodename); } }
void out_switch_port(ibnd_port_t * port, int group, char *out_prefix) { char *ext_port_str = NULL; char *rem_nodename = NULL; uint32_t iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F); uint32_t ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F); uint32_t fdr10 = mad_get_field(port->ext_info, 0, IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F); uint32_t cap_mask, espeed; DEBUG("port %p:%d remoteport %p\n", port, port->portnum, port->remoteport); fprintf(f, "%s[%d]", out_prefix ? out_prefix : "", port->portnum); ext_port_str = out_ext_port(port, group); if (ext_port_str) fprintf(f, "%s", ext_port_str); rem_nodename = remap_node_name(node_name_map, port->remoteport->node->guid, port->remoteport->node->nodedesc); ext_port_str = out_ext_port(port->remoteport, group); if (!port->node->ports[0]) { cap_mask = 0; ispeed = 0; espeed = 0; } else { cap_mask = mad_get_field(port->node->ports[0]->info, 0, IB_PORT_CAPMASK_F); if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)) espeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_ACTIVE_F); else espeed = 0; } fprintf(f, "\t%s[%d]%s", node_name(port->remoteport->node), port->remoteport->portnum, ext_port_str ? ext_port_str : ""); if (port->remoteport->node->type != IB_NODE_SWITCH) fprintf(f, "(%" PRIx64 ") ", port->remoteport->guid); fprintf(f, "\t\t# \"%s\" lid %d %s%s", rem_nodename, port->remoteport->node->type == IB_NODE_SWITCH ? port->remoteport->node->smalid : port->remoteport->base_lid, dump_linkwidth_compat(iwidth), (ispeed != 4 && !espeed) ? dump_linkspeed_compat(ispeed) : dump_linkspeedext_compat(espeed, ispeed, fdr10)); if (full_info) fprintf(f, " s=%d w=%d", ispeed, iwidth); if (ibnd_is_xsigo_tca(port->remoteport->guid)) fprintf(f, " slot %d", port->portnum); else if (ibnd_is_xsigo_hca(port->remoteport->guid)) fprintf(f, " (scp)"); fprintf(f, "\n"); free(rem_nodename); }
static void cpi_rcv_respond(IN osm_sa_t * sa, IN const osm_madw_t * p_madw) { osm_madw_t *p_resp_madw; const ib_sa_mad_t *p_sa_mad; ib_sa_mad_t *p_resp_sa_mad; ib_class_port_info_t *p_resp_cpi; ib_gid_t zero_gid; uint32_t cap_mask2; uint8_t rtv; OSM_LOG_ENTER(sa->p_log); memset(&zero_gid, 0, sizeof(ib_gid_t)); /* Get a MAD to reply. Address of Mad is in the received mad_wrapper */ p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind, MAD_BLOCK_SIZE, &p_madw->mad_addr); if (!p_resp_madw) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1408: " "Unable to allocate MAD\n"); goto Exit; } p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw); memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE); p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK; /* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */ p_resp_sa_mad->sm_key = 0; p_resp_cpi = (ib_class_port_info_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad); /* finally do it (the job) man ! */ p_resp_cpi->base_ver = 1; p_resp_cpi->class_ver = 2; /* Calculate encoded response time value */ /* transaction timeout is in msec */ if (sa->p_subn->opt.transaction_timeout > msecs_to_rtv_table[MAX_MSECS_TO_RTV - 1]) rtv = MAX_MSECS_TO_RTV - 1; else { for (rtv = 0; rtv < MAX_MSECS_TO_RTV; rtv++) { if (sa->p_subn->opt.transaction_timeout <= msecs_to_rtv_table[rtv]) break; } } rtv += 8; ib_class_set_resp_time_val(p_resp_cpi, rtv); p_resp_cpi->redir_gid = zero_gid; p_resp_cpi->redir_tc_sl_fl = 0; p_resp_cpi->redir_lid = 0; p_resp_cpi->redir_pkey = 0; p_resp_cpi->redir_qp = CL_NTOH32(1); p_resp_cpi->redir_qkey = IB_QP1_WELL_KNOWN_Q_KEY; p_resp_cpi->trap_gid = zero_gid; p_resp_cpi->trap_tc_sl_fl = 0; p_resp_cpi->trap_lid = 0; p_resp_cpi->trap_pkey = 0; p_resp_cpi->trap_hop_qp = 0; p_resp_cpi->trap_qkey = IB_QP1_WELL_KNOWN_Q_KEY; /* set specific capability mask bits */ /* we do not support the following options/optional records: OSM_CAP_IS_SUBN_OPT_RECS_SUP : RandomForwardingTableRecord, ServiceAssociationRecord other optional records supported "under the table" OSM_CAP_IS_MULTIPATH_SUP: TraceRecord OSM_CAP_IS_REINIT_SUP: For reinitialization functionality. So not sending traps, but supporting Get(Notice) and Set(Notice). */ /* Note host notation replaced later */ #if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP) p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP | OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED | OSM_CAP_IS_MULTIPATH_SUP; #else p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP | OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED; #endif cap_mask2 = OSM_CAP2_IS_FULL_PORTINFO_REC_SUPPORTED | OSM_CAP2_IS_EXTENDED_SPEEDS_SUPPORTED | OSM_CAP2_IS_ALIAS_GUIDS_SUPPORTED | OSM_CAP2_IS_MULTICAST_SERVICE_RECS_SUPPORTED | OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED | OSM_CAP2_IS_LINK_WIDTH_2X_SUPPORTED; if (sa->p_subn->opt.use_mfttop) cap_mask2 |= OSM_CAP2_IS_MCAST_TOP_SUPPORTED; if (sa->p_subn->opt.qos) cap_mask2 |= OSM_CAP2_IS_QOS_SUPPORTED; ib_class_set_cap_mask2(p_resp_cpi, cap_mask2); if (!sa->p_subn->opt.disable_multicast) p_resp_cpi->cap_mask |= OSM_CAP_IS_UD_MCAST_SUP; p_resp_cpi->cap_mask = cl_hton16(p_resp_cpi->cap_mask); if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_FRAMES)) osm_dump_sa_mad_v2(sa->p_log, p_resp_sa_mad, FILE_ID, OSM_LOG_FRAMES); osm_sa_send(sa, p_resp_madw, FALSE); Exit: OSM_LOG_EXIT(sa->p_log); }
static void print_port_config(char *node_name, ibnd_node_t * node, int portnum) { char width[64], speed[64], state[64], physstate[64]; char remote_str[256]; char link_str[256]; char width_msg[256]; char speed_msg[256]; char ext_port_str[256]; int iwidth, ispeed, fdr10, espeed, istate, iphystate, cap_mask; uint8_t *info; ibnd_port_t *port = node->ports[portnum]; if (!port) return; iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F); ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F); fdr10 = mad_get_field(port->ext_info, 0, IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F) & FDR10; if (port->node->type == IB_NODE_SWITCH) info = (uint8_t *)&port->node->ports[0]->info; else info = (uint8_t *)&port->info; cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F); if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)) espeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_ACTIVE_F); else espeed = 0; istate = mad_get_field(port->info, 0, IB_PORT_STATE_F); iphystate = mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F); remote_str[0] = '\0'; link_str[0] = '\0'; width_msg[0] = '\0'; speed_msg[0] = '\0'; /* C14-24.2.1 states that a down port allows for invalid data to be * returned for all PortInfo components except PortState and * PortPhysicalState */ if (istate != IB_LINK_DOWN) { if (!espeed) { if (fdr10) sprintf(speed, "10.0 Gbps (FDR10)"); else mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed); } else mad_dump_val(IB_PORT_LINK_SPEED_EXT_ACTIVE_F, speed, 64, &espeed); snprintf(link_str, 256, "(%3s %18s %6s/%8s)", mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth), speed, mad_dump_val(IB_PORT_STATE_F, state, 64, &istate), mad_dump_val(IB_PORT_PHYS_STATE_F, physstate, 64, &iphystate)); } else { snprintf(link_str, 256, "( %6s/%8s)", mad_dump_val(IB_PORT_STATE_F, state, 64, &istate), mad_dump_val(IB_PORT_PHYS_STATE_F, physstate, 64, &iphystate)); } if (port->remoteport) { char *rem_node_name = NULL; if (port->remoteport->ext_portnum) snprintf(ext_port_str, 256, "%d", port->remoteport->ext_portnum); else ext_port_str[0] = '\0'; get_max_msg(width_msg, speed_msg, 256, port); rem_node_name = remap_node_name(node_name_map, port->remoteport->node->guid, port->remoteport->node-> nodedesc); snprintf(remote_str, 256, "0x%016" PRIx64 " %6d %4d[%2s] \"%s\" (%s %s)\n", port->remoteport->guid, port->remoteport->base_lid ? port->remoteport-> base_lid : port->remoteport->node->smalid, port->remoteport->portnum, ext_port_str, rem_node_name, width_msg, speed_msg); free(rem_node_name); } else snprintf(remote_str, 256, " [ ] \"\" ( )\n"); if (port->ext_portnum) snprintf(ext_port_str, 256, "%d", port->ext_portnum); else ext_port_str[0] = '\0'; if (node->type == IB_NODE_SWITCH) printf(" Link info: %6d", node->smalid); else printf(" Link info: %6d", port->base_lid); printf("%4d[%2s] ==%s==> %s", port->portnum, ext_port_str, link_str, remote_str); }
void get_max_msg(char *width_msg, char *speed_msg, int msg_size, ibnd_port_t * port) { char buf[64]; uint32_t max_speed = 0; uint32_t cap_mask, rem_cap_mask, fdr10; uint8_t *info = NULL; uint32_t max_width = get_max(mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_SUPPORTED_F) & mad_get_field(port->remoteport->info, 0, IB_PORT_LINK_WIDTH_SUPPORTED_F)); if ((max_width & mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F)) == 0) // we are not at the max supported width // print what we could be at. snprintf(width_msg, msg_size, "Could be %s", mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, buf, 64, &max_width)); if (port->node->type == IB_NODE_SWITCH) { if (port->node->ports[0]) info = (uint8_t *)&port->node->ports[0]->info; } else info = (uint8_t *)&port->info; if (info) cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F); else cap_mask = 0; info = NULL; if (port->remoteport->node->type == IB_NODE_SWITCH) { if (port->remoteport->node->ports[0]) info = (uint8_t *)&port->remoteport->node->ports[0]->info; } else info = (uint8_t *)&port->remoteport->info; if (info) rem_cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F); else rem_cap_mask = 0; if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS) && rem_cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)) goto check_ext_speed; check_fdr10_supp: fdr10 = (mad_get_field(port->ext_info, 0, IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F) & FDR10) && (mad_get_field(port->remoteport->ext_info, 0, IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F) & FDR10); if (fdr10) goto check_fdr10_active; max_speed = get_max(mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_SUPPORTED_F) & mad_get_field(port->remoteport->info, 0, IB_PORT_LINK_SPEED_SUPPORTED_F)); if ((max_speed & mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F)) == 0) // we are not at the max supported speed // print what we could be at. snprintf(speed_msg, msg_size, "Could be %s", mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, buf, 64, &max_speed)); return; check_ext_speed: if (mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_SUPPORTED_F) == 0 || mad_get_field(port->remoteport->info, 0, IB_PORT_LINK_SPEED_EXT_SUPPORTED_F) == 0) goto check_fdr10_supp; max_speed = get_max(mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_SUPPORTED_F) & mad_get_field(port->remoteport->info, 0, IB_PORT_LINK_SPEED_EXT_SUPPORTED_F)); if ((max_speed & mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_ACTIVE_F)) == 0) // we are not at the max supported extended speed // print what we could be at. snprintf(speed_msg, msg_size, "Could be %s", mad_dump_val(IB_PORT_LINK_SPEED_EXT_ACTIVE_F, buf, 64, &max_speed)); return; check_fdr10_active: if ((mad_get_field(port->ext_info, 0, IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F) & FDR10) == 0) snprintf(speed_msg, msg_size, "Could be FDR10"); }
static int recv_port_info(smp_engine_t * engine, ibnd_smp_t * smp, uint8_t * mad, void *cb_data) { ibnd_scan_t *scan = (ibnd_scan_t *)engine->user_data; ibnd_fabric_t *fabric = scan->fabric; ibnd_node_t *node = cb_data; ibnd_port_t *port; uint8_t *port_info = mad + IB_SMP_DATA_OFFS; uint8_t port_num, local_port; int phystate, ispeed, espeed; uint8_t *info; uint32_t cap_mask; port_num = (uint8_t) mad_get_field(mad, 0, IB_MAD_ATTRMOD_F); local_port = (uint8_t) mad_get_field(port_info, 0, IB_PORT_LOCAL_PORT_F); /* this may have been created before */ port = node->ports[port_num]; if (!port) { port = node->ports[port_num] = calloc(1, sizeof(*port)); if (!port) { IBND_ERROR("Failed to allocate 0x%" PRIx64 " port %u\n", node->guid, port_num); return -1; } port->guid = mad_get_field64(node->info, 0, IB_NODE_PORT_GUID_F); } memcpy(port->info, port_info, sizeof(port->info)); port->node = node; port->portnum = port_num; port->ext_portnum = 0; port->base_lid = (uint16_t) mad_get_field(port->info, 0, IB_PORT_LID_F); port->lmc = (uint8_t) mad_get_field(port->info, 0, IB_PORT_LMC_F); if (port_num == 0) { node->smalid = port->base_lid; node->smalmc = port->lmc; } else if (node->type == IB_NODE_SWITCH) { port->base_lid = node->smalid; port->lmc = node->smalmc; } add_to_portguid_hash(port, fabric->portstbl); if ((scan->cfg->flags & IBND_CONFIG_MLX_EPI) && is_mlnx_ext_port_info_supported(port)) { phystate = mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F); ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F); if (port->node->type == IB_NODE_SWITCH) info = (uint8_t *)&port->node->ports[0]->info; else info = (uint8_t *)&port->info; cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F); if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS)) espeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_EXT_ACTIVE_F); else espeed = 0; if (phystate == IB_PORT_PHYS_STATE_LINKUP && ispeed == IB_LINK_SPEED_ACTIVE_10 && espeed == IB_LINK_SPEED_EXT_ACTIVE_NONE) { /* LinkUp/QDR */ query_mlnx_ext_port_info(engine, &smp->path, node, port_num); return 0; } } debug_port(&smp->path, port); if (port_num && mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F) == IB_PORT_PHYS_STATE_LINKUP && ((node->type == IB_NODE_SWITCH && port_num != local_port) || (node == fabric->from_node && port_num == fabric->from_portnum))) { int rc = 0; ib_portid_t path = smp->path; if (node->type != IB_NODE_SWITCH && node == fabric->from_node && path.drpath.cnt > 1) rc = retract_dpath(engine, &path); else { /* we can't proceed through an HCA with DR */ if (path.lid == 0 || node->type == IB_NODE_SWITCH) rc = extend_dpath(engine, &path, port_num); } if (rc > 0) { struct ni_cbdata * cbdata = malloc(sizeof(*cbdata)); cbdata->node = node; cbdata->port_num = port_num; query_node_info(engine, &path, cbdata); } } return 0; }