⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcmplc.c

📁 h内核
💻 C
📖 第 1 页 / 共 4 页
字号:
		plc_go_state(smc,np,PL_PCM_STOP) ;		mib->fddiPORTConnectState = PCM_DISABLED ;		SETMASK(PLC(np,PL_CNTRL_B),PL_MAINT,PL_MAINT) ;		sm_ph_linestate(smc,np,(int) MIB2LS(mib->fddiPORTMaint_LS)) ;		outpw(PLC(np,PL_CNTRL_A),PL_SC_BYPASS) ;		ACTIONS_DONE() ;		break ;	case PC9_MAINT :		DB_PCMN(1,"PCM %c : MAINT\n",phy->phy_name,0) ;		/*PC90*/		if (cmd == PC_ENABLE) {			GO_STATE(PC0_OFF) ;			break ;		}		break ;	default:		SMT_PANIC(smc,SMT_E0118, SMT_E0118_MSG) ;		break ;	}}/* * force line state on a PHY output	(only in MAINT state) */static void sm_ph_linestate(struct s_smc *smc, int phy, int ls){	int	cntrl ;	SK_UNUSED(smc) ;	cntrl = (inpw(PLC(phy,PL_CNTRL_B)) & ~PL_MAINT_LS) |						PL_PCM_STOP | PL_MAINT ;	switch(ls) {	case PC_QLS: 		/* Force Quiet */		cntrl |= PL_M_QUI0 ;		break ;	case PC_MLS: 		/* Force Master */		cntrl |= PL_M_MASTR ;		break ;	case PC_HLS: 		/* Force Halt */		cntrl |= PL_M_HALT ;		break ;	default :	case PC_ILS: 		/* Force Idle */		cntrl |= PL_M_IDLE ;		break ;	case PC_LS_PDR: 	/* Enable repeat filter */		cntrl |= PL_M_TPDR ;		break ;	}	outpw(PLC(phy,PL_CNTRL_B),cntrl) ;}static void reset_lem_struct(struct s_phy *phy){	struct lem_counter *lem = &phy->lem ;	phy->mib->fddiPORTLer_Estimate = 15 ;	lem->lem_float_ber = 15 * 100 ;}/* * link error monitor */static void lem_evaluate(struct s_smc *smc, struct s_phy *phy){	int ber ;	u_long errors ;	struct lem_counter *lem = &phy->lem ;	struct fddi_mib_p	*mib ;	int			cond ;	mib = phy->mib ;	if (!lem->lem_on)		return ;	errors = inpw(PLC(((int) phy->np),PL_LINK_ERR_CTR)) ;	lem->lem_errors += errors ;	mib->fddiPORTLem_Ct += errors ;	errors = lem->lem_errors ;	/*	 * calculation is called on a intervall of 8 seconds	 *	-> this means, that one error in 8 sec. is one of 8*125*10E6	 *	the same as BER = 10E-9	 * Please note:	 *	-> 9 errors in 8 seconds mean:	 *	   BER = 9 * 10E-9  and this is	 *	    < 10E-8, so the limit of 10E-8 is not reached!	 */		if (!errors)		ber = 15 ;	else	if (errors <= 9)	ber = 9 ;	else	if (errors <= 99)	ber = 8 ;	else	if (errors <= 999)	ber = 7 ;	else	if (errors <= 9999)	ber = 6 ;	else	if (errors <= 99999)	ber = 5 ;	else	if (errors <= 999999)	ber = 4 ;	else	if (errors <= 9999999)	ber = 3 ;	else	if (errors <= 99999999)	ber = 2 ;	else	if (errors <= 999999999) ber = 1 ;	else				ber = 0 ;	/*	 * weighted average	 */	ber *= 100 ;	lem->lem_float_ber = lem->lem_float_ber * 7 + ber * 3 ;	lem->lem_float_ber /= 10 ;	mib->fddiPORTLer_Estimate = lem->lem_float_ber / 100 ;	if (mib->fddiPORTLer_Estimate < 4) {		mib->fddiPORTLer_Estimate = 4 ;	}	if (lem->lem_errors) {		DB_PCMN(1,"LEM %c :\n",phy->np == PB? 'B' : 'A',0) ;		DB_PCMN(1,"errors      : %ld\n",lem->lem_errors,0) ;		DB_PCMN(1,"sum_errors  : %ld\n",mib->fddiPORTLem_Ct,0) ;		DB_PCMN(1,"current BER : 10E-%d\n",ber/100,0) ;		DB_PCMN(1,"float BER   : 10E-(%d/100)\n",lem->lem_float_ber,0) ;		DB_PCMN(1,"avg. BER    : 10E-%d\n",			mib->fddiPORTLer_Estimate,0) ;	}	lem->lem_errors = 0L ;#ifndef	SLIM_SMT	cond = (mib->fddiPORTLer_Estimate <= mib->fddiPORTLer_Alarm) ?		TRUE : FALSE ;#ifdef	SMT_EXT_CUTOFF	smt_ler_alarm_check(smc,phy,cond) ;#endif	/* nSMT_EXT_CUTOFF */	if (cond != mib->fddiPORTLerFlag) {		smt_srf_event(smc,SMT_COND_PORT_LER,			(int) (INDEX_PORT+ phy->np) ,cond) ;	}#endif	if (	mib->fddiPORTLer_Estimate <= mib->fddiPORTLer_Cutoff) {		phy->pc_lem_fail = TRUE ;		/* flag */		mib->fddiPORTLem_Reject_Ct++ ;		/*		 * "forgive 10e-2" if we cutoff so we can come		 * up again ..		 */		lem->lem_float_ber += 2*100 ;		/*PC81b*/#ifdef	CONCENTRATOR		DB_PCMN(1,"PCM: LER cutoff on port %d cutoff %d\n",			phy->np, mib->fddiPORTLer_Cutoff) ;#endif#ifdef	SMT_EXT_CUTOFF		smt_port_off_event(smc,phy->np);#else	/* nSMT_EXT_CUTOFF */		queue_event(smc,(int)(EVENT_PCM+phy->np),PC_START) ;#endif	/* nSMT_EXT_CUTOFF */	}}/* * called by SMT to calculate LEM bit error rate */void sm_lem_evaluate(struct s_smc *smc){	int np ;	for (np = 0 ; np < NUMPHYS ; np++)		lem_evaluate(smc,&smc->y[np]) ;}static void lem_check_lct(struct s_smc *smc, struct s_phy *phy){	struct lem_counter	*lem = &phy->lem ;	struct fddi_mib_p	*mib ;	int errors ;	mib = phy->mib ;	phy->pc_lem_fail = FALSE ;		/* flag */	errors = inpw(PLC(((int)phy->np),PL_LINK_ERR_CTR)) ;	lem->lem_errors += errors ;	mib->fddiPORTLem_Ct += errors ;	if (lem->lem_errors) {		switch(phy->lc_test) {		case LC_SHORT:			if (lem->lem_errors >= smc->s.lct_short)				phy->pc_lem_fail = TRUE ;			break ;		case LC_MEDIUM:			if (lem->lem_errors >= smc->s.lct_medium)				phy->pc_lem_fail = TRUE ;			break ;		case LC_LONG:			if (lem->lem_errors >= smc->s.lct_long)				phy->pc_lem_fail = TRUE ;			break ;		case LC_EXTENDED:			if (lem->lem_errors >= smc->s.lct_extended)				phy->pc_lem_fail = TRUE ;			break ;		}		DB_PCMN(1," >>errors : %d\n",lem->lem_errors,0) ;	}	if (phy->pc_lem_fail) {		mib->fddiPORTLCTFail_Ct++ ;		mib->fddiPORTLem_Reject_Ct++ ;	}	else		mib->fddiPORTLCTFail_Ct = 0 ;}/* * LEM functions */static void sm_ph_lem_start(struct s_smc *smc, int np, int threshold){	struct lem_counter *lem = &smc->y[np].lem ;	lem->lem_on = 1 ;	lem->lem_errors = 0L ;	/* Do NOT reset mib->fddiPORTLer_Estimate here. It is called too	 * often.	 */	outpw(PLC(np,PL_LE_THRESHOLD),threshold) ;	(void)inpw(PLC(np,PL_LINK_ERR_CTR)) ;	/* clear error counter */	/* enable LE INT */	SETMASK(PLC(np,PL_INTR_MASK),PL_LE_CTR,PL_LE_CTR) ;}static void sm_ph_lem_stop(struct s_smc *smc, int np){	struct lem_counter *lem = &smc->y[np].lem ;	lem->lem_on = 0 ;	CLEAR(PLC(np,PL_INTR_MASK),PL_LE_CTR) ;}/* ARGSUSED */void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off)/* int on_off;	en- or disable ident. ls */{	SK_UNUSED(smc) ;	phy = phy ; on_off = on_off ;}/* * PCM pseudo code * receive actions are called AFTER the bit n is received, * i.e. if pc_rcode_actions(5) is called, bit 6 is the next bit to be received *//* * PCM pseudo code 5.1 .. 6.1 */static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy){	struct fddi_mib_p	*mib ;	mib = phy->mib ;	DB_PCMN(1,"SIG rec %x %x: \n", bit,phy->r_val[bit] ) ;	bit++ ;	switch(bit) {	case 0:	case 1:	case 2:		break ;	case 3 :		if (phy->r_val[1] == 0 && phy->r_val[2] == 0)			mib->fddiPORTNeighborType = TA ;		else if (phy->r_val[1] == 0 && phy->r_val[2] == 1)			mib->fddiPORTNeighborType = TB ;		else if (phy->r_val[1] == 1 && phy->r_val[2] == 0)			mib->fddiPORTNeighborType = TS ;		else if (phy->r_val[1] == 1 && phy->r_val[2] == 1)			mib->fddiPORTNeighborType = TM ;		break ;	case 4:		if (mib->fddiPORTMy_Type == TM &&			mib->fddiPORTNeighborType == TM) {			DB_PCMN(1,"PCM %c : E100 withhold M-M\n",				phy->phy_name,0) ;			mib->fddiPORTPC_Withhold = PC_WH_M_M ;			RS_SET(smc,RS_EVENT) ;		}		else if (phy->t_val[3] || phy->r_val[3]) {			mib->fddiPORTPC_Withhold = PC_WH_NONE ;			if (mib->fddiPORTMy_Type == TM ||			    mib->fddiPORTNeighborType == TM)				phy->pc_mode = PM_TREE ;			else				phy->pc_mode = PM_PEER ;			/* reevaluate the selection criteria (wc_flag) */			all_selection_criteria (smc);			if (phy->wc_flag) {				mib->fddiPORTPC_Withhold = PC_WH_PATH ;			}		}		else {			mib->fddiPORTPC_Withhold = PC_WH_OTHER ;			RS_SET(smc,RS_EVENT) ;			DB_PCMN(1,"PCM %c : E101 withhold other\n",				phy->phy_name,0) ;		}		phy->twisted = ((mib->fddiPORTMy_Type != TS) &&				(mib->fddiPORTMy_Type != TM) &&				(mib->fddiPORTNeighborType ==				mib->fddiPORTMy_Type)) ;		if (phy->twisted) {			DB_PCMN(1,"PCM %c : E102 !!! TWISTED !!!\n",				phy->phy_name,0) ;		}		break ;	case 5 :		break ;	case 6:		if (phy->t_val[4] || phy->r_val[4]) {			if ((phy->t_val[4] && phy->t_val[5]) ||			    (phy->r_val[4] && phy->r_val[5]) )				phy->lc_test = LC_EXTENDED ;			else				phy->lc_test = LC_LONG ;		}		else if (phy->t_val[5] || phy->r_val[5])			phy->lc_test = LC_MEDIUM ;		else			phy->lc_test = LC_SHORT ;		switch (phy->lc_test) {		case LC_SHORT :				/* 50ms */			outpw(PLC((int)phy->np,PL_LC_LENGTH), TP_LC_LENGTH ) ;			phy->t_next[7] = smc->s.pcm_lc_short ;			break ;		case LC_MEDIUM :			/* 500ms */			outpw(PLC((int)phy->np,PL_LC_LENGTH), TP_LC_LONGLN ) ;			phy->t_next[7] = smc->s.pcm_lc_medium ;			break ;		case LC_LONG :			SETMASK(PLC((int)phy->np,PL_CNTRL_B),PL_LONG,PL_LONG) ;			phy->t_next[7] = smc->s.pcm_lc_long ;			break ;		case LC_EXTENDED :			SETMASK(PLC((int)phy->np,PL_CNTRL_B),PL_LONG,PL_LONG) ;			phy->t_next[7] = smc->s.pcm_lc_extended ;			break ;		}		if (phy->t_next[7] > smc->s.pcm_lc_medium) {			start_pcm_timer0(smc,phy->t_next[7],PC_TIMEOUT_LCT,phy);		}		DB_PCMN(1,"LCT timer = %ld us\n", phy->t_next[7], 0) ;		phy->t_next[9] = smc->s.pcm_t_next_9 ;		break ;	case 7:		if (phy->t_val[6]) {			phy->cf_loop = TRUE ;		}		phy->td_flag = TRUE ;		break ;	case 8:		if (phy->t_val[7] || phy->r_val[7]) {			DB_PCMN(1,"PCM %c : E103 LCT fail %s\n",				phy->phy_name,phy->t_val[7]? "local":"remote") ;			queue_event(smc,(int)(EVENT_PCM+phy->np),PC_START) ;		}		break ;	case 9:		if (phy->t_val[8] || phy->r_val[8]) {			if (phy->t_val[8])				phy->cf_loop = TRUE ;			phy->td_flag = TRUE ;		}		break ;	case 10:		if (phy->r_val[9]) {			/* neighbor intends to have MAC on output */ ;			mib->fddiPORTMacIndicated.R_val = TRUE ;		}		else {			/* neighbor does not intend to have MAC on output */ ;			mib->fddiPORTMacIndicated.R_val = FALSE ;		}		break ;	}}/* * PCM pseudo code 5.1 .. 6.1 */static void pc_tcode_actions(struct s_smc *smc, const int bit, struct s_phy *phy){	int	np = phy->np ;	struct fddi_mib_p	*mib ;	mib = phy->mib ;	switch(bit) {	case 0:		phy->t_val[0] = 0 ;		/* no escape used */		break ;	case 1:		if (mib->fddiPORTMy_Type == TS || mib->fddiPORTMy_Type == TM)			phy->t_val[1] = 1 ;		else			phy->t_val[1] = 0 ;		break ;	case 2 :		if (mib->fddiPORTMy_Type == TB || mib->fddiPORTMy_Type == TM)			phy->t_val[2] = 1 ;		else			phy->t_val[2] = 0 ;		break ;	case 3:		{		int	type,ne ;		int	policy ;		type = mib->fddiPORTMy_Type ;		ne = mib->fddiPORTNeighborType ;		policy = smc->mib.fddiSMTConnectionPolicy ;		phy->t_val[3] = 1 ;	/* Accept connection */		switch (type) {		case TA :			if (				((policy & POLICY_AA) && ne == TA) ||				((policy & POLICY_AB) && ne == TB) ||				((policy & POLICY_AS) && ne == TS) ||				((policy & POLICY_AM) && ne == TM) )				phy->t_val[3] = 0 ;	/* Reject */			break ;		case TB :			if (				((policy & POLICY_BA) && ne == TA) ||				((policy & POLICY_BB) && ne == TB) ||				((policy & POLICY_BS) && ne == TS) ||				((policy & POLICY_BM) && ne == TM) )				phy->t_val[3] = 0 ;	/* Reject */			break ;		case TS :			if (				((policy & POLICY_SA) && ne == TA) ||				((policy & POLICY_SB) && ne == TB) ||				((policy & POLICY_SS) && ne == TS) ||				((policy & POLICY_SM) && ne == TM) )				phy->t_val[3] = 0 ;	/* Reject */			break ;		case TM :			if (	ne == TM ||				((policy & POLICY_MA) && ne == TA) ||				((policy & POLICY_MB) && ne == TB) ||				((policy & POLICY_MS) && ne == TS) ||				((policy & POLICY_MM) && ne == TM) )				phy->t_val[3] = 0 ;	/* Reject */			break ;		}#ifndef	SLIM_SMT		/*		 * detect undesirable connection attempt event		 */		if (	(type == TA && ne == TA ) ||			(type == TA && ne == TS ) ||			(type == TB && ne == TB ) ||			(type == TB && ne == TS ) ||			(type == TS && ne == TA ) ||			(type == TS && ne == TB ) ) {			smt_srf_event(smc,SMT_EVENT_PORT_CONNECTION,				(int) (INDEX_PORT+ phy->np) ,0) ;		}#endif		}		break ;	case 4:		if (mib->fddiPORTPC_Withhold == PC_WH_NONE) {			if (phy->pc_lem_fail) {				phy->t_val[4] = 1 ;	/* long */				phy->t_val[5] = 0 ;			}			else {				phy->t_val[4] = 0 ;				if (mib->fddiPORTLCTFail_Ct > 0)					phy->t_val[5] = 1 ;	/* medium */				else					phy->t_val[5] = 0 ;	/* short */				/*				 * Implementers choice: use medium				 * instead of short when undesired				 * connection attempt is made.				 */				if (phy->wc_flag)					phy->t_val[5] = 1 ;	/* medium */			}			mib->fddiPORTConnectState = PCM_CONNECTING ;		}		else {			mib->fddiPORTConnectState = PCM_STANDBY ;			phy->t_val[4] = 1 ;	/* extended */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -