void smt_emulate_token_ct(struct s_smc *smc, int mac_index) { u_long count; u_long time; time = smt_get_time(); count = ((time - smc->sm.last_tok_time[mac_index]) * 100)/TICKS_PER_SECOND; if (smc->hw.mac_ring_is_up){ smc->mib.m[mac_index].fddiMACToken_Ct += count; } smc->sm.last_tok_time[mac_index] = time; }
void smt_emulate_token_ct(struct s_smc *smc, int mac_index) { u_long count; u_long time; time = smt_get_time(); count = ((time - smc->sm.last_tok_time[mac_index]) * 100)/TICKS_PER_SECOND; /* * Only when ring is up we will have a token count. The * flag is unfortunatly a single instance value. This * doesn't matter now, because we currently have only * one MAC instance. */ if (smc->hw.mac_ring_is_up){ smc->mib.m[mac_index].fddiMACToken_Ct += count; } /* Remember current time */ smc->sm.last_tok_time[mac_index] = time; }
void smt_init_evc(struct s_smc *smc) { struct s_srf_evc *evc ; const struct evc_init *init ; int i ; int index ; int offset ; static u_char fail_safe = FALSE ; memset((char *)smc->evcs,0,sizeof(smc->evcs)) ; evc = smc->evcs ; init = evc_inits ; for (i = 0 ; (unsigned) i < MAX_INIT_EVC ; i++) { for (index = 0 ; index < init->n ; index++) { evc->evc_code = init->code ; evc->evc_para = init->para ; evc->evc_index = init->index + index ; #ifndef DEBUG evc->evc_multiple = &fail_safe ; evc->evc_cond_state = &fail_safe ; #endif evc++ ; } init++ ; } if ((unsigned) (evc - smc->evcs) > MAX_EVCS) { SMT_PANIC(smc,SMT_E0127, SMT_E0127_MSG) ; } /* * conditions */ smc->evcs[0].evc_cond_state = &smc->mib.fddiSMTPeerWrapFlag ; smc->evcs[1].evc_cond_state = &smc->mib.m[MAC0].fddiMACDuplicateAddressCond ; smc->evcs[2].evc_cond_state = &smc->mib.m[MAC0].fddiMACFrameErrorFlag ; smc->evcs[3].evc_cond_state = &smc->mib.m[MAC0].fddiMACNotCopiedFlag ; /* * events */ smc->evcs[4].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_N ; smc->evcs[5].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_P ; offset = 6 ; for (i = 0 ; i < NUMPHYS ; i++) { /* * conditions */ smc->evcs[offset + 0*NUMPHYS].evc_cond_state = &smc->mib.p[i].fddiPORTLerFlag ; smc->evcs[offset + 1*NUMPHYS].evc_cond_state = &smc->mib.p[i].fddiPORTEB_Condition ; /* * events */ smc->evcs[offset + 2*NUMPHYS].evc_multiple = &smc->mib.p[i].fddiPORTMultiple_U ; smc->evcs[offset + 3*NUMPHYS].evc_multiple = &smc->mib.p[i].fddiPORTMultiple_P ; offset++ ; } #ifdef DEBUG for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) { if (SMT_IS_CONDITION(evc->evc_code)) { if (!evc->evc_cond_state) { SMT_PANIC(smc,SMT_E0128, SMT_E0128_MSG) ; } evc->evc_multiple = &fail_safe ; } else { if (!evc->evc_multiple) { SMT_PANIC(smc,SMT_E0129, SMT_E0129_MSG) ; } evc->evc_cond_state = &fail_safe ; } } #endif smc->srf.TSR = smt_get_time() ; smc->srf.sr_state = SR0_WAIT ; }
void smt_srf_event(struct s_smc *smc, int code, int index, int cond) { struct s_srf_evc *evc ; int cond_asserted = 0 ; int cond_deasserted = 0 ; int event_occurred = 0 ; int tsr ; int T_Limit = 2*TICKS_PER_SECOND ; if (code == SMT_COND_MAC_DUP_ADDR && cond) { RS_SET(smc,RS_DUPADDR) ; } if (code) { DB_SMT("SRF: %s index %d\n",srf_names[code],index) ; if (!(evc = smt_get_evc(smc,code,index))) { DB_SMT("SRF : smt_get_evc() failed\n",0,0) ; return ; } /* * ignore condition if no change */ if (SMT_IS_CONDITION(code)) { if (*evc->evc_cond_state == cond) return ; } /* * set transition time stamp */ smt_set_timestamp(smc,smc->mib.fddiSMTTransitionTimeStamp) ; if (SMT_IS_CONDITION(code)) { DB_SMT("SRF: condition is %s\n",cond ? "ON":"OFF",0) ; if (cond) { *evc->evc_cond_state = TRUE ; evc->evc_rep_required = TRUE ; smc->srf.any_report = TRUE ; cond_asserted = TRUE ; } else { *evc->evc_cond_state = FALSE ; cond_deasserted = TRUE ; } } else { if (evc->evc_rep_required) { *evc->evc_multiple = TRUE ; } else { evc->evc_rep_required = TRUE ; *evc->evc_multiple = FALSE ; } smc->srf.any_report = TRUE ; event_occurred = TRUE ; } #ifdef FDDI_MIB snmp_srf_event(smc,evc) ; #endif /* FDDI_MIB */ } tsr = smt_get_time() - smc->srf.TSR ; switch (smc->srf.sr_state) { case SR0_WAIT : /* SR01a */ if (cond_asserted && tsr < T_Limit) { smc->srf.SRThreshold = THRESHOLD_2 ; smc->srf.sr_state = SR1_HOLDOFF ; break ; } /* SR01b */ if (cond_deasserted && tsr < T_Limit) { smc->srf.sr_state = SR1_HOLDOFF ; break ; } /* SR01c */ if (event_occurred && tsr < T_Limit) { smc->srf.sr_state = SR1_HOLDOFF ; break ; } /* SR00b */ if (cond_asserted && tsr >= T_Limit) { smc->srf.SRThreshold = THRESHOLD_2 ; smc->srf.TSR = smt_get_time() ; smt_send_srf(smc) ; break ; } /* SR00c */ if (cond_deasserted && tsr >= T_Limit) { smc->srf.TSR = smt_get_time() ; smt_send_srf(smc) ; break ; } /* SR00d */ if (event_occurred && tsr >= T_Limit) { smc->srf.TSR = smt_get_time() ; smt_send_srf(smc) ; break ; } /* SR00e */ if (smc->srf.any_report && (u_long) tsr >= smc->srf.SRThreshold) { smc->srf.SRThreshold *= 2 ; if (smc->srf.SRThreshold > THRESHOLD_32) smc->srf.SRThreshold = THRESHOLD_32 ; smc->srf.TSR = smt_get_time() ; smt_send_srf(smc) ; break ; } /* SR02 */ if (!smc->mib.fddiSMTStatRptPolicy) { smc->srf.sr_state = SR2_DISABLED ; break ; } break ; case SR1_HOLDOFF : /* SR10b */ if (tsr >= T_Limit) { smc->srf.sr_state = SR0_WAIT ; smc->srf.TSR = smt_get_time() ; smt_send_srf(smc) ; break ; } /* SR11a */ if (cond_asserted) { smc->srf.SRThreshold = THRESHOLD_2 ; } /* SR11b */ /* SR11c */ /* handled above */ /* SR12 */ if (!smc->mib.fddiSMTStatRptPolicy) { smc->srf.sr_state = SR2_DISABLED ; break ; } break ; case SR2_DISABLED : if (smc->mib.fddiSMTStatRptPolicy) { smc->srf.sr_state = SR0_WAIT ; smc->srf.TSR = smt_get_time() ; smc->srf.SRThreshold = THRESHOLD_2 ; clear_all_rep(smc) ; break ; } break ; } }
void smt_reset_defaults(struct s_smc *smc, int level) { struct smt_config *smt ; int i ; u_long smt_boot_time; smt_init_mib(smc,level) ; smc->os.smc_version = SMC_VERSION ; smt_boot_time = smt_get_time(); for( i = 0; i < NUMMACS; i++ ) smc->sm.last_tok_time[i] = smt_boot_time ; smt = &smc->s ; smt->attach_s = 0 ; smt->build_ring_map = 1 ; smt->sas = SMT_DAS ; smt->numphys = NUMPHYS ; smt->pcm_tb_min = DEFAULT_TB_MIN ; smt->pcm_tb_max = DEFAULT_TB_MAX ; smt->pcm_c_min = DEFAULT_C_MIN ; smt->pcm_t_out = DEFAULT_T_OUT ; smt->pcm_tl_min = DEFAULT_TL_MIN ; smt->pcm_lc_short = DEFAULT_LC_SHORT ; smt->pcm_lc_medium = DEFAULT_LC_MEDIUM ; smt->pcm_lc_long = DEFAULT_LC_LONG ; smt->pcm_lc_extended = DEFAULT_LC_EXTENDED ; smt->pcm_t_next_9 = DEFAULT_T_NEXT_9 ; smt->pcm_ns_max = DEFAULT_NS_MAX ; smt->ecm_i_max = DEFAULT_I_MAX ; smt->ecm_in_max = DEFAULT_IN_MAX ; smt->ecm_td_min = DEFAULT_TD_MIN ; smt->ecm_test_done = DEFAULT_TEST_DONE ; smt->ecm_check_poll = DEFAULT_CHECK_POLL ; smt->rmt_t_non_op = DEFAULT_T_NON_OP ; smt->rmt_t_stuck = DEFAULT_T_STUCK ; smt->rmt_t_direct = DEFAULT_T_DIRECT ; smt->rmt_t_jam = DEFAULT_T_JAM ; smt->rmt_t_announce = DEFAULT_T_ANNOUNCE ; smt->rmt_t_poll = DEFAULT_POLL ; smt->rmt_dup_mac_behavior = FALSE ; /* See Struct smt_config */ smt->mac_d_max = DEFAULT_D_MAX ; smt->lct_short = DEFAULT_LCT_SHORT ; smt->lct_medium = DEFAULT_LCT_MEDIUM ; smt->lct_long = DEFAULT_LCT_LONG ; smt->lct_extended = DEFAULT_LCT_EXTEND ; #ifndef SLIM_SMT #ifdef ESS if (level == 0) { smc->ess.sync_bw_available = FALSE ; smc->mib.fddiESSPayload = 0 ; smc->mib.fddiESSOverhead = 0 ; smc->mib.fddiESSMaxTNeg = (u_long)(- MS2BCLK(25)) ; smc->mib.fddiESSMinSegmentSize = 1 ; smc->mib.fddiESSCategory = SB_STATIC ; smc->mib.fddiESSSynchTxMode = FALSE ; smc->ess.raf_act_timer_poll = FALSE ; smc->ess.timer_count = 7 ; /* first RAF alc req after 3s */ } smc->ess.local_sba_active = FALSE ; smc->ess.sba_reply_pend = NULL ; #endif #ifdef SBA smt_init_sba(smc,level) ; #endif #endif /* no SLIM_SMT */ #ifdef TAG_MODE if (level == 0) { smc->hw.pci_fix_value = 0 ; } #endif }
void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs) { struct smt_header *sm ; int local ; int illegal = 0 ; switch (m_fc(mb)) { case FC_SMT_INFO : case FC_SMT_LAN_LOC : case FC_SMT_LOC : case FC_SMT_NSA : break ; default : smt_free_mbuf(smc,mb) ; return ; } smc->mib.m[MAC0].fddiMACSMTCopied_Ct++ ; sm = smtod(mb,struct smt_header *) ; local = ((fs & L_INDICATOR) != 0) ; hwm_conv_can(smc,(char *)sm,12) ; if (is_individual(&sm->smt_dest) && !is_my_addr(smc,&sm->smt_dest)) { smt_free_mbuf(smc,mb) ; return ; } #if 0 if (is_my_addr(smc,&sm->smt_source) && !local) { smt_free_mbuf(smc,mb) ; return ; } #endif smt_swap_para(sm,(int) mb->sm_len,1) ; DB_SMT("SMT : received packet [%s] at 0x%x\n", smt_type_name[m_fc(mb) & 0xf],sm) ; DB_SMT("SMT : version %d, class %s\n",sm->smt_version, smt_class_name[(sm->smt_class>LAST_CLASS)?0 : sm->smt_class]) ; #ifdef SBA if (m_fc(mb) == FC_SMT_NSA && sm->smt_class == SMT_NIF && (sm->smt_type == SMT_ANNOUNCE || sm->smt_type == SMT_REQUEST)) { smc->sba.sm = sm ; sba(smc,NIF) ; } #endif if ( (fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) { DB_SMT("SMT : ignoring NSA with A-indicator set from %s\n", addr_to_string(&sm->smt_source),0) ; smt_free_mbuf(smc,mb) ; return ; } if (((sm->smt_class == SMT_ECF) && (sm->smt_len > SMT_MAX_ECHO_LEN)) || ((sm->smt_class != SMT_ECF) && (sm->smt_len > SMT_MAX_INFO_LEN))) { smt_free_mbuf(smc,mb) ; return ; } switch (sm->smt_class) { case SMT_NIF : case SMT_SIF_CONFIG : case SMT_SIF_OPER : case SMT_ECF : if (sm->smt_version != SMT_VID) illegal = 1; break ; default : if (sm->smt_version != SMT_VID_2) illegal = 1; break ; } if (illegal) { DB_SMT("SMT : version = %d, dest = %s\n", sm->smt_version,addr_to_string(&sm->smt_source)) ; smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_VERSION,local) ; smt_free_mbuf(smc,mb) ; return ; } if ((sm->smt_len > mb->sm_len - sizeof(struct smt_header)) || ((sm->smt_len & 3) && (sm->smt_class != SMT_ECF))) { DB_SMT("SMT: info length error, len = %d\n",sm->smt_len,0) ; smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_LENGTH,local) ; smt_free_mbuf(smc,mb) ; return ; } switch (sm->smt_class) { case SMT_NIF : if (smt_check_para(smc,sm,plist_nif)) { DB_SMT("SMT: NIF with para problem, ignoring\n",0,0) ; break ; } ; switch (sm->smt_type) { case SMT_ANNOUNCE : case SMT_REQUEST : if (!(fs & C_INDICATOR) && m_fc(mb) == FC_SMT_NSA && is_broadcast(&sm->smt_dest)) { struct smt_p_state *st ; if (!is_equal( &smc->mib.m[MAC0].fddiMACUpstreamNbr, &sm->smt_source)) { DB_SMT("SMT : updated my UNA = %s\n", addr_to_string(&sm->smt_source),0) ; if (!is_equal(&smc->mib.m[MAC0]. fddiMACUpstreamNbr,&SMT_Unknown)){ smc->mib.m[MAC0].fddiMACOldUpstreamNbr= smc->mib.m[MAC0].fddiMACUpstreamNbr ; } smc->mib.m[MAC0].fddiMACUpstreamNbr = sm->smt_source ; smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC,0) ; smt_echo_test(smc,0) ; } smc->sm.smt_tvu = smt_get_time() ; st = (struct smt_p_state *) sm_to_para(smc,sm,SMT_P_STATE) ; if (st) { smc->mib.m[MAC0].fddiMACUNDA_Flag = (st->st_dupl_addr & SMT_ST_MY_DUPA) ? TRUE : FALSE ; update_dac(smc,1) ; } } if ((sm->smt_type == SMT_REQUEST) && is_individual(&sm->smt_source) && ((!(fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) || (m_fc(mb) != FC_SMT_NSA))) { DB_SMT("SMT : replying to NIF request %s\n", addr_to_string(&sm->smt_source),0) ; smt_send_nif(smc,&sm->smt_source, FC_SMT_INFO, sm->smt_tid, SMT_REPLY,local) ; } break ; case SMT_REPLY : DB_SMT("SMT : received NIF response from %s\n", addr_to_string(&sm->smt_source),0) ; if (fs & A_INDICATOR) { smc->sm.pend[SMT_TID_NIF] = 0 ; DB_SMT("SMT : duplicate address\n",0,0) ; smc->mib.m[MAC0].fddiMACDupAddressTest = DA_FAILED ; smc->r.dup_addr_test = DA_FAILED ; queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ; smc->mib.m[MAC0].fddiMACDA_Flag = TRUE ; update_dac(smc,1) ; break ; } if (sm->smt_tid == smc->sm.pend[SMT_TID_NIF]) { smc->sm.pend[SMT_TID_NIF] = 0 ; if (!is_equal( &smc->mib.m[MAC0].fddiMACDownstreamNbr, &sm->smt_source)) { DB_SMT("SMT : updated my DNA\n",0,0) ; if (!is_equal(&smc->mib.m[MAC0]. fddiMACDownstreamNbr, &SMT_Unknown)){ smc->mib.m[MAC0].fddiMACOldDownstreamNbr = smc->mib.m[MAC0].fddiMACDownstreamNbr ; } smc->mib.m[MAC0].fddiMACDownstreamNbr = sm->smt_source ; smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC,0) ; smt_echo_test(smc,1) ; } smc->mib.m[MAC0].fddiMACDA_Flag = FALSE ; update_dac(smc,1) ; smc->sm.smt_tvd = smt_get_time() ; smc->mib.m[MAC0].fddiMACDupAddressTest = DA_PASSED ; if (smc->r.dup_addr_test != DA_PASSED) { smc->r.dup_addr_test = DA_PASSED ; queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ; } } else if (sm->smt_tid == smc->sm.pend[SMT_TID_NIF_TEST]) { DB_SMT("SMT : NIF test TID ok\n",0,0) ; } else { DB_SMT("SMT : expected TID %lx, got %lx\n", smc->sm.pend[SMT_TID_NIF],sm->smt_tid) ; } break ; default : illegal = 2 ; break ; } break ; case SMT_SIF_CONFIG : if (sm->smt_type != SMT_REQUEST) break ; DB_SMT("SMT : replying to SIF Config request from %s\n", addr_to_string(&sm->smt_source),0) ; smt_send_sif_config(smc,&sm->smt_source,sm->smt_tid,local) ; break ; case SMT_SIF_OPER : if (sm->smt_type != SMT_REQUEST) break ; DB_SMT("SMT : replying to SIF Operation request from %s\n", addr_to_string(&sm->smt_source),0) ; smt_send_sif_operation(smc,&sm->smt_source,sm->smt_tid,local) ; break ; case SMT_ECF : switch (sm->smt_type) { case SMT_REPLY : smc->mib.priv.fddiPRIVECF_Reply_Rx++ ; DB_SMT("SMT: received ECF reply from %s\n", addr_to_string(&sm->smt_source),0) ; if (sm_to_para(smc,sm,SMT_P_ECHODATA) == NULL) { DB_SMT("SMT: ECHODATA missing\n",0,0) ; break ; } if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF]) { DB_SMT("SMT : ECF test TID ok\n",0,0) ; } else if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF_UNA]) { DB_SMT("SMT : ECF test UNA ok\n",0,0) ; } else if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF_DNA]) { DB_SMT("SMT : ECF test DNA ok\n",0,0) ; } else { DB_SMT("SMT : expected TID %lx, got %lx\n", smc->sm.pend[SMT_TID_ECF], sm->smt_tid) ; } break ; case SMT_REQUEST : smc->mib.priv.fddiPRIVECF_Req_Rx++ ; { if (sm->smt_len && !sm_to_para(smc,sm,SMT_P_ECHODATA)) { DB_SMT("SMT: ECF with para problem,sending RDF\n",0,0) ; smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_LENGTH, local) ; break ; } DB_SMT("SMT - sending ECF reply to %s\n", addr_to_string(&sm->smt_source),0) ; sm->smt_dest = sm->smt_source ; sm->smt_type = SMT_REPLY ; dump_smt(smc,sm,"ECF REPLY") ; smc->mib.priv.fddiPRIVECF_Reply_Tx++ ; smt_send_frame(smc,mb,FC_SMT_INFO,local) ; return ; } default : illegal = 1 ; break ; } break ; #ifndef BOOT case SMT_RAF : #ifdef ESS DB_ESSN(2,"ESS: RAF frame received\n",0,0) ; fs = ess_raf_received_pack(smc,mb,sm,fs) ; #endif #ifdef SBA DB_SBAN(2,"SBA: RAF frame received\n",0,0) ; sba_raf_received_pack(smc,sm,fs) ; #endif break ; case SMT_RDF : smc->mib.priv.fddiPRIVRDF_Rx++ ; break ; case SMT_ESF : if (sm->smt_type == SMT_REQUEST) { DB_SMT("SMT - received ESF, sending RDF\n",0,0) ; smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ; } break ; case SMT_PMF_GET : case SMT_PMF_SET : if (sm->smt_type != SMT_REQUEST) break ; if (sm->smt_class == SMT_PMF_GET) smc->mib.priv.fddiPRIVPMF_Get_Rx++ ; else smc->mib.priv.fddiPRIVPMF_Set_Rx++ ; if ((sm->smt_class == SMT_PMF_SET) && !is_individual(&sm->smt_dest)) { DB_SMT("SMT: ignoring PMF-SET with I/G set\n",0,0) ; break ; } smt_pmf_received_pack(smc,mb, local) ; break ; case SMT_SRF : dump_smt(smc,sm,"SRF received") ; break ; default : if (sm->smt_type != SMT_REQUEST) break ; DB_SMT("SMT : class = %d, send RDF to %s\n", sm->smt_class, addr_to_string(&sm->smt_source)) ; smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ; break ; #endif } if (illegal) { DB_SMT("SMT: discarding invalid frame, reason = %d\n", illegal,0) ; } smt_free_mbuf(smc,mb) ; }
void smt_event(struct s_smc *smc, int event) { u_long time ; #ifndef SMT_REAL_TOKEN_CT int i ; #endif if (smc->sm.please_reconnect) { smc->sm.please_reconnect -- ; if (smc->sm.please_reconnect == 0) { queue_event(smc,EVENT_ECM,EC_CONNECT) ; } } if (event == SM_FAST) return ; smt_timer_poll(smc) ; smt_start_watchdog(smc) ; #ifndef SLIM_SMT #ifndef BOOT #ifdef ESS ess_timer_poll(smc) ; #endif #endif #ifdef SBA sba_timer_poll(smc) ; #endif smt_srf_event(smc,0,0,0) ; #endif time = smt_get_time() ; if (time - smc->sm.smt_last_lem >= TICKS_PER_SECOND*8) { struct fddi_mib_m *mib ; u_long upper ; u_long lower ; int cond ; int port; struct s_phy *phy ; sm_lem_evaluate(smc) ; smc->sm.smt_last_lem = time ; #ifndef SLIM_SMT mac_update_counter(smc) ; mib = smc->mib.m ; upper = (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) + (mib->fddiMACError_Ct - mib->fddiMACOld_Error_Ct) ; lower = (mib->fddiMACFrame_Ct - mib->fddiMACOld_Frame_Ct) + (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) ; mib->fddiMACFrameErrorRatio = div_ratio(upper,lower) ; cond = ((!mib->fddiMACFrameErrorThreshold && mib->fddiMACError_Ct != mib->fddiMACOld_Error_Ct) || (mib->fddiMACFrameErrorRatio > mib->fddiMACFrameErrorThreshold)) ; if (cond != mib->fddiMACFrameErrorFlag) smt_srf_event(smc,SMT_COND_MAC_FRAME_ERROR, INDEX_MAC,cond) ; upper = (mib->fddiMACNotCopied_Ct - mib->fddiMACOld_NotCopied_Ct) ; lower = upper + (mib->fddiMACCopied_Ct - mib->fddiMACOld_Copied_Ct) ; mib->fddiMACNotCopiedRatio = div_ratio(upper,lower) ; cond = ((!mib->fddiMACNotCopiedThreshold && mib->fddiMACNotCopied_Ct != mib->fddiMACOld_NotCopied_Ct)|| (mib->fddiMACNotCopiedRatio > mib->fddiMACNotCopiedThreshold)) ; if (cond != mib->fddiMACNotCopiedFlag) smt_srf_event(smc,SMT_COND_MAC_NOT_COPIED, INDEX_MAC,cond) ; mib->fddiMACOld_Frame_Ct = mib->fddiMACFrame_Ct ; mib->fddiMACOld_Copied_Ct = mib->fddiMACCopied_Ct ; mib->fddiMACOld_Error_Ct = mib->fddiMACError_Ct ; mib->fddiMACOld_Lost_Ct = mib->fddiMACLost_Ct ; mib->fddiMACOld_NotCopied_Ct = mib->fddiMACNotCopied_Ct ; for (port = 0; port < NUMPHYS; port ++) { phy = &smc->y[port] ; if (!phy->mib->fddiPORTHardwarePresent) { continue; } cond = (phy->mib->fddiPORTEBError_Ct - phy->mib->fddiPORTOldEBError_Ct > 5) ; smt_srf_event(smc,SMT_COND_PORT_EB_ERROR, (int) (INDEX_PORT+ phy->np) ,cond) ; phy->mib->fddiPORTOldEBError_Ct = phy->mib->fddiPORTEBError_Ct ; } #endif } #ifndef SLIM_SMT if (time - smc->sm.smt_last_notify >= (u_long) (smc->mib.fddiSMTTT_Notify * TICKS_PER_SECOND) ) { if (!smc->sm.pend[SMT_TID_NIF]) smc->sm.pend[SMT_TID_NIF] = smt_get_tid(smc) ; smt_send_nif(smc,&fddi_broadcast, FC_SMT_NSA, smc->sm.pend[SMT_TID_NIF], SMT_REQUEST,0) ; smc->sm.smt_last_notify = time ; } if (smc->sm.smt_tvu && time - smc->sm.smt_tvu > 228*TICKS_PER_SECOND) { DB_SMT("SMT : UNA expired\n",0,0) ; smc->sm.smt_tvu = 0 ; if (!is_equal(&smc->mib.m[MAC0].fddiMACUpstreamNbr, &SMT_Unknown)){ smc->mib.m[MAC0].fddiMACOldUpstreamNbr= smc->mib.m[MAC0].fddiMACUpstreamNbr ; } smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACUNDA_Flag = FALSE ; update_dac(smc,0) ; smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC,0) ; } if (smc->sm.smt_tvd && time - smc->sm.smt_tvd > 228*TICKS_PER_SECOND) { DB_SMT("SMT : DNA expired\n",0,0) ; smc->sm.smt_tvd = 0 ; if (!is_equal(&smc->mib.m[MAC0].fddiMACDownstreamNbr, &SMT_Unknown)){ smc->mib.m[MAC0].fddiMACOldDownstreamNbr= smc->mib.m[MAC0].fddiMACDownstreamNbr ; } smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ; smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC,0) ; } #endif #ifndef SMT_REAL_TOKEN_CT for (i = MAC0; i < NUMMACS; i++ ){ if (time - smc->sm.last_tok_time[i] > 2*TICKS_PER_SECOND ){ smt_emulate_token_ct( smc, i ); } } #endif smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L, EV_TOKEN(EVENT_SMT,SM_TIMER)) ; }
/*ARGSUSED1*/ void smt_event(struct s_smc *smc, int event) { u_long time ; #ifndef SMT_REAL_TOKEN_CT int i ; #endif if (smc->sm.please_reconnect) { smc->sm.please_reconnect -- ; if (smc->sm.please_reconnect == 0) { /* Counted down */ queue_event(smc,EVENT_ECM,EC_CONNECT) ; } } if (event == SM_FAST) return ; /* * timer for periodic cleanup in driver * reset and start the watchdog (FM2) * ESS timer * SBA timer */ smt_timer_poll(smc) ; smt_start_watchdog(smc) ; #ifndef SLIM_SMT #ifndef BOOT #ifdef ESS ess_timer_poll(smc) ; #endif #endif #ifdef SBA sba_timer_poll(smc) ; #endif smt_srf_event(smc,0,0,0) ; #endif /* no SLIM_SMT */ time = smt_get_time() ; if (time - smc->sm.smt_last_lem >= TICKS_PER_SECOND*8) { /* * Use 8 sec. for the time intervall, it simplifies the * LER estimation. */ struct fddi_mib_m *mib ; u_long upper ; u_long lower ; int cond ; int port; struct s_phy *phy ; /* * calculate LEM bit error rate */ sm_lem_evaluate(smc) ; smc->sm.smt_last_lem = time ; /* * check conditions */ #ifndef SLIM_SMT mac_update_counter(smc) ; mib = smc->mib.m ; upper = (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) + (mib->fddiMACError_Ct - mib->fddiMACOld_Error_Ct) ; lower = (mib->fddiMACFrame_Ct - mib->fddiMACOld_Frame_Ct) + (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) ; mib->fddiMACFrameErrorRatio = div_ratio(upper,lower) ; cond = ((!mib->fddiMACFrameErrorThreshold && mib->fddiMACError_Ct != mib->fddiMACOld_Error_Ct) || (mib->fddiMACFrameErrorRatio > mib->fddiMACFrameErrorThreshold)) ; if (cond != mib->fddiMACFrameErrorFlag) smt_srf_event(smc,SMT_COND_MAC_FRAME_ERROR, INDEX_MAC,cond) ; upper = (mib->fddiMACNotCopied_Ct - mib->fddiMACOld_NotCopied_Ct) ; lower = upper + (mib->fddiMACCopied_Ct - mib->fddiMACOld_Copied_Ct) ; mib->fddiMACNotCopiedRatio = div_ratio(upper,lower) ; cond = ((!mib->fddiMACNotCopiedThreshold && mib->fddiMACNotCopied_Ct != mib->fddiMACOld_NotCopied_Ct)|| (mib->fddiMACNotCopiedRatio > mib->fddiMACNotCopiedThreshold)) ; if (cond != mib->fddiMACNotCopiedFlag) smt_srf_event(smc,SMT_COND_MAC_NOT_COPIED, INDEX_MAC,cond) ; /* * set old values */ mib->fddiMACOld_Frame_Ct = mib->fddiMACFrame_Ct ; mib->fddiMACOld_Copied_Ct = mib->fddiMACCopied_Ct ; mib->fddiMACOld_Error_Ct = mib->fddiMACError_Ct ; mib->fddiMACOld_Lost_Ct = mib->fddiMACLost_Ct ; mib->fddiMACOld_NotCopied_Ct = mib->fddiMACNotCopied_Ct ; /* * Check port EBError Condition */ for (port = 0; port < NUMPHYS; port ++) { phy = &smc->y[port] ; if (!phy->mib->fddiPORTHardwarePresent) { continue; } cond = (phy->mib->fddiPORTEBError_Ct - phy->mib->fddiPORTOldEBError_Ct > 5) ; /* If ratio is more than 5 in 8 seconds * Set the condition. */ smt_srf_event(smc,SMT_COND_PORT_EB_ERROR, (int) (INDEX_PORT+ phy->np) ,cond) ; /* * set old values */ phy->mib->fddiPORTOldEBError_Ct = phy->mib->fddiPORTEBError_Ct ; } #endif /* no SLIM_SMT */ } #ifndef SLIM_SMT if (time - smc->sm.smt_last_notify >= (u_long) (smc->mib.fddiSMTTT_Notify * TICKS_PER_SECOND) ) { /* * we can either send an announcement or a request * a request will trigger a reply so that we can update * our dna * note: same tid must be used until reply is received */ if (!smc->sm.pend[SMT_TID_NIF]) smc->sm.pend[SMT_TID_NIF] = smt_get_tid(smc) ; smt_send_nif(smc,&fddi_broadcast, FC_SMT_NSA, smc->sm.pend[SMT_TID_NIF], SMT_REQUEST,0) ; smc->sm.smt_last_notify = time ; } /* * check timer */ if (smc->sm.smt_tvu && time - smc->sm.smt_tvu > 228*TICKS_PER_SECOND) { DB_SMT("SMT : UNA expired\n",0,0) ; smc->sm.smt_tvu = 0 ; if (!is_equal(&smc->mib.m[MAC0].fddiMACUpstreamNbr, &SMT_Unknown)){ /* Do not update unknown address */ smc->mib.m[MAC0].fddiMACOldUpstreamNbr= smc->mib.m[MAC0].fddiMACUpstreamNbr ; } smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACUNDA_Flag = FALSE ; /* * Make sure the fddiMACUNDA_Flag = FALSE is * included in the SRF so we don't generate * a separate SRF for the deassertion of this * condition */ update_dac(smc,0) ; smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC,0) ; } if (smc->sm.smt_tvd && time - smc->sm.smt_tvd > 228*TICKS_PER_SECOND) { DB_SMT("SMT : DNA expired\n",0,0) ; smc->sm.smt_tvd = 0 ; if (!is_equal(&smc->mib.m[MAC0].fddiMACDownstreamNbr, &SMT_Unknown)){ /* Do not update unknown address */ smc->mib.m[MAC0].fddiMACOldDownstreamNbr= smc->mib.m[MAC0].fddiMACDownstreamNbr ; } smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ; smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC,0) ; } #endif /* no SLIM_SMT */ #ifndef SMT_REAL_TOKEN_CT /* * Token counter emulation section. If hardware supports the token * count, the token counter will be updated in mac_update_counter. */ for (i = MAC0; i < NUMMACS; i++ ){ if (time - smc->sm.last_tok_time[i] > 2*TICKS_PER_SECOND ){ smt_emulate_token_ct( smc, i ); } } #endif smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L, EV_TOKEN(EVENT_SMT,SM_TIMER)) ; }