📄 pcmplc.c
字号:
phy->t_val[5] = 1 ; } break ; case 5: break ; case 6: /* we do NOT have a MAC for LCT */ phy->t_val[6] = 0 ; break ; case 7: phy->cf_loop = FALSE ; lem_check_lct(smc,phy) ; if (phy->pc_lem_fail) { DB_PCMN(1,"PCM %c : E104 LCT failed\n", phy->phy_name,0) ; phy->t_val[7] = 1 ; } else phy->t_val[7] = 0 ; break ; case 8: phy->t_val[8] = 0 ; /* Don't request MAC loopback */ break ; case 9: phy->cf_loop = 0 ; if ((mib->fddiPORTPC_Withhold != PC_WH_NONE) || ((smc->s.sas == SMT_DAS) && (phy->wc_flag))) { queue_event(smc,EVENT_PCM+np,PC_START) ; break ; } phy->t_val[9] = FALSE ; switch (smc->s.sas) { case SMT_DAS : /* * MAC intended on output */ if (phy->pc_mode == PM_TREE) { if ((np == PB) || ((np == PA) && (smc->y[PB].mib->fddiPORTConnectState != PCM_ACTIVE))) phy->t_val[9] = TRUE ; } else { if (np == PB) phy->t_val[9] = TRUE ; } break ; case SMT_SAS : if (np == PS) phy->t_val[9] = TRUE ; break ;#ifdef CONCENTRATOR case SMT_NAC : /* * MAC intended on output */ if (np == PB) phy->t_val[9] = TRUE ; break ;#endif } mib->fddiPORTMacIndicated.T_val = phy->t_val[9] ; break ; } DB_PCMN(1,"SIG snd %x %x: \n", bit,phy->t_val[bit] ) ;}/* * return status twisted (called by SMT) */int pcm_status_twisted(struct s_smc *smc){ int twist = 0 ; if (smc->s.sas != SMT_DAS) return(0) ; if (smc->y[PA].twisted && (smc->y[PA].mib->fddiPORTPCMState == PC8_ACTIVE)) twist |= 1 ; if (smc->y[PB].twisted && (smc->y[PB].mib->fddiPORTPCMState == PC8_ACTIVE)) twist |= 2 ; return(twist) ;}/* * return status (called by SMT) * type * state * remote phy type * remote mac yes/no */void pcm_status_state(struct s_smc *smc, int np, int *type, int *state, int *remote, int *mac){ struct s_phy *phy = &smc->y[np] ; struct fddi_mib_p *mib ; mib = phy->mib ; /* remote PHY type and MAC - set only if active */ *mac = 0 ; *type = mib->fddiPORTMy_Type ; /* our PHY type */ *state = mib->fddiPORTConnectState ; *remote = mib->fddiPORTNeighborType ; switch(mib->fddiPORTPCMState) { case PC8_ACTIVE : *mac = mib->fddiPORTMacIndicated.R_val ; break ; }}/* * return rooted station status (called by SMT) */int pcm_rooted_station(struct s_smc *smc){ int n ; for (n = 0 ; n < NUMPHYS ; n++) { if (smc->y[n].mib->fddiPORTPCMState == PC8_ACTIVE && smc->y[n].mib->fddiPORTNeighborType == TM) return(0) ; } return(1) ;}/* * Interrupt actions for PLC & PCM events */void plc_irq(struct s_smc *smc, int np, unsigned int cmd)/* int np; PHY index */{ struct s_phy *phy = &smc->y[np] ; struct s_plc *plc = &phy->plc ; int n ;#ifdef SUPERNET_3 int corr_mask ;#endif /* SUPERNET_3 */ int i ; if (np >= smc->s.numphys) { plc->soft_err++ ; return ; } if (cmd & PL_EBUF_ERR) { /* elastic buff. det. over-|underflow*/ /* * Check whether the SRF Condition occurred. */ if (!plc->ebuf_cont && phy->mib->fddiPORTPCMState == PC8_ACTIVE){ /* * This is the real Elasticity Error. * More than one in a row are treated as a * single one. * Only count this in the active state. */ phy->mib->fddiPORTEBError_Ct ++ ; } plc->ebuf_err++ ; if (plc->ebuf_cont <= 1000) { /* * Prevent counter from being wrapped after * hanging years in that interrupt. */ plc->ebuf_cont++ ; /* Ebuf continous error */ }#ifdef SUPERNET_3 if (plc->ebuf_cont == 1000 && ((inpw(PLC(np,PL_STATUS_A)) & PLC_REV_MASK) == PLC_REV_SN3)) { /* * This interrupt remeained high for at least * 1000 consecutive interrupt calls. * * This is caused by a hardware error of the * ORION part of the Supernet III chipset. * * Disable this bit from the mask. */ corr_mask = (plc_imsk_na & ~PL_EBUF_ERR) ; outpw(PLC(np,PL_INTR_MASK),corr_mask); /* * Disconnect from the ring. * Call the driver with the reset indication. */ queue_event(smc,EVENT_ECM,EC_DISCONNECT) ; /* * Make an error log entry. */ SMT_ERR_LOG(smc,SMT_E0136, SMT_E0136_MSG) ; /* * Indicate the Reset. */ drv_reset_indication(smc) ; }#endif /* SUPERNET_3 */ } else { /* Reset the continous error variable */ plc->ebuf_cont = 0 ; /* reset Ebuf continous error */ } if (cmd & PL_PHYINV) { /* physical layer invalid signal */ plc->phyinv++ ; } if (cmd & PL_VSYM_CTR) { /* violation symbol counter has incr.*/ plc->vsym_ctr++ ; } if (cmd & PL_MINI_CTR) { /* dep. on PLC_CNTRL_A's MINI_CTR_INT*/ plc->mini_ctr++ ; } if (cmd & PL_LE_CTR) { /* link error event counter */ int j ; /* * note: PL_LINK_ERR_CTR MUST be read to clear it */ j = inpw(PLC(np,PL_LE_THRESHOLD)) ; i = inpw(PLC(np,PL_LINK_ERR_CTR)) ; if (i < j) { /* wrapped around */ i += 256 ; } if (phy->lem.lem_on) { /* Note: Lem errors shall only be counted when * link is ACTIVE or LCT is active. */ phy->lem.lem_errors += i ; phy->mib->fddiPORTLem_Ct += i ; } } if (cmd & PL_TPC_EXPIRED) { /* TPC timer reached zero */ if (plc->p_state == PS_LCT) { /* * end of LCT */ ; } plc->tpc_exp++ ; } if (cmd & PL_LS_MATCH) { /* LS == LS in PLC_CNTRL_B's MATCH_LS*/ switch (inpw(PLC(np,PL_CNTRL_B)) & PL_MATCH_LS) { case PL_I_IDLE : phy->curr_ls = PC_ILS ; break ; case PL_I_HALT : phy->curr_ls = PC_HLS ; break ; case PL_I_MASTR : phy->curr_ls = PC_MLS ; break ; case PL_I_QUIET : phy->curr_ls = PC_QLS ; break ; } } if (cmd & PL_PCM_BREAK) { /* PCM has entered the BREAK state */ int reason; reason = inpw(PLC(np,PL_STATUS_B)) & PL_BREAK_REASON ; switch (reason) { case PL_B_PCS : plc->b_pcs++ ; break ; case PL_B_TPC : plc->b_tpc++ ; break ; case PL_B_TNE : plc->b_tne++ ; break ; case PL_B_QLS : plc->b_qls++ ; break ; case PL_B_ILS : plc->b_ils++ ; break ; case PL_B_HLS : plc->b_hls++ ; break ; } /*jd 05-Aug-1999 changed: Bug #10419 */ DB_PCMN(1,"PLC %d: MDcF = %x\n", np, smc->e.DisconnectFlag); if (smc->e.DisconnectFlag == FALSE) { DB_PCMN(1,"PLC %d: restart (reason %x)\n", np, reason); queue_event(smc,EVENT_PCM+np,PC_START) ; } else { DB_PCMN(1,"PLC %d: NO!! restart (reason %x)\n", np, reason); } return ; } /* * If both CODE & ENABLE are set ignore enable */ if (cmd & PL_PCM_CODE) { /* receive last sign.-bit | LCT complete */ queue_event(smc,EVENT_PCM+np,PC_SIGNAL) ; n = inpw(PLC(np,PL_RCV_VECTOR)) ; for (i = 0 ; i < plc->p_bits ; i++) { phy->r_val[plc->p_start+i] = n & 1 ; n >>= 1 ; } } else if (cmd & PL_PCM_ENABLED) { /* asserted SC_JOIN, scrub.completed*/ queue_event(smc,EVENT_PCM+np,PC_JOIN) ; } if (cmd & PL_TRACE_PROP) { /* MLS while PC8_ACTIV || PC2_TRACE */ /*PC22b*/ if (!phy->tr_flag) { DB_PCMN(1,"PCM : irq TRACE_PROP %d %d\n", np,smc->mib.fddiSMTECMState) ; phy->tr_flag = TRUE ; smc->e.trace_prop |= ENTITY_BIT(ENTITY_PHY(np)) ; queue_event(smc,EVENT_ECM,EC_TRACE_PROP) ; } } /* * filter PLC glitch ??? * QLS || HLS only while in PC2_TRACE state */ if ((cmd & PL_SELF_TEST) && (phy->mib->fddiPORTPCMState == PC2_TRACE)) { /*PC22a*/ if (smc->e.path_test == PT_PASSED) { DB_PCMN(1,"PCM : state = %s %d\n", get_pcmstate(smc,np), phy->mib->fddiPORTPCMState) ; smc->e.path_test = PT_PENDING ; queue_event(smc,EVENT_ECM,EC_PATH_TEST) ; } } if (cmd & PL_TNE_EXPIRED) { /* TNE: length of noise events */ /* break_required (TNE > NS_Max) */ if (phy->mib->fddiPORTPCMState == PC8_ACTIVE) { if (!phy->tr_flag) { DB_PCMN(1,"PCM %c : PC81 %s\n",phy->phy_name,"NSE"); queue_event(smc,EVENT_PCM+np,PC_START) ; return ; } } }#if 0 if (cmd & PL_NP_ERR) { /* NP has requested to r/w an inv reg*/ /* * It's a bug by AMD */ plc->np_err++ ; } /* pin inactiv (GND) */ if (cmd & PL_PARITY_ERR) { /* p. error dedected on TX9-0 inp */ plc->parity_err++ ; } if (cmd & PL_LSDO) { /* carrier detected */ ; }#endif}void pcm_set_lct_short(struct s_smc *smc, int n){ if (n <= 0 || n > 1000) return ; smc->s.lct_short = n ;}#ifdef DEBUG/* * fill state struct */void pcm_get_state(struct s_smc *smc, struct smt_state *state){ struct s_phy *phy ; struct pcm_state *pcs ; int i ; int ii ; short rbits ; short tbits ; struct fddi_mib_p *mib ; for (i = 0, phy = smc->y, pcs = state->pcm_state ; i < NUMPHYS ; i++ , phy++, pcs++ ) { mib = phy->mib ; pcs->pcm_type = (u_char) mib->fddiPORTMy_Type ; pcs->pcm_state = (u_char) mib->fddiPORTPCMState ; pcs->pcm_mode = phy->pc_mode ; pcs->pcm_neighbor = (u_char) mib->fddiPORTNeighborType ; pcs->pcm_bsf = mib->fddiPORTBS_Flag ; pcs->pcm_lsf = phy->ls_flag ; pcs->pcm_lct_fail = (u_char) mib->fddiPORTLCTFail_Ct ; pcs->pcm_ls_rx = LS2MIB(sm_pm_get_ls(smc,i)) ; for (ii = 0, rbits = tbits = 0 ; ii < NUMBITS ; ii++) { rbits <<= 1 ; tbits <<= 1 ; if (phy->r_val[NUMBITS-1-ii]) rbits |= 1 ; if (phy->t_val[NUMBITS-1-ii]) tbits |= 1 ; } pcs->pcm_r_val = rbits ; pcs->pcm_t_val = tbits ; }}int get_pcm_state(struct s_smc *smc, int np){ int pcs ; SK_UNUSED(smc) ; switch (inpw(PLC(np,PL_STATUS_B)) & PL_PCM_STATE) { case PL_PC0 : pcs = PC_STOP ; break ; case PL_PC1 : pcs = PC_START ; break ; case PL_PC2 : pcs = PC_TRACE ; break ; case PL_PC3 : pcs = PC_SIGNAL ; break ; case PL_PC4 : pcs = PC_SIGNAL ; break ; case PL_PC5 : pcs = PC_SIGNAL ; break ; case PL_PC6 : pcs = PC_JOIN ; break ; case PL_PC7 : pcs = PC_JOIN ; break ; case PL_PC8 : pcs = PC_ENABLE ; break ; case PL_PC9 : pcs = PC_MAINT ; break ; default : pcs = PC_DISABLE ; break ; } return(pcs) ;}char *get_linestate(struct s_smc *smc, int np){ char *ls = "" ; SK_UNUSED(smc) ; switch (inpw(PLC(np,PL_STATUS_A)) & PL_LINE_ST) { case PL_L_NLS : ls = "NOISE" ; break ; case PL_L_ALS : ls = "ACTIV" ; break ; case PL_L_UND : ls = "UNDEF" ; break ; case PL_L_ILS4: ls = "ILS 4" ; break ; case PL_L_QLS : ls = "QLS" ; break ; case PL_L_MLS : ls = "MLS" ; break ; case PL_L_HLS : ls = "HLS" ; break ; case PL_L_ILS16:ls = "ILS16" ; break ;#ifdef lint default: ls = "unknown" ; break ;#endif } return(ls) ;}char *get_pcmstate(struct s_smc *smc, int np){ char *pcs ; SK_UNUSED(smc) ; switch (inpw(PLC(np,PL_STATUS_B)) & PL_PCM_STATE) { case PL_PC0 : pcs = "OFF" ; break ; case PL_PC1 : pcs = "BREAK" ; break ; case PL_PC2 : pcs = "TRACE" ; break ; case PL_PC3 : pcs = "CONNECT"; break ; case PL_PC4 : pcs = "NEXT" ; break ; case PL_PC5 : pcs = "SIGNAL" ; break ; case PL_PC6 : pcs = "JOIN" ; break ; case PL_PC7 : pcs = "VERIFY" ; break ; case PL_PC8 : pcs = "ACTIV" ; break ; case PL_PC9 : pcs = "MAINT" ; break ; default : pcs = "UNKNOWN" ; break ; } return(pcs) ;}void list_phy(struct s_smc *smc){ struct s_plc *plc ; int np ; for (np = 0 ; np < NUMPHYS ; np++) { plc = &smc->y[np].plc ; printf("PHY %d:\tERRORS\t\t\tBREAK_REASONS\t\tSTATES:\n",np) ; printf("\tsoft_error: %ld \t\tPC_Start : %ld\n", plc->soft_err,plc->b_pcs); printf("\tparity_err: %ld \t\tTPC exp. : %ld\t\tLine: %s\n", plc->parity_err,plc->b_tpc,get_linestate(smc,np)) ; printf("\tebuf_error: %ld \t\tTNE exp. : %ld\n", plc->ebuf_err,plc->b_tne) ; printf("\tphyinvalid: %ld \t\tQLS det. : %ld\t\tPCM : %s\n", plc->phyinv,plc->b_qls,get_pcmstate(smc,np)) ; printf("\tviosym_ctr: %ld \t\tILS det. : %ld\n", plc->vsym_ctr,plc->b_ils) ; printf("\tmingap_ctr: %ld \t\tHLS det. : %ld\n", plc->mini_ctr,plc->b_hls) ; printf("\tnodepr_err: %ld\n",plc->np_err) ; printf("\tTPC_exp : %ld\n",plc->tpc_exp) ; printf("\tLEM_err : %ld\n",smc->y[np].lem.lem_errors) ; }}#ifdef CONCENTRATORvoid pcm_lem_dump(struct s_smc *smc){ int i ; struct s_phy *phy ; struct fddi_mib_p *mib ; char *entostring() ; printf("PHY errors BER\n") ; printf("----------------------\n") ; for (i = 0,phy = smc->y ; i < NUMPHYS ; i++,phy++) { if (!plc_is_installed(smc,i)) continue ; mib = phy->mib ; printf("%s\t%ld\t10E-%d\n", entostring(smc,ENTITY_PHY(i)), mib->fddiPORTLem_Ct, mib->fddiPORTLer_Estimate) ; }}#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -