static void smt_send_ecf_request(struct s_smc *smc, struct fddi_addr *dest, int len) { smc->sm.pend[SMT_TID_ECF] = smt_get_tid(smc) ; smt_send_ecf(smc,dest, FC_SMT_INFO, smc->sm.pend[SMT_TID_ECF], SMT_REQUEST,len) ; }
static void smt_echo_test(struct s_smc *smc, int dna) { u_long tid ; smc->sm.pend[dna ? SMT_TID_ECF_DNA : SMT_TID_ECF_UNA] = tid = smt_get_tid(smc) ; smt_send_ecf(smc, dna ? &smc->mib.m[MAC0].fddiMACDownstreamNbr : &smc->mib.m[MAC0].fddiMACUpstreamNbr, FC_SMT_INFO,tid, SMT_REQUEST, (SMT_TEST_ECHO_LEN & ~3)-8) ; }
static void ess_send_alc_req(struct s_smc *smc) { struct smt_sba_alc_req *req ; SMbuf *mb ; if (!smc->mib.fddiESSPayload) { smc->mib.fddiESSOverhead = 0 ; } else { if (!smc->mib.fddiESSOverhead) smc->mib.fddiESSOverhead = DEFAULT_OV ; } if (smc->mib.fddiESSOverhead == smc->mib.a[PATH0].fddiPATHSbaOverhead && smc->mib.fddiESSPayload == smc->mib.a[PATH0].fddiPATHSbaPayload){ smc->ess.raf_act_timer_poll = FALSE ; smc->ess.timer_count = 7 ; return ; } if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST, sizeof(struct smt_sba_alc_req)))) return ; req = smtod(mb,struct smt_sba_alc_req *) ; req->smt.smt_tid = smc->ess.alloc_trans_id = smt_get_tid(smc) ; req->smt.smt_dest = smt_sba_da ; req->s_type.para.p_type = SMT_P0015 ; req->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ; req->s_type.res_type = SYNC_BW ; req->cmd.para.p_type = SMT_P0016 ; req->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ; req->cmd.sba_cmd = REQUEST_ALLOCATION ; req->path.para.p_type = SMT_P320B ; req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ; req->path.mib_index = SBAPATHINDEX ; req->path.path_pad = 0; req->path.path_index = PRIMARY_RING ; req->pl_req.para.p_type = SMT_P0017 ; req->pl_req.para.p_len = sizeof(struct smt_p_0017) - PARA_LEN ; req->pl_req.sba_pl_req = smc->mib.fddiESSPayload - smc->mib.a[PATH0].fddiPATHSbaPayload ; req->ov_req.para.p_type = SMT_P0018 ; req->ov_req.para.p_len = sizeof(struct smt_p_0018) - PARA_LEN ; req->ov_req.sba_ov_req = smc->mib.fddiESSOverhead - smc->mib.a[PATH0].fddiPATHSbaOverhead ; req->payload.para.p_type = SMT_P320F ; req->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ; req->payload.mib_index = SBAPATHINDEX ; req->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ; req->overhead.para.p_type = SMT_P3210 ; req->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ; req->overhead.mib_index = SBAPATHINDEX ; req->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ; req->a_addr.para.p_type = SMT_P0019 ; req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ; req->a_addr.sba_pad = 0; req->a_addr.alloc_addr = null_addr ; req->cat.para.p_type = SMT_P001A ; req->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ; req->cat.category = smc->mib.fddiESSCategory ; req->tneg.para.p_type = SMT_P001B ; req->tneg.para.p_len = sizeof(struct smt_p_001b) - PARA_LEN ; req->tneg.max_t_neg = smc->mib.fddiESSMaxTNeg ; req->segm.para.p_type = SMT_P001C ; req->segm.para.p_len = sizeof(struct smt_p_001c) - PARA_LEN ; req->segm.min_seg_siz = smc->mib.fddiESSMinSegmentSize ; dump_smt(smc,(struct smt_header *)req,"RAF") ; ess_send_frame(smc,mb) ; }
static void ess_send_alc_req(struct s_smc *smc) { struct smt_sba_alc_req *req ; SMbuf *mb ; /* * send never allocation request where the requested payload and * overhead is zero or deallocate bandwidth when no bandwidth is * parsed */ if (!smc->mib.fddiESSPayload) { smc->mib.fddiESSOverhead = 0 ; } else { if (!smc->mib.fddiESSOverhead) smc->mib.fddiESSOverhead = DEFAULT_OV ; } if (smc->mib.fddiESSOverhead == smc->mib.a[PATH0].fddiPATHSbaOverhead && smc->mib.fddiESSPayload == smc->mib.a[PATH0].fddiPATHSbaPayload){ smc->ess.raf_act_timer_poll = FALSE ; smc->ess.timer_count = 7 ; /* next RAF alc req after 3 s */ return ; } /* * get and initialize the response frame */ if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST, sizeof(struct smt_sba_alc_req)))) return ; req = smtod(mb,struct smt_sba_alc_req *) ; req->smt.smt_tid = smc->ess.alloc_trans_id = smt_get_tid(smc) ; req->smt.smt_dest = smt_sba_da ; /* set P15 */ req->s_type.para.p_type = SMT_P0015 ; req->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ; req->s_type.res_type = SYNC_BW ; /* set P16 */ req->cmd.para.p_type = SMT_P0016 ; req->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ; req->cmd.sba_cmd = REQUEST_ALLOCATION ; /* * set the parameter type and parameter length of all used * parameters */ /* set P320B */ req->path.para.p_type = SMT_P320B ; req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ; req->path.mib_index = SBAPATHINDEX ; req->path.path_pad = 0; req->path.path_index = PRIMARY_RING ; /* set P0017 */ req->pl_req.para.p_type = SMT_P0017 ; req->pl_req.para.p_len = sizeof(struct smt_p_0017) - PARA_LEN ; req->pl_req.sba_pl_req = smc->mib.fddiESSPayload - smc->mib.a[PATH0].fddiPATHSbaPayload ; /* set P0018 */ req->ov_req.para.p_type = SMT_P0018 ; req->ov_req.para.p_len = sizeof(struct smt_p_0018) - PARA_LEN ; req->ov_req.sba_ov_req = smc->mib.fddiESSOverhead - smc->mib.a[PATH0].fddiPATHSbaOverhead ; /* set P320F */ req->payload.para.p_type = SMT_P320F ; req->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ; req->payload.mib_index = SBAPATHINDEX ; req->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ; /* set P3210 */ req->overhead.para.p_type = SMT_P3210 ; req->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ; req->overhead.mib_index = SBAPATHINDEX ; req->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ; /* set P19 */ req->a_addr.para.p_type = SMT_P0019 ; req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ; req->a_addr.sba_pad = 0; req->a_addr.alloc_addr = null_addr ; /* set P1A */ req->cat.para.p_type = SMT_P001A ; req->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ; req->cat.category = smc->mib.fddiESSCategory ; /* set P1B */ req->tneg.para.p_type = SMT_P001B ; req->tneg.para.p_len = sizeof(struct smt_p_001b) - PARA_LEN ; req->tneg.max_t_neg = smc->mib.fddiESSMaxTNeg ; /* set P1C */ req->segm.para.p_type = SMT_P001C ; req->segm.para.p_len = sizeof(struct smt_p_001c) - PARA_LEN ; req->segm.min_seg_siz = smc->mib.fddiESSMinSegmentSize ; dump_smt(smc,(struct smt_header *)req,"RAF") ; ess_send_frame(smc,mb) ; }
static void smt_send_nif_request(struct s_smc *smc, struct fddi_addr *dest) { smc->sm.pend[SMT_TID_NIF_TEST] = smt_get_tid(smc) ; smt_send_nif(smc,dest, FC_SMT_INFO, smc->sm.pend[SMT_TID_NIF_TEST], SMT_REQUEST,0) ; }
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)) ; }