static void ni_rcv_get_port_info(IN osm_sm_t * sm, IN osm_node_t * node, IN const osm_madw_t * madw) { osm_madw_context_t context; osm_physp_t *physp; ib_node_info_t *ni; unsigned port; ib_api_status_t status; int mlnx_epi_supported = 0; ni = ib_smp_get_payload_ptr(osm_madw_get_smp_ptr(madw)); port = ib_node_info_get_local_port_num(ni); if (sm->p_subn->opt.fdr10) mlnx_epi_supported = is_mlnx_ext_port_info_supported(ni->device_id); physp = osm_node_get_physp_ptr(node, port); if (!physp) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1E: " "Failed to find physp for port %d of Node GUID 0x%" PRIx64 "\n", port, cl_ntoh64(osm_node_get_node_guid(node))); return; } context.pi_context.node_guid = osm_node_get_node_guid(node); context.pi_context.port_guid = osm_physp_get_port_guid(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(physp), IB_MAD_ATTR_PORT_INFO, cl_hton32(port), TRUE, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD02: " "Failure initiating PortInfo request (%s)\n", ib_get_err_str(status)); if (mlnx_epi_supported) { status = osm_req_get(sm, osm_physp_get_dr_path_ptr(physp), IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO, cl_hton32(port), TRUE, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0B: " "Failure initiating MLNX ExtPortInfo request (%s)\n", ib_get_err_str(status)); } }
bool IBConnection::_writeKeys( const struct IBDest *myDest ) { char msg[KEY_MSG_SIZE]; sprintf( msg, KEY_PRINT_FMT, cl_hton16(myDest->lid), cl_hton32(myDest->qpn), cl_hton32(myDest->psn), cl_hton32(myDest->rkey), myDest->vaddr); _socketConnection->send( msg, KEY_MSG_SIZE ); return true; }
static void build_trap144_local(ib_mad_notice_attr_t * n, ib_portid_t * port) { n->generic_type = 0x80 | IB_NOTICE_TYPE_INFO; n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port)); n->g_or_v.generic.trap_num = cl_hton16(144); n->issuer_lid = cl_hton16((uint16_t) port->lid); n->data_details.ntc_144.lid = n->issuer_lid; n->data_details.ntc_144.new_cap_mask = cl_hton32(get_cap_mask(port)); n->data_details.ntc_144.local_changes = TRAP_144_MASK_OTHER_LOCAL_CHANGES; }
/********************************************************************** The plock must be held before calling this function. **********************************************************************/ static void pi_rcv_process_switch_port0(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; osm_madw_context_t context; uint8_t port, num_ports; OSM_LOG_ENTER(sm->p_log); if (p_physp->need_update) sm->p_subn->ignore_existing_lfts = TRUE; pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp); /* Update the PortInfo attribute */ osm_physp_set_port_info(p_physp, p_pi, sm); /* Determine if base switch port 0 */ if (p_node->sw && !ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info)) /* PortState is not used on BSP0 but just in case it is DOWN */ p_physp->port_info = *p_pi; /* Now, query PortInfo for the switch external ports */ num_ports = osm_node_get_num_physp(p_node); 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; for (port = 1; port < num_ports; port++) { status = osm_req_get(sm, osm_physp_get_dr_path_ptr(p_physp), IB_MAD_ATTR_PORT_INFO, cl_hton32(port), FALSE, ib_port_info_get_m_key(&p_physp->port_info), CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F16: " "Failure initiating PortInfo request (%s)\n", ib_get_err_str(status)); } pi_rcv_process_endport(sm, p_physp, p_pi); OSM_LOG_EXIT(sm->p_log); }
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 qos_mad_item_t *osm_qos_mad_create(IN osm_sm_t * sm, IN osm_physp_t * p, IN uint32_t data_size, IN uint8_t * p_data, IN ib_net16_t attr_id, IN uint32_t attr_mod) { qos_mad_item_t *p_mad; osm_madw_context_t context; osm_madw_t *p_madw; osm_node_t *p_node; p_node = osm_physp_get_node_ptr(p); switch (attr_id){ case IB_MAD_ATTR_SLVL_TABLE: 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; break; case IB_MAD_ATTR_VL_ARBITRATION: context.vla_context.node_guid = osm_node_get_node_guid(p_node); context.vla_context.port_guid = osm_physp_get_port_guid(p); context.vla_context.set_method = TRUE; break; default: return NULL; } p_mad = (qos_mad_item_t *) malloc(sizeof(*p_mad)); if (!p_mad) return NULL; memset(p_mad, 0, sizeof(*p_mad)); p_madw = osm_prepare_req_set(sm, osm_physp_get_dr_path_ptr(p), p_data, data_size, attr_id, cl_hton32(attr_mod), CL_DISP_MSGID_NONE, &context); if (p_madw == NULL) { free(p_mad); return NULL; } p_mad->p_madw = p_madw; return p_mad; }
static void mpr_rcv_build_pr(IN osm_sa_t * sa, IN const osm_alias_guid_t * p_src_alias_guid, IN const osm_alias_guid_t * p_dest_alias_guid, IN uint16_t src_lid_ho, IN uint16_t dest_lid_ho, IN uint8_t preference, IN const osm_path_parms_t * p_parms, OUT ib_path_rec_t * p_pr) { const osm_physp_t *p_src_physp, *p_dest_physp; OSM_LOG_ENTER(sa->p_log); p_src_physp = p_src_alias_guid->p_base_port->p_physp; p_dest_physp = p_dest_alias_guid->p_base_port->p_physp; p_pr->dgid.unicast.prefix = osm_physp_get_subnet_prefix(p_dest_physp); p_pr->dgid.unicast.interface_id = osm_physp_get_port_guid(p_dest_physp); p_pr->sgid.unicast.prefix = osm_physp_get_subnet_prefix(p_src_physp); p_pr->sgid.unicast.interface_id = osm_physp_get_port_guid(p_src_physp); p_pr->dlid = cl_hton16(dest_lid_ho); p_pr->slid = cl_hton16(src_lid_ho); p_pr->hop_flow_raw &= cl_hton32(1 << 31); p_pr->pkey = p_parms->pkey; ib_path_rec_set_qos_class(p_pr, 0); ib_path_rec_set_sl(p_pr, p_parms->sl); p_pr->mtu = (uint8_t) (p_parms->mtu | 0x80); p_pr->rate = (uint8_t) (p_parms->rate | 0x80); /* According to 1.2 spec definition Table 205 PacketLifeTime description, for loopback paths, packetLifeTime shall be zero. */ if (p_src_alias_guid->p_base_port == p_dest_alias_guid->p_base_port) p_pr->pkt_life = 0x80; /* loopback */ else p_pr->pkt_life = (uint8_t) (p_parms->pkt_life | 0x80); p_pr->preference = preference; /* always return num_path = 0 so this is only the reversible component */ if (p_parms->reversible) p_pr->num_path = 0x80; OSM_LOG_EXIT(sa->p_log); }
/********************************************************************** 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); }
IBInterface::IBInterface( ) : _completionQueue( 0 ) , _queuePair( 0 ) , _posReadInBuffer( 0 ) , _firstTimeWrite( true ) , _numBufRead( 0 ) , _numBufWrite( 0 ) { srand(1); _countWrite = 0; _psn = cl_hton32( rand() & 0xffffff ); _writePoll.resize( EQ_NUMBLOCKMEMORY ); _readPoll.resize( EQ_NUMBLOCKMEMORY ); _dests.resize( EQ_NUMBLOCKMEMORY ); _writeBlocks.resize( EQ_NUMBLOCKMEMORY ); _readBlocks.resize( EQ_NUMBLOCKMEMORY ); for (int i = 0; i < EQ_NUMBLOCKMEMORY ; i++) { _writeBlocks[i] = new IBMemBlock(); _readBlocks[i] = new IBMemBlock(); } memset( _readPoll.getData(), 0, sizeof ( uint32_t ) * EQ_NUMBLOCKMEMORY ); memset( _writePoll.getData(), true, sizeof ( bool ) * EQ_NUMBLOCKMEMORY ); _floatTimeReadNB = 0.0f; _floatTimeReadSync = 0.0f; _timeTotalWaitPoll = 0.0f; _timeTotalWaitobj = 0.0f; _timeTotalWrite = 0.0f; _timeTotalWriteWait = 0.0f; _timeCopyBufferRead = 0.0f; _timeCopyBufferWrite = 0.0f; }
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); }
/********************************************************************** * 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); }
/********************************************************************** 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); }
/********************************************************************** 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); }
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; }
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); }
/* * Register/Unregister to receive the given InformInfo * * Uses the qp context to send the inform info mad. * Wait for GetResp(InformInfoResp) * */ ib_api_status_t osmt_reg_unreg_inform_info(IN osmtest_t * p_osmt, IN osmt_qp_ctx_t * p_qp_ctx, IN ib_inform_info_t * p_inform_info, IN uint8_t reg_flag) { ib_sa_mad_t *p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_send_buf); ib_inform_info_t *p_ii = ib_sa_mad_get_payload_ptr(p_sa_mad); /* SA Payload */ VAPI_ret_t vapi_ret; VAPI_wc_desc_t wc_desc; VAPI_ud_av_hndl_t avh; static VAPI_wr_id_t wrid = 16198; osm_log_t *p_log = &p_osmt->log; ib_api_status_t status = IB_SUCCESS; OSM_LOG_ENTER(&p_osmt->log); /* init the MAD */ ib_mad_init_new((ib_mad_t *) p_sa_mad, IB_MCLASS_SUBN_ADM, (uint8_t) 2, IB_MAD_METHOD_SET, cl_hton64(wrid), (ib_net16_t) 0, 0); wrid++; p_sa_mad->attr_id = IB_MAD_ATTR_INFORM_INFO; /* copy the reference inform info */ memcpy(p_ii, p_inform_info, sizeof(ib_inform_info_t)); if (reg_flag) { OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "Subscribing InformInfo: Traps from lid:0x%X to 0x%X, trap num :0x%X\n", p_ii->lid_range_begin, p_ii->lid_range_end, p_ii->g_or_v.generic.trap_num); } else { OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "UnSubscribing InformInfo: Traps from lid:0x%X to 0x%X\n", p_ii->lid_range_begin, p_ii->lid_range_end); } /* set the subscribe bit */ if (reg_flag) { p_ii->subscribe = 1; } else { p_ii->subscribe = 0; /* * we need to set the QPN on the mad if we unsubscribe: * o13-2.1.1 - QPN Field need to be set when unsubscribing. */ ib_inform_info_set_qpn(p_ii, cl_hton32(p_qp_ctx->qp_bind_hndl.qp_id. qp_num)); } osm_dump_inform_info(&p_osmt->log, p_ii, OSM_LOG_DEBUG); /* --------------------- PREP ------------------------- */ if (osmt_mtl_mad_post_recv_bufs(&p_qp_ctx->qp_bind_hndl, p_qp_ctx->p_recv_buf, 1, /* but we need only one mad at a time */ GRH_LEN + MAD_BLOCK_SIZE, wrid) != 1) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0120: " "Error posting recv bufs\n"); status = IB_ERROR; goto Exit; } OSM_LOG(p_log, OSM_LOG_DEBUG, "Posted recv bufs\n"); vapi_ret = osmt_mtl_create_av(&p_qp_ctx->qp_bind_hndl, p_osmt->local_port.sm_lid, &avh); if (vapi_ret != VAPI_OK) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0121: " "Error Preparing AVH (%s)\n", VAPI_strerror_sym(vapi_ret)); status = IB_ERROR; goto Exit; } OSM_LOG(p_log, OSM_LOG_DEBUG, "Prepared AVH\n"); if (osm_log_is_active(p_log, OSM_LOG_DEBUG)) { osm_dump_sa_mad(p_log, (ib_sa_mad_t *) (p_qp_ctx->p_send_buf), OSM_LOG_DEBUG); #if 0 for (i = 56; i < 253; i++) { if (i % 8 == 0) { printf("\n %d : ", i); } printf("0x%02X ", p_qp_ctx->p_send_buf[i]); } #endif printf("\n"); } /* --------------------- SEND ------------------------- */ vapi_ret = osmt_mtl_mad_send(&p_qp_ctx->qp_bind_hndl, wrid, p_qp_ctx->p_send_buf, 1, /* SA is QP1 */ 0, /* SL is 0 */ OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY, avh); if (vapi_ret != VAPI_OK) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0122: " "Error sending mad (%s)\n", VAPI_strerror_sym(vapi_ret)); status = IB_ERROR; goto Exit; } vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl, p_qp_ctx->qp_bind_hndl.sq_cq_hndl, &wc_desc, 20, 10000, NULL); if (vapi_ret != VAPI_OK) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0123: " "Error getting send completion (%s)\n", VAPI_strerror_sym(vapi_ret)); status = IB_ERROR; goto Exit; } if (wc_desc.status != VAPI_SUCCESS) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0124: " "Error on send completion (%s) (%d)\n", VAPI_strerror_sym(wc_desc.status), wc_desc.status); status = IB_ERROR; goto Exit; } OSM_LOG(p_log, OSM_LOG_DEBUG, "Sent MAD\n"); /* --------------------- RECV ------------------------- */ vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl, p_qp_ctx->qp_bind_hndl.rq_cq_hndl, &wc_desc, 20, 10000, &avh); if (vapi_ret != VAPI_SUCCESS) { if (vapi_ret == VAPI_CQ_EMPTY) { status = IB_TIMEOUT; } else { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0125: " "Error receiving mad (%s)\n", VAPI_strerror_sym(vapi_ret)); status = IB_ERROR; } goto Exit; } /* check to see if successful - by examination of the subscribe bit */ p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_recv_buf + GRH_LEN); if (p_sa_mad->status != IB_SUCCESS) { OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "Remote error = %s\n", ib_get_mad_status_str((ib_mad_t *) p_sa_mad)); status = IB_REMOTE_ERROR; goto Exit; } if (p_sa_mad->method != IB_MAD_METHOD_GET_RESP) { OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "Expected IB_MAD_METHOD_GET_RESP but got:(%X)\n", p_sa_mad->method); status = IB_REMOTE_ERROR; goto Exit; } if (p_sa_mad->attr_id != IB_MAD_ATTR_INFORM_INFO) { OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "Expected IB_MAD_ATTR_INFORM_INFO but got:(%X)\n", cl_ntoh16(p_sa_mad->attr_id)); status = IB_REMOTE_ERROR; goto Exit; } p_ii = ib_sa_mad_get_payload_ptr(p_sa_mad); if (!p_ii->subscribe) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0126: " "Subscribe/Unsubscribe Failed\n"); status = IB_REMOTE_ERROR; } Exit: OSM_LOG_EXIT(&p_osmt->log); return status; }
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; }