static int set_lft_block(IN osm_switch_t *p_sw, IN osm_ucast_mgr_t *p_mgr, IN uint16_t block_id_ho) { uint8_t block[IB_SMP_DATA_SIZE]; osm_madw_context_t context; osm_dr_path_t *p_path; ib_api_status_t status; /* Send linear forwarding table blocks to the switch as long as the switch indicates it has blocks needing configuration. */ if (!p_sw->new_lft) { /* any routing should provide the new_lft */ CL_ASSERT(p_mgr->p_subn->opt.use_ucast_cache && p_mgr->cache_valid && !p_sw->need_update); return -1; } p_path = osm_physp_get_dr_path_ptr(osm_node_get_physp_ptr(p_sw->p_node, 0)); context.lft_context.node_guid = osm_node_get_node_guid(p_sw->p_node); context.lft_context.set_method = TRUE; if (!osm_switch_get_lft_block(p_sw, block_id_ho, block) || (!p_sw->need_update && !p_mgr->p_subn->need_update && !memcmp(block, p_sw->new_lft + block_id_ho * IB_SMP_DATA_SIZE, IB_SMP_DATA_SIZE))) return 0; OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Writing FT block %u to switch 0x%" PRIx64 "\n", block_id_ho, cl_ntoh64(context.lft_context.node_guid)); status = osm_req_set(p_mgr->sm, p_path, p_sw->new_lft + block_id_ho * IB_SMP_DATA_SIZE, IB_SMP_DATA_SIZE, IB_MAD_ATTR_LIN_FWD_TBL, cl_hton32(block_id_ho), CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) { OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A05: " "Sending linear fwd. tbl. block failed (%s)\n", ib_get_err_str(status)); return -1; } return 0; }
static ib_api_status_t sl2vl_update_table(osm_sm_t * sm, osm_physp_t * p, uint8_t in_port, uint8_t out_port, unsigned force_update, const ib_slvl_table_t * sl2vl_table) { osm_madw_context_t context; ib_slvl_table_t tbl, *p_tbl; osm_node_t *p_node = osm_physp_get_node_ptr(p); uint32_t attr_mod; unsigned vl_mask; uint8_t vl1, vl2; int i; vl_mask = (1 << (ib_port_info_get_op_vls(&p->port_info) - 1)) - 1; for (i = 0; i < IB_MAX_NUM_VLS / 2; i++) { vl1 = sl2vl_table->raw_vl_by_sl[i] >> 4; vl2 = sl2vl_table->raw_vl_by_sl[i] & 0xf; if (vl1 != 15) vl1 &= vl_mask; if (vl2 != 15) vl2 &= vl_mask; tbl.raw_vl_by_sl[i] = (vl1 << 4) | vl2; } if (!force_update && (p_tbl = osm_physp_get_slvl_tbl(p, in_port)) && !memcmp(p_tbl, &tbl, sizeof(tbl))) return IB_SUCCESS; context.slvl_context.node_guid = osm_node_get_node_guid(p_node); context.slvl_context.port_guid = osm_physp_get_port_guid(p); context.slvl_context.set_method = TRUE; attr_mod = in_port << 8 | out_port; return osm_req_set(sm, osm_physp_get_dr_path_ptr(p), (uint8_t *) & tbl, sizeof(tbl), IB_MAD_ATTR_SLVL_TABLE, cl_hton32(attr_mod), CL_DISP_MSGID_NONE, &context); }
/* * QoS primitives */ static ib_api_status_t vlarb_update_table_block(osm_sm_t * sm, osm_physp_t * p, uint8_t port_num, unsigned force_update, const ib_vl_arb_table_t * table_block, unsigned block_length, unsigned block_num) { ib_vl_arb_table_t block; osm_madw_context_t context; uint32_t attr_mod; unsigned vl_mask, i; vl_mask = (1 << (ib_port_info_get_op_vls(&p->port_info) - 1)) - 1; memset(&block, 0, sizeof(block)); memcpy(&block, table_block, block_length * sizeof(block.vl_entry[0])); for (i = 0; i < block_length; i++) block.vl_entry[i].vl &= vl_mask; if (!force_update && !memcmp(&p->vl_arb[block_num], &block, block_length * sizeof(block.vl_entry[0]))) return IB_SUCCESS; context.vla_context.node_guid = osm_node_get_node_guid(osm_physp_get_node_ptr(p)); context.vla_context.port_guid = osm_physp_get_port_guid(p); context.vla_context.set_method = TRUE; attr_mod = ((block_num + 1) << 16) | port_num; return osm_req_set(sm, osm_physp_get_dr_path_ptr(p), (uint8_t *) & block, sizeof(block), IB_MAD_ATTR_VL_ARBITRATION, cl_hton32(attr_mod), CL_DISP_MSGID_NONE, &context); }
static boolean_t __osm_link_mgr_set_physp_pi(osm_sm_t * sm, IN osm_physp_t * const p_physp, IN uint8_t const port_state) { uint8_t payload[IB_SMP_DATA_SIZE]; ib_port_info_t *const p_pi = (ib_port_info_t *) payload; const ib_port_info_t *p_old_pi; osm_madw_context_t context; osm_node_t *p_node; ib_api_status_t status; uint8_t port_num; uint8_t mtu; uint8_t op_vls; boolean_t esp0 = FALSE; boolean_t send_set = FALSE; osm_physp_t *p_remote_physp; OSM_LOG_ENTER(sm->p_log); p_node = osm_physp_get_node_ptr(p_physp); port_num = osm_physp_get_port_num(p_physp); if (port_num == 0) { /* CAs don't have a port 0, and for switch port 0, we need to check if this is enhanced or base port 0. For base port 0 the following parameters are not valid (p822, table 145). */ if (!p_node->sw) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 4201: " "Cannot find switch by guid: 0x%" PRIx64 "\n", cl_ntoh64(p_node->node_info.node_guid)); goto Exit; } if (ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info) == FALSE) { /* This means the switch doesn't support enhanced port 0. Can skip it. */ OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Skipping port 0, GUID 0x%016" PRIx64 "\n", cl_ntoh64(osm_physp_get_port_guid(p_physp))); goto Exit; } esp0 = TRUE; } /* PAST THIS POINT WE ARE HANDLING EITHER A NON PORT 0 OR ENHANCED PORT 0 */ p_old_pi = &p_physp->port_info; memset(payload, 0, IB_SMP_DATA_SIZE); memcpy(payload, p_old_pi, sizeof(ib_port_info_t)); /* Should never write back a value that is bigger then 3 in the PortPhysicalState field - so can not simply copy! Actually we want to write there: port physical state - no change, link down default state = polling port state - as requested. */ p_pi->state_info2 = 0x02; ib_port_info_set_port_state(p_pi, port_state); if (ib_port_info_get_link_down_def_state(p_pi) != ib_port_info_get_link_down_def_state(p_old_pi)) send_set = TRUE; /* didn't get PortInfo before */ if (!ib_port_info_get_port_state(p_old_pi)) send_set = TRUE; /* we only change port fields if we do not change state */ if (port_state == IB_LINK_NO_CHANGE) { /* The following fields are relevant only for CA port, router, or Enh. SP0 */ if (osm_node_get_type(p_node) != IB_NODE_TYPE_SWITCH || port_num == 0) { p_pi->m_key = sm->p_subn->opt.m_key; if (memcmp(&p_pi->m_key, &p_old_pi->m_key, sizeof(p_pi->m_key))) send_set = TRUE; p_pi->subnet_prefix = sm->p_subn->opt.subnet_prefix; if (memcmp(&p_pi->subnet_prefix, &p_old_pi->subnet_prefix, sizeof(p_pi->subnet_prefix))) send_set = TRUE; p_pi->base_lid = osm_physp_get_base_lid(p_physp); if (memcmp(&p_pi->base_lid, &p_old_pi->base_lid, sizeof(p_pi->base_lid))) send_set = TRUE; /* we are initializing the ports with our local sm_base_lid */ p_pi->master_sm_base_lid = sm->p_subn->sm_base_lid; if (memcmp(&p_pi->master_sm_base_lid, &p_old_pi->master_sm_base_lid, sizeof(p_pi->master_sm_base_lid))) send_set = TRUE; p_pi->m_key_lease_period = sm->p_subn->opt.m_key_lease_period; if (memcmp(&p_pi->m_key_lease_period, &p_old_pi->m_key_lease_period, sizeof(p_pi->m_key_lease_period))) send_set = TRUE; if (esp0 == FALSE) p_pi->mkey_lmc = sm->p_subn->opt.lmc; else { if (sm->p_subn->opt.lmc_esp0) p_pi->mkey_lmc = sm->p_subn->opt.lmc; else p_pi->mkey_lmc = 0; } if (memcmp(&p_pi->mkey_lmc, &p_old_pi->mkey_lmc, sizeof(p_pi->mkey_lmc))) send_set = TRUE; ib_port_info_set_timeout(p_pi, sm->p_subn->opt. subnet_timeout); if (ib_port_info_get_timeout(p_pi) != ib_port_info_get_timeout(p_old_pi)) send_set = TRUE; } /* Several timeout mechanisms: */ p_remote_physp = osm_physp_get_remote(p_physp); if (port_num != 0 && p_remote_physp) { if (osm_node_get_type(osm_physp_get_node_ptr(p_physp)) == IB_NODE_TYPE_ROUTER) { ib_port_info_set_hoq_lifetime(p_pi, sm->p_subn-> opt. leaf_head_of_queue_lifetime); } else if (osm_node_get_type (osm_physp_get_node_ptr(p_physp)) == IB_NODE_TYPE_SWITCH) { /* Is remote end CA or router (a leaf port) ? */ if (osm_node_get_type (osm_physp_get_node_ptr(p_remote_physp)) != IB_NODE_TYPE_SWITCH) { ib_port_info_set_hoq_lifetime(p_pi, sm-> p_subn-> opt. leaf_head_of_queue_lifetime); ib_port_info_set_vl_stall_count(p_pi, sm-> p_subn-> opt. leaf_vl_stall_count); } else { ib_port_info_set_hoq_lifetime(p_pi, sm-> p_subn-> opt. head_of_queue_lifetime); ib_port_info_set_vl_stall_count(p_pi, sm-> p_subn-> opt. vl_stall_count); } } if (ib_port_info_get_hoq_lifetime(p_pi) != ib_port_info_get_hoq_lifetime(p_old_pi) || ib_port_info_get_vl_stall_count(p_pi) != ib_port_info_get_vl_stall_count(p_old_pi)) send_set = TRUE; } ib_port_info_set_phy_and_overrun_err_thd(p_pi, sm->p_subn->opt. local_phy_errors_threshold, sm->p_subn->opt. overrun_errors_threshold); if (memcmp(&p_pi->error_threshold, &p_old_pi->error_threshold, sizeof(p_pi->error_threshold))) send_set = TRUE; /* Set the easy common parameters for all port types, then determine the neighbor MTU. */ p_pi->link_width_enabled = p_old_pi->link_width_supported; if (memcmp(&p_pi->link_width_enabled, &p_old_pi->link_width_enabled, sizeof(p_pi->link_width_enabled))) send_set = TRUE; if (sm->p_subn->opt.force_link_speed && (sm->p_subn->opt.force_link_speed != 15 || ib_port_info_get_link_speed_enabled(p_pi) != ib_port_info_get_link_speed_sup(p_pi))) { ib_port_info_set_link_speed_enabled(p_pi, sm->p_subn->opt. force_link_speed); if (memcmp(&p_pi->link_speed, &p_old_pi->link_speed, sizeof(p_pi->link_speed))) send_set = TRUE; } /* calc new op_vls and mtu */ op_vls = osm_physp_calc_link_op_vls(sm->p_log, sm->p_subn, p_physp); mtu = osm_physp_calc_link_mtu(sm->p_log, p_physp); ib_port_info_set_neighbor_mtu(p_pi, mtu); if (ib_port_info_get_neighbor_mtu(p_pi) != ib_port_info_get_neighbor_mtu(p_old_pi)) send_set = TRUE; ib_port_info_set_op_vls(p_pi, op_vls); if (ib_port_info_get_op_vls(p_pi) != ib_port_info_get_op_vls(p_old_pi)) send_set = TRUE; /* provide the vl_high_limit from the qos mgr */ if (sm->p_subn->opt.qos && p_physp->vl_high_limit != p_old_pi->vl_high_limit) { send_set = TRUE; p_pi->vl_high_limit = p_physp->vl_high_limit; } } if (port_state != IB_LINK_NO_CHANGE && port_state != ib_port_info_get_port_state(p_old_pi)) { send_set = TRUE; if (port_state == IB_LINK_ACTIVE) context.pi_context.active_transition = TRUE; else context.pi_context.active_transition = FALSE; } 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 = TRUE; context.pi_context.light_sweep = FALSE; /* We need to send the PortInfoSet request with the new sm_lid in the following cases: 1. There is a change in the values (send_set == TRUE) 2. This is a switch external port (so it wasn't handled yet by osm_lid_mgr) and first_time_master_sweep flag on the subnet is TRUE, which means the SM just became master, and it then needs to send at PortInfoSet to every port. */ if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH && port_num && sm->p_subn->first_time_master_sweep == TRUE) send_set = TRUE; if (send_set) status = osm_req_set(sm, osm_physp_get_dr_path_ptr(p_physp), payload, sizeof(payload), IB_MAD_ATTR_PORT_INFO, cl_hton32(port_num), CL_DISP_MSGID_NONE, &context); Exit: OSM_LOG_EXIT(sm->p_log); return send_set; }
static int link_mgr_set_physp_pi(osm_sm_t * sm, IN osm_physp_t * p_physp, IN uint8_t port_state) { uint8_t payload[IB_SMP_DATA_SIZE], payload2[IB_SMP_DATA_SIZE]; ib_port_info_t *p_pi = (ib_port_info_t *) payload; ib_mlnx_ext_port_info_t *p_epi = (ib_mlnx_ext_port_info_t *) payload2; const ib_port_info_t *p_old_pi; const ib_mlnx_ext_port_info_t *p_old_epi; osm_madw_context_t context; osm_node_t *p_node; ib_api_status_t status; uint8_t port_num, mtu, op_vls, smsl = OSM_DEFAULT_SL; boolean_t esp0 = FALSE, send_set = FALSE, send_set2 = FALSE; osm_physp_t *p_remote_physp, *physp0; int qdr_change = 0, fdr10_change = 0; int ret = 0; ib_net32_t attr_mod, cap_mask; OSM_LOG_ENTER(sm->p_log); p_node = osm_physp_get_node_ptr(p_physp); p_old_pi = &p_physp->port_info; port_num = osm_physp_get_port_num(p_physp); if (port_num == 0) { /* CAs don't have a port 0, and for switch port 0, we need to check if this is enhanced or base port 0. For base port 0 the following parameters are not valid (IBA 1.2.1 p.830 table 146). */ if (!p_node->sw) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 4201: " "Cannot find switch by guid: 0x%" PRIx64 "\n", cl_ntoh64(p_node->node_info.node_guid)); goto Exit; } if (ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info) == FALSE) { /* Even for base port 0 we might have to set smsl (if we are using lash routing) */ smsl = link_mgr_get_smsl(sm, p_physp); if (smsl != ib_port_info_get_master_smsl(p_old_pi)) { send_set = TRUE; OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Setting SMSL to %d on port 0 GUID 0x%016" PRIx64 "\n", smsl, cl_ntoh64(osm_physp_get_port_guid (p_physp))); } else { /* This means the switch doesn't support enhanced port 0 and we don't need to change SMSL. Can skip it. */ OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Skipping port 0, GUID 0x%016" PRIx64 "\n", cl_ntoh64(osm_physp_get_port_guid (p_physp))); goto Exit; } } else esp0 = TRUE; } memcpy(payload, p_old_pi, sizeof(ib_port_info_t)); /* Should never write back a value that is bigger then 3 in the PortPhysicalState field - so can not simply copy! Actually we want to write there: port physical state - no change, link down default state = polling port state - as requested. */ p_pi->state_info2 = 0x02; ib_port_info_set_port_state(p_pi, port_state); /* Check whether this is base port0 smsl handling only */ if (port_num == 0 && esp0 == FALSE) { ib_port_info_set_master_smsl(p_pi, smsl); goto Send; } /* PAST THIS POINT WE ARE HANDLING EITHER A NON PORT 0 OR ENHANCED PORT 0 */ if (ib_port_info_get_link_down_def_state(p_pi) != ib_port_info_get_link_down_def_state(p_old_pi)) send_set = TRUE; /* didn't get PortInfo before */ if (!ib_port_info_get_port_state(p_old_pi)) send_set = TRUE; /* we only change port fields if we do not change state */ if (port_state == IB_LINK_NO_CHANGE) { /* The following fields are relevant only for CA port, router, or Enh. SP0 */ if (osm_node_get_type(p_node) != IB_NODE_TYPE_SWITCH || port_num == 0) { p_pi->m_key = sm->p_subn->opt.m_key; if (memcmp(&p_pi->m_key, &p_old_pi->m_key, sizeof(p_pi->m_key))) send_set = TRUE; p_pi->subnet_prefix = sm->p_subn->opt.subnet_prefix; if (memcmp(&p_pi->subnet_prefix, &p_old_pi->subnet_prefix, sizeof(p_pi->subnet_prefix))) send_set = TRUE; p_pi->base_lid = osm_physp_get_base_lid(p_physp); if (memcmp(&p_pi->base_lid, &p_old_pi->base_lid, sizeof(p_pi->base_lid))) send_set = TRUE; /* we are initializing the ports with our local sm_base_lid */ p_pi->master_sm_base_lid = sm->p_subn->sm_base_lid; if (memcmp(&p_pi->master_sm_base_lid, &p_old_pi->master_sm_base_lid, sizeof(p_pi->master_sm_base_lid))) send_set = TRUE; smsl = link_mgr_get_smsl(sm, p_physp); if (smsl != ib_port_info_get_master_smsl(p_old_pi)) { ib_port_info_set_master_smsl(p_pi, smsl); OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Setting SMSL to %d on GUID 0x%016" PRIx64 ", port %d\n", smsl, cl_ntoh64(osm_physp_get_port_guid (p_physp)), port_num); send_set = TRUE; } p_pi->m_key_lease_period = sm->p_subn->opt.m_key_lease_period; if (memcmp(&p_pi->m_key_lease_period, &p_old_pi->m_key_lease_period, sizeof(p_pi->m_key_lease_period))) send_set = TRUE; /* M_KeyProtectBits are currently always zero */ p_pi->mkey_lmc = 0; if (esp0 == FALSE || sm->p_subn->opt.lmc_esp0) ib_port_info_set_lmc(p_pi, sm->p_subn->opt.lmc); if (ib_port_info_get_lmc(p_old_pi) != ib_port_info_get_lmc(p_pi) || ib_port_info_get_mpb(p_old_pi) != ib_port_info_get_mpb(p_pi)) send_set = TRUE; ib_port_info_set_timeout(p_pi, sm->p_subn->opt. subnet_timeout); if (ib_port_info_get_timeout(p_pi) != ib_port_info_get_timeout(p_old_pi)) send_set = TRUE; } /* Several timeout mechanisms: */ p_remote_physp = osm_physp_get_remote(p_physp); if (port_num != 0 && p_remote_physp) { if (osm_node_get_type(osm_physp_get_node_ptr(p_physp)) == IB_NODE_TYPE_ROUTER) { ib_port_info_set_hoq_lifetime(p_pi, sm->p_subn-> opt. leaf_head_of_queue_lifetime); } else if (osm_node_get_type (osm_physp_get_node_ptr(p_physp)) == IB_NODE_TYPE_SWITCH) { /* Is remote end CA or router (a leaf port) ? */ if (osm_node_get_type (osm_physp_get_node_ptr(p_remote_physp)) != IB_NODE_TYPE_SWITCH) { ib_port_info_set_hoq_lifetime(p_pi, sm-> p_subn-> opt. leaf_head_of_queue_lifetime); ib_port_info_set_vl_stall_count(p_pi, sm-> p_subn-> opt. leaf_vl_stall_count); } else { ib_port_info_set_hoq_lifetime(p_pi, sm-> p_subn-> opt. head_of_queue_lifetime); ib_port_info_set_vl_stall_count(p_pi, sm-> p_subn-> opt. vl_stall_count); } } if (ib_port_info_get_hoq_lifetime(p_pi) != ib_port_info_get_hoq_lifetime(p_old_pi) || ib_port_info_get_vl_stall_count(p_pi) != ib_port_info_get_vl_stall_count(p_old_pi)) send_set = TRUE; } ib_port_info_set_phy_and_overrun_err_thd(p_pi, sm->p_subn->opt. local_phy_errors_threshold, sm->p_subn->opt. overrun_errors_threshold); if (memcmp(&p_pi->error_threshold, &p_old_pi->error_threshold, sizeof(p_pi->error_threshold))) send_set = TRUE; /* Set the easy common parameters for all port types, then determine the neighbor MTU. */ p_pi->link_width_enabled = p_old_pi->link_width_supported; if (memcmp(&p_pi->link_width_enabled, &p_old_pi->link_width_enabled, sizeof(p_pi->link_width_enabled))) send_set = TRUE; if (sm->p_subn->opt.force_link_speed && (sm->p_subn->opt.force_link_speed != 15 || ib_port_info_get_link_speed_enabled(p_pi) != ib_port_info_get_link_speed_sup(p_pi))) { ib_port_info_set_link_speed_enabled(p_pi, sm->p_subn->opt. force_link_speed); if (memcmp(&p_pi->link_speed, &p_old_pi->link_speed, sizeof(p_pi->link_speed))) { send_set = TRUE; /* Determine whether QDR in LSE is being changed */ if ((ib_port_info_get_link_speed_enabled(p_pi) & IB_LINK_SPEED_ACTIVE_10 && !(ib_port_info_get_link_speed_enabled(p_old_pi) & IB_LINK_SPEED_ACTIVE_10)) || ((!(ib_port_info_get_link_speed_enabled(p_pi) & IB_LINK_SPEED_ACTIVE_10) && ib_port_info_get_link_speed_enabled(p_old_pi) & IB_LINK_SPEED_ACTIVE_10))) qdr_change = 1; } } if (sm->p_subn->opt.fdr10 && p_physp->ext_port_info.link_speed_supported & FDR10) { if (sm->p_subn->opt.fdr10 == 1) { /* enable */ if (!(p_physp->ext_port_info.link_speed_enabled & FDR10)) fdr10_change = 1; } else { /* disable */ if (p_physp->ext_port_info.link_speed_enabled & FDR10) fdr10_change = 1; } if (fdr10_change) { p_old_epi = &p_physp->ext_port_info; memcpy(payload2, p_old_epi, sizeof(ib_mlnx_ext_port_info_t)); p_epi->state_change_enable = 0x01; if (sm->p_subn->opt.fdr10 == 1) p_epi->link_speed_enabled = FDR10; else p_epi->link_speed_enabled = 0; send_set2 = TRUE; } } if (osm_node_get_type(p_physp->p_node) == IB_NODE_TYPE_SWITCH) { physp0 = osm_node_get_physp_ptr(p_physp->p_node, 0); cap_mask = physp0->port_info.capability_mask; } else cap_mask = p_pi->capability_mask; if (!(cap_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) qdr_change = 0; /* Do peer ports support extended link speeds ? */ if (port_num != 0 && p_remote_physp) { osm_physp_t *rphysp0; ib_net32_t rem_cap_mask; if (osm_node_get_type(p_remote_physp->p_node) == IB_NODE_TYPE_SWITCH) { rphysp0 = osm_node_get_physp_ptr(p_remote_physp->p_node, 0); rem_cap_mask = rphysp0->port_info.capability_mask; } else rem_cap_mask = p_remote_physp->port_info.capability_mask; if (cap_mask & IB_PORT_CAP_HAS_EXT_SPEEDS && rem_cap_mask & IB_PORT_CAP_HAS_EXT_SPEEDS) { if (sm->p_subn->opt.force_link_speed_ext && (sm->p_subn->opt.force_link_speed_ext != IB_LINK_SPEED_EXT_SET_LSES || p_pi->link_speed_ext_enabled != ib_port_info_get_link_speed_sup(p_pi))) { p_pi->link_speed_ext_enabled = sm->p_subn->opt.force_link_speed_ext; if (memcmp(&p_pi->link_speed_ext_enabled, &p_old_pi->link_speed_ext_enabled, sizeof(p_pi->link_speed_ext_enabled))) send_set = TRUE; } } } /* calc new op_vls and mtu */ op_vls = osm_physp_calc_link_op_vls(sm->p_log, sm->p_subn, p_physp); mtu = osm_physp_calc_link_mtu(sm->p_log, p_physp); ib_port_info_set_neighbor_mtu(p_pi, mtu); if (ib_port_info_get_neighbor_mtu(p_pi) != ib_port_info_get_neighbor_mtu(p_old_pi)) send_set = TRUE; ib_port_info_set_op_vls(p_pi, op_vls); if (ib_port_info_get_op_vls(p_pi) != ib_port_info_get_op_vls(p_old_pi)) send_set = TRUE; /* provide the vl_high_limit from the qos mgr */ if (sm->p_subn->opt.qos && p_physp->vl_high_limit != p_old_pi->vl_high_limit) { send_set = TRUE; p_pi->vl_high_limit = p_physp->vl_high_limit; } } Send: if (port_state != IB_LINK_NO_CHANGE && port_state != ib_port_info_get_port_state(p_old_pi)) { send_set = TRUE; if (port_state == IB_LINK_ACTIVE) context.pi_context.active_transition = TRUE; else context.pi_context.active_transition = FALSE; } 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 = TRUE; context.pi_context.light_sweep = FALSE; /* We need to send the PortInfoSet request with the new sm_lid in the following cases: 1. There is a change in the values (send_set == TRUE) 2. This is a switch external port (so it wasn't handled yet by osm_lid_mgr) and first_time_master_sweep flag on the subnet is TRUE, which means the SM just became master, and it then needs to send at PortInfoSet to every port. */ if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH && port_num && sm->p_subn->first_time_master_sweep == TRUE) send_set = TRUE; if (!send_set) goto Exit; attr_mod = cl_hton32(port_num); if (qdr_change) attr_mod |= cl_hton32(1 << 31); /* AM SMSupportExtendedSpeeds */ status = osm_req_set(sm, osm_physp_get_dr_path_ptr(p_physp), payload, sizeof(payload), IB_MAD_ATTR_PORT_INFO, attr_mod, CL_DISP_MSGID_NONE, &context); if (status) ret = -1; if (send_set2) { status = osm_req_set(sm, osm_physp_get_dr_path_ptr(p_physp), payload2, sizeof(payload2), IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO, cl_hton32(port_num), CL_DISP_MSGID_NONE, &context); if (status) ret = -1; } Exit: OSM_LOG_EXIT(sm->p_log); return ret; }
/********************************************************************** * Send SubnSet(SMInfo) SMP with HANDOVER attribute to the * remote_sm indicated. **********************************************************************/ static void state_mgr_send_handover(IN osm_sm_t * sm, IN osm_remote_sm_t * p_sm) { uint8_t payload[IB_SMP_DATA_SIZE]; ib_sm_info_t *p_smi = (ib_sm_info_t *) payload; osm_madw_context_t context; const osm_port_t *p_port; ib_api_status_t status; OSM_LOG_ENTER(sm->p_log); /* * Send a query of SubnSet(SMInfo) HANDOVER to the remote sm given. */ memset(&context, 0, sizeof(context)); p_port = p_sm->p_port; if (p_port == NULL) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3316: " "No port object on given remote_sm object\n"); goto Exit; } /* update the master_guid in the sm_state_mgr object according to */ /* the guid of the port where the new Master SM should reside. */ OSM_LOG(sm->p_log, OSM_LOG_VERBOSE, "Handing over mastership. Updating sm_state_mgr master_guid: %016" PRIx64 " (node %s)\n", cl_ntoh64(p_port->guid), p_port->p_node ? p_port->p_node->print_desc : "UNKNOWN"); sm->master_sm_guid = p_port->guid; context.smi_context.port_guid = p_port->guid; context.smi_context.set_method = TRUE; p_smi->guid = sm->p_subn->sm_port_guid; p_smi->act_count = cl_hton32(sm->p_subn->p_osm->stats.qp0_mads_sent); p_smi->pri_state = (uint8_t) (sm->p_subn->sm_state | sm->p_subn->opt.sm_priority << 4); /* * Return 0 for the SM key unless we authenticate the requester * as the master SM. */ if (ib_sminfo_get_state(&p_sm->smi) == IB_SMINFO_STATE_MASTER) { OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Responding to master SM with real sm_key\n"); p_smi->sm_key = sm->p_subn->opt.sm_key; } else { /* The requester is not authenticated as master - set sm_key to zero */ OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Responding to SM not master with zero sm_key\n"); p_smi->sm_key = 0; } status = osm_req_set(sm, osm_physp_get_dr_path_ptr(p_port->p_physp), payload, sizeof(payload), IB_MAD_ATTR_SM_INFO, IB_SMINFO_ATTR_MOD_HANDOVER, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3317: " "Failure requesting SMInfo (%s)\n", ib_get_err_str(status)); Exit: OSM_LOG_EXIT(sm->p_log); }
static void ucast_mgr_set_fwd_top(IN cl_map_item_t * p_map_item, IN void *cxt) { osm_ucast_mgr_t *p_mgr = cxt; osm_switch_t * p_sw = (osm_switch_t *) p_map_item; osm_node_t *p_node; osm_physp_t *p_physp; osm_dr_path_t *p_path; osm_madw_context_t context; ib_api_status_t status; ib_switch_info_t si; boolean_t set_swinfo_require = FALSE; uint16_t lin_top; uint8_t life_state; CL_ASSERT(p_mgr); OSM_LOG_ENTER(p_mgr->p_log); CL_ASSERT(p_sw && p_sw->max_lid_ho); p_node = p_sw->p_node; CL_ASSERT(p_node); if (p_mgr->max_lid < p_sw->max_lid_ho) p_mgr->max_lid = p_sw->max_lid_ho; p_physp = osm_node_get_physp_ptr(p_node, 0); CL_ASSERT(p_physp); p_path = osm_physp_get_dr_path_ptr(p_physp); /* Set the top of the unicast forwarding table. */ si = p_sw->switch_info; lin_top = cl_hton16(p_sw->max_lid_ho); if (lin_top != si.lin_top) { set_swinfo_require = TRUE; si.lin_top = lin_top; context.si_context.lft_top_change = TRUE; } else context.si_context.lft_top_change = FALSE; life_state = si.life_state; ib_switch_info_set_life_time(&si, p_mgr->p_subn->opt.packet_life_time); if (life_state != si.life_state) set_swinfo_require = TRUE; if (set_swinfo_require) { OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Setting switch FT top to LID %u\n", p_sw->max_lid_ho); context.si_context.light_sweep = FALSE; context.si_context.node_guid = osm_node_get_node_guid(p_node); context.si_context.set_method = TRUE; status = osm_req_set(p_mgr->sm, p_path, (uint8_t *) & si, sizeof(si), IB_MAD_ATTR_SWITCH_INFO, 0, FALSE, ib_port_info_get_m_key(&p_physp->port_info), CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A06: " "Sending SwitchInfo attribute failed (%s)\n", ib_get_err_str(status)); } OSM_LOG_EXIT(p_mgr->p_log); }
static void ucast_mgr_set_fwd_top(IN cl_map_item_t * p_map_item, IN void *cxt) { osm_ucast_mgr_t *p_mgr = cxt; osm_switch_t * p_sw = (osm_switch_t *) p_map_item; osm_node_t *p_node; osm_dr_path_t *p_path; osm_madw_context_t context; ib_api_status_t status; ib_switch_info_t si; boolean_t set_swinfo_require = FALSE; uint16_t lin_top; uint8_t life_state; CL_ASSERT(p_mgr); OSM_LOG_ENTER(p_mgr->p_log); CL_ASSERT(p_sw); p_node = p_sw->p_node; CL_ASSERT(p_node); if (p_mgr->max_lid < p_sw->max_lid_ho) p_mgr->max_lid = p_sw->max_lid_ho; p_path = osm_physp_get_dr_path_ptr(osm_node_get_physp_ptr(p_node, 0)); /* Set the top of the unicast forwarding table. */ si = p_sw->switch_info; lin_top = cl_hton16(p_sw->max_lid_ho); if (lin_top != si.lin_top) { set_swinfo_require = TRUE; si.lin_top = lin_top; } /* check to see if the change state bit is on. If it is - then we need to clear it. */ if (ib_switch_info_get_state_change(&si)) life_state = ((p_mgr->p_subn->opt.packet_life_time << 3) | (si.life_state & IB_SWITCH_PSC)) & 0xfc; else life_state = (p_mgr->p_subn->opt.packet_life_time << 3) & 0xf8; if (life_state != si.life_state || ib_switch_info_get_state_change(&si)) { set_swinfo_require = TRUE; si.life_state = life_state; } if (set_swinfo_require) { OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Setting switch FT top to LID %u\n", p_sw->max_lid_ho); context.si_context.light_sweep = FALSE; context.si_context.node_guid = osm_node_get_node_guid(p_node); context.si_context.set_method = TRUE; status = osm_req_set(p_mgr->sm, p_path, (uint8_t *) & si, sizeof(si), IB_MAD_ATTR_SWITCH_INFO, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A06: " "Sending SwitchInfo attribute failed (%s)\n", ib_get_err_str(status)); } OSM_LOG_EXIT(p_mgr->p_log); }
int osm_ucast_mgr_set_fwd_table(IN osm_ucast_mgr_t * const p_mgr, IN osm_switch_t * const p_sw) { osm_node_t *p_node; osm_dr_path_t *p_path; osm_madw_context_t context; ib_api_status_t status; ib_switch_info_t si; uint16_t block_id_ho = 0; uint8_t block[IB_SMP_DATA_SIZE]; boolean_t set_swinfo_require = FALSE; uint16_t lin_top; uint8_t life_state; CL_ASSERT(p_mgr); OSM_LOG_ENTER(p_mgr->p_log); CL_ASSERT(p_sw); p_node = p_sw->p_node; CL_ASSERT(p_node); p_path = osm_physp_get_dr_path_ptr(osm_node_get_physp_ptr(p_node, 0)); /* Set the top of the unicast forwarding table. */ si = p_sw->switch_info; lin_top = cl_hton16(p_sw->max_lid_ho); if (lin_top != si.lin_top) { set_swinfo_require = TRUE; si.lin_top = lin_top; } /* check to see if the change state bit is on. If it is - then we need to clear it. */ if (ib_switch_info_get_state_change(&si)) life_state = ((p_mgr->p_subn->opt.packet_life_time << 3) | (si.life_state & IB_SWITCH_PSC)) & 0xfc; else life_state = (p_mgr->p_subn->opt.packet_life_time << 3) & 0xf8; if ((life_state != si.life_state) || ib_switch_info_get_state_change(&si)) { set_swinfo_require = TRUE; si.life_state = life_state; } if (set_swinfo_require) { OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Setting switch FT top to LID %u\n", p_sw->max_lid_ho); context.si_context.light_sweep = FALSE; context.si_context.node_guid = osm_node_get_node_guid(p_node); context.si_context.set_method = TRUE; status = osm_req_set(p_mgr->sm, p_path, (uint8_t *) & si, sizeof(si), IB_MAD_ATTR_SWITCH_INFO, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A06: " "Sending SwitchInfo attribute failed (%s)\n", ib_get_err_str(status)); } /* Send linear forwarding table blocks to the switch as long as the switch indicates it has blocks needing configuration. */ context.lft_context.node_guid = osm_node_get_node_guid(p_node); context.lft_context.set_method = TRUE; if (!p_sw->new_lft) { /* any routing should provide the new_lft */ CL_ASSERT(p_mgr->p_subn->opt.use_ucast_cache && p_mgr->cache_valid && !p_sw->need_update); goto Exit; } for (block_id_ho = 0; osm_switch_get_lft_block(p_sw, block_id_ho, block); block_id_ho++) { if (!p_sw->need_update && !memcmp(block, p_sw->new_lft + block_id_ho * IB_SMP_DATA_SIZE, IB_SMP_DATA_SIZE)) continue; OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Writing FT block %u\n", block_id_ho); status = osm_req_set(p_mgr->sm, p_path, p_sw->new_lft + block_id_ho * IB_SMP_DATA_SIZE, sizeof(block), IB_MAD_ATTR_LIN_FWD_TBL, cl_hton32(block_id_ho), CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A05: " "Sending linear fwd. tbl. block failed (%s)\n", ib_get_err_str(status)); } Exit: OSM_LOG_EXIT(p_mgr->p_log); return 0; }