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

📄 pcmplc.c

📁 h内核
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * *	(C)Copyright 1998,1999 SysKonnect, *	a business unit of Schneider & Koch & Co. Datensysteme GmbH. * *	See the file "skfddi.c" for further information. * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2 of the License, or *	(at your option) any later version. * *	The information in this file is provided "AS IS" without warranty. * ******************************************************************************//*	PCM	Physical Connection Management*//* * Hardware independent state machine implemantation * The following external SMT functions are referenced : * * 		queue_event() * 		smt_timer_start() * 		smt_timer_stop() * * 	The following external HW dependent functions are referenced : * 		sm_pm_control() *		sm_ph_linestate() *		sm_pm_ls_latch() * * 	The following HW dependent events are required : *		PC_QLS *		PC_ILS *		PC_HLS *		PC_MLS *		PC_NSE *		PC_LEM * */#include "h/types.h"#include "h/fddi.h"#include "h/smc.h"#include "h/supern_2.h"#define KERNEL#include "h/smtstate.h"#ifndef	lintstatic const char ID_sccs[] = "@(#)pcmplc.c	2.55 99/08/05 (C) SK " ;#endif#ifdef	FDDI_MIBextern int snmp_fddi_trap(#ifdef	ANSICstruct s_smc	* smc, int  type, int  index#endif);#endif#ifdef	CONCENTRATORextern int plc_is_installed(#ifdef	ANSICstruct s_smc *smc ,int p#endif) ;#endif/* * FSM Macros */#define AFLAG		(0x20)#define GO_STATE(x)	(mib->fddiPORTPCMState = (x)|AFLAG)#define ACTIONS_DONE()	(mib->fddiPORTPCMState &= ~AFLAG)#define ACTIONS(x)	(x|AFLAG)/* * PCM states */#define PC0_OFF			0#define PC1_BREAK		1#define PC2_TRACE		2#define PC3_CONNECT		3#define PC4_NEXT		4#define PC5_SIGNAL		5#define PC6_JOIN		6#define PC7_VERIFY		7#define PC8_ACTIVE		8#define PC9_MAINT		9#ifdef	DEBUG/* * symbolic state names */static const char * const pcm_states[] =  {	"PC0_OFF","PC1_BREAK","PC2_TRACE","PC3_CONNECT","PC4_NEXT",	"PC5_SIGNAL","PC6_JOIN","PC7_VERIFY","PC8_ACTIVE","PC9_MAINT"} ;/* * symbolic event names */static const char * const pcm_events[] = {	"NONE","PC_START","PC_STOP","PC_LOOP","PC_JOIN","PC_SIGNAL",	"PC_REJECT","PC_MAINT","PC_TRACE","PC_PDR",	"PC_ENABLE","PC_DISABLE",	"PC_QLS","PC_ILS","PC_MLS","PC_HLS","PC_LS_PDR","PC_LS_NONE",	"PC_TIMEOUT_TB_MAX","PC_TIMEOUT_TB_MIN",	"PC_TIMEOUT_C_MIN","PC_TIMEOUT_T_OUT",	"PC_TIMEOUT_TL_MIN","PC_TIMEOUT_T_NEXT","PC_TIMEOUT_LCT",	"PC_NSE","PC_LEM"} ;#endif#ifdef	MOT_ELM/* * PCL-S control register * this register in the PLC-S controls the scrambling parameters */#define PLCS_CONTROL_C_U	0#define PLCS_CONTROL_C_S	(PL_C_SDOFF_ENABLE | PL_C_SDON_ENABLE | \				 PL_C_CIPHER_ENABLE)#define	PLCS_FASSERT_U		0#define	PLCS_FASSERT_S		0xFd76	/* 52.0 us */#define	PLCS_FDEASSERT_U	0#define	PLCS_FDEASSERT_S	0#else	/* nMOT_ELM *//* * PCL-S control register * this register in the PLC-S controls the scrambling parameters * can be patched for ANSI compliance if standard changes */static const u_char plcs_control_c_u[17] = "PLC_CNTRL_C_U=\0\0" ;static const u_char plcs_control_c_s[17] = "PLC_CNTRL_C_S=\01\02" ;#define PLCS_CONTROL_C_U (plcs_control_c_u[14] | (plcs_control_c_u[15]<<8))#define PLCS_CONTROL_C_S (plcs_control_c_s[14] | (plcs_control_c_s[15]<<8))#endif	/* nMOT_ELM *//* * external vars *//* struct definition see 'cmtdef.h' (also used by CFM) */#define PS_OFF		0#define PS_BIT3		1#define PS_BIT4		2#define PS_BIT7		3#define PS_LCT		4#define PS_BIT8		5#define PS_JOIN		6#define PS_ACTIVE	7#define LCT_LEM_MAX	255/* * PLC timing parameter */#define PLC_MS(m)	((int)((0x10000L-(m*100000L/2048))))#define SLOW_TL_MIN	PLC_MS(6)#define SLOW_C_MIN	PLC_MS(10)static	const struct plt {	int	timer ;			/* relative plc timer address */	int	para ;			/* default timing parameters */} pltm[] = {	{ PL_C_MIN, SLOW_C_MIN },	/* min t. to remain Connect State */	{ PL_TL_MIN, SLOW_TL_MIN },	/* min t. to transmit a Line State */	{ PL_TB_MIN, TP_TB_MIN },	/* min break time */	{ PL_T_OUT, TP_T_OUT },		/* Signaling timeout */	{ PL_LC_LENGTH, TP_LC_LENGTH },	/* Link Confidence Test Time */	{ PL_T_SCRUB, TP_T_SCRUB },	/* Scrub Time == MAC TVX time ! */	{ PL_NS_MAX, TP_NS_MAX },	/* max t. that noise is tolerated */	{ 0,0 }} ;/* * interrupt mask */#ifdef	SUPERNET_3/* * Do we need the EBUF error during signaling, too, to detect SUPERNET_3 * PLL bug? */static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |			PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR;#else	/* SUPERNET_3 *//* * We do NOT need the elasticity buffer error during signaling. */static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |			PL_PCM_ENABLED | PL_SELF_TEST ;#endif	/* SUPERNET_3 */static int plc_imsk_act = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |			PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR;/* external functions */void all_selection_criteria(struct s_smc *smc);/* internal functions */static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd);static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy);static void pc_tcode_actions(struct s_smc *smc, const int bit, struct s_phy *phy);static void reset_lem_struct(struct s_phy *phy);static void plc_init(struct s_smc *smc, int p);static void sm_ph_lem_start(struct s_smc *smc, int np, int threshold);static void sm_ph_lem_stop(struct s_smc *smc, int np);static void sm_ph_linestate(struct s_smc *smc, int phy, int ls);static void real_init_plc(struct s_smc *smc);/* * SMT timer interface *      start PCM timer 0 */static void start_pcm_timer0(struct s_smc *smc, u_long value, int event,			     struct s_phy *phy){	phy->timer0_exp = FALSE ;       /* clear timer event flag */	smt_timer_start(smc,&phy->pcm_timer0,value,		EV_TOKEN(EVENT_PCM+phy->np,event)) ;}/* * SMT timer interface *      stop PCM timer 0 */static void stop_pcm_timer0(struct s_smc *smc, struct s_phy *phy){	if (phy->pcm_timer0.tm_active)		smt_timer_stop(smc,&phy->pcm_timer0) ;}/*	init PCM state machine (called by driver)	clear all PCM vars and flags*/void pcm_init(struct s_smc *smc){	int		i ;	int		np ;	struct s_phy	*phy ;	struct fddi_mib_p	*mib ;	for (np = 0,phy = smc->y ; np < NUMPHYS ; np++,phy++) {		/* Indicates the type of PHY being used */		mib = phy->mib ;		mib->fddiPORTPCMState = ACTIONS(PC0_OFF) ;		phy->np = np ;		switch (smc->s.sas) {#ifdef	CONCENTRATOR		case SMT_SAS :			mib->fddiPORTMy_Type = (np == PS) ? TS : TM ;			break ;		case SMT_DAS :			mib->fddiPORTMy_Type = (np == PA) ? TA :					(np == PB) ? TB : TM ;			break ;		case SMT_NAC :			mib->fddiPORTMy_Type = TM ;			break;#else		case SMT_SAS :			mib->fddiPORTMy_Type = (np == PS) ? TS : TNONE ;			mib->fddiPORTHardwarePresent = (np == PS) ? TRUE :					FALSE ;#ifndef	SUPERNET_3			smc->y[PA].mib->fddiPORTPCMState = PC0_OFF ;#else			smc->y[PB].mib->fddiPORTPCMState = PC0_OFF ;#endif			break ;		case SMT_DAS :			mib->fddiPORTMy_Type = (np == PB) ? TB : TA ;			break ;#endif		}		/*		 * set PMD-type		 */		phy->pmd_scramble = 0 ;		switch (phy->pmd_type[PMD_SK_PMD]) {		case 'P' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_MULTI ;			break ;		case 'L' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_LCF ;			break ;		case 'D' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;			break ;		case 'S' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;			phy->pmd_scramble = TRUE ;			break ;		case 'U' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;			phy->pmd_scramble = TRUE ;			break ;		case '1' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_SINGLE1 ;			break ;		case '2' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_SINGLE2 ;			break ;		case '3' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_SINGLE2 ;			break ;		case '4' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_SINGLE1 ;			break ;		case 'H' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_UNKNOWN ;			break ;		case 'I' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;			break ;		case 'G' :			mib->fddiPORTPMDClass = MIB_PMDCLASS_TP ;			break ;		default:			mib->fddiPORTPMDClass = MIB_PMDCLASS_UNKNOWN ;			break ;		}		/*		 * A and B port can be on primary and secondary path		 */		switch (mib->fddiPORTMy_Type) {		case TA :			mib->fddiPORTAvailablePaths |= MIB_PATH_S ;			mib->fddiPORTRequestedPaths[1] = MIB_P_PATH_LOCAL ;			mib->fddiPORTRequestedPaths[2] =				MIB_P_PATH_LOCAL |				MIB_P_PATH_CON_ALTER |				MIB_P_PATH_SEC_PREFER ;			mib->fddiPORTRequestedPaths[3] =				MIB_P_PATH_LOCAL |				MIB_P_PATH_CON_ALTER |				MIB_P_PATH_SEC_PREFER |				MIB_P_PATH_THRU ;			break ;		case TB :			mib->fddiPORTAvailablePaths |= MIB_PATH_S ;			mib->fddiPORTRequestedPaths[1] = MIB_P_PATH_LOCAL ;			mib->fddiPORTRequestedPaths[2] =				MIB_P_PATH_LOCAL |				MIB_P_PATH_PRIM_PREFER ;			mib->fddiPORTRequestedPaths[3] =				MIB_P_PATH_LOCAL |				MIB_P_PATH_PRIM_PREFER |				MIB_P_PATH_CON_PREFER |				MIB_P_PATH_THRU ;			break ;		case TS :			mib->fddiPORTAvailablePaths |= MIB_PATH_S ;			mib->fddiPORTRequestedPaths[1] = MIB_P_PATH_LOCAL ;			mib->fddiPORTRequestedPaths[2] =				MIB_P_PATH_LOCAL |				MIB_P_PATH_CON_ALTER |				MIB_P_PATH_PRIM_PREFER ;			mib->fddiPORTRequestedPaths[3] =				MIB_P_PATH_LOCAL |				MIB_P_PATH_CON_ALTER |				MIB_P_PATH_PRIM_PREFER ;			break ;		case TM :			mib->fddiPORTRequestedPaths[1] = MIB_P_PATH_LOCAL ;			mib->fddiPORTRequestedPaths[2] =				MIB_P_PATH_LOCAL |				MIB_P_PATH_SEC_ALTER |				MIB_P_PATH_PRIM_ALTER ;			mib->fddiPORTRequestedPaths[3] = 0 ;			break ;		}		phy->pc_lem_fail = FALSE ;		mib->fddiPORTPCMStateX = mib->fddiPORTPCMState ;		mib->fddiPORTLCTFail_Ct = 0 ;		mib->fddiPORTBS_Flag = 0 ;		mib->fddiPORTCurrentPath = MIB_PATH_ISOLATED ;		mib->fddiPORTNeighborType = TNONE ;		phy->ls_flag = 0 ;		phy->rc_flag = 0 ;		phy->tc_flag = 0 ;		phy->td_flag = 0 ;		if (np >= PM)			phy->phy_name = '0' + np - PM ;		else			phy->phy_name = 'A' + np ;		phy->wc_flag = FALSE ;		/* set by SMT */		memset((char *)&phy->lem,0,sizeof(struct lem_counter)) ;		reset_lem_struct(phy) ;		memset((char *)&phy->plc,0,sizeof(struct s_plc)) ;		phy->plc.p_state = PS_OFF ;		for (i = 0 ; i < NUMBITS ; i++) {			phy->t_next[i] = 0 ;		}	}	real_init_plc(smc) ;}void init_plc(struct s_smc *smc){	SK_UNUSED(smc) ;	/*	 * dummy	 * this is an obsolete public entry point that has to remain	 * for compat. It is used by various drivers.	 * the work is now done in real_init_plc()	 * which is called from pcm_init() ;	 */}static void real_init_plc(struct s_smc *smc){	int	p ;	for (p = 0 ; p < NUMPHYS ; p++)		plc_init(smc,p) ;}static void plc_init(struct s_smc *smc, int p){	int	i ;#ifndef	MOT_ELM	int	rev ;	/* Revision of PLC-x */#endif	/* MOT_ELM */	/* transit PCM state machine to MAINT state */	outpw(PLC(p,PL_CNTRL_B),0) ;	outpw(PLC(p,PL_CNTRL_B),PL_PCM_STOP) ;	outpw(PLC(p,PL_CNTRL_A),0) ;	/*	 * if PLC-S then set control register C	 */#ifndef	MOT_ELM	rev = inpw(PLC(p,PL_STATUS_A)) & PLC_REV_MASK ;	if (rev != PLC_REVISION_A)#endif	/* MOT_ELM */	{		if (smc->y[p].pmd_scramble) {			outpw(PLC(p,PL_CNTRL_C),PLCS_CONTROL_C_S) ;#ifdef	MOT_ELM			outpw(PLC(p,PL_T_FOT_ASS),PLCS_FASSERT_S) ;			outpw(PLC(p,PL_T_FOT_DEASS),PLCS_FDEASSERT_S) ;#endif	/* MOT_ELM */		}		else {			outpw(PLC(p,PL_CNTRL_C),PLCS_CONTROL_C_U) ;#ifdef	MOT_ELM			outpw(PLC(p,PL_T_FOT_ASS),PLCS_FASSERT_U) ;			outpw(PLC(p,PL_T_FOT_DEASS),PLCS_FDEASSERT_U) ;#endif	/* MOT_ELM */		}	}	/*	 * set timer register	 */	for ( i = 0 ; pltm[i].timer; i++)	/* set timer parameter reg */		outpw(PLC(p,pltm[i].timer),pltm[i].para) ;	(void)inpw(PLC(p,PL_INTR_EVENT)) ;	/* clear interrupt event reg */	plc_clear_irq(smc,p) ;	outpw(PLC(p,PL_INTR_MASK),plc_imsk_na); /* enable non active irq's */	/*	 * if PCM is configured for class s, it will NOT go to the	 * REMOVE state if offline (page 3-36;)	 * in the concentrator, all inactive PHYS always must be in	 * the remove state	 * there's no real need to use this feature at all ..	 */#ifndef	CONCENTRATOR	if ((smc->s.sas == SMT_SAS) && (p == PS)) {		outpw(PLC(p,PL_CNTRL_B),PL_CLASS_S) ;	}#endif}/* * control PCM state machine */static void plc_go_state(struct s_smc *smc, int p, int state){	HW_PTR port ;	int val ;	SK_UNUSED(smc) ;	port = (HW_PTR) (PLC(p,PL_CNTRL_B)) ;	val = inpw(port) & ~(PL_PCM_CNTRL | PL_MAINT) ;	outpw(port,val) ;	outpw(port,val | state) ;}/* * read current line state (called by ECM & PCM) */int sm_pm_get_ls(struct s_smc *smc, int phy){	int	state ;

⌨️ 快捷键说明

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