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

📄 skgesirq.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * * SkGePortCheckUpLone - Check if the link is up * * return: *	0	o.k. nothing needed *	1	Restart needed on this port *	2	Link came up */static int	SkGePortCheckUpLone(SK_AC	*pAC,		/* Adapters context */SK_IOC	IoC,		/* IO Context */int	Port)		/* Which port should be checked */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */	SK_U16		Isrc;		/* Interrupt source register */	SK_U16		LpAb;		/* Link Partner Ability */	SK_U8		NextMode;	/* Next AutoSensing Mode */	SK_U16		ExtStat;	/* Extended Status Register */	SK_U16		PhyStat;	/* Phy Status Register */	SK_U16		StatSum;	int		Done;	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PHWLinkUp) {		return(SK_HW_PS_NONE) ;	}	StatSum = pPrt->PIsave;	pPrt->PIsave = 0;	/* Now wait for each ports link */	if (pPrt->PLinkMode == SK_LMODE_HALF ||	    pPrt->PLinkMode == SK_LMODE_FULL) {		AutoNeg = SK_FALSE;	} else {		AutoNeg = SK_TRUE;	}	/*	 * here we usually can check whether the link is in sync and	 * autonegotiation is done.	 */	XM_IN16(IoC, Port, XM_ISRC, &Isrc) ;	PHY_READ(IoC, pPrt, Port, PHY_LONE_STAT, &PhyStat);	StatSum |= PhyStat;	SkXmAutoNegLipaLone(pAC, IoC, Port, PhyStat);	if ((PhyStat & PHY_ST_LSYNC) == 0){		/*		 * Save Autonegotiation Done bit		 */		pPrt->PIsave = (SK_U16) (StatSum & PHY_ST_AN_OVER);#ifdef DEBUG		if (pPrt->PIsave & PHY_ST_AN_OVER) {			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,				("AutoNeg done rescheduled Port %d\n", Port));		}#endif		return(SK_HW_PS_NONE) ;	}	if (AutoNeg) {		if (StatSum & PHY_ST_AN_OVER) {			SkHWLinkUp(pAC, IoC, Port) ;			Done = SkXmAutoNegDone(pAC,IoC,Port);			if (Done != SK_AND_OK) {				/* Get PHY parameters, for debuging only */				PHY_READ(IoC, pPrt, Port,					PHY_LONE_AUNE_LP,					&LpAb);				PHY_READ(IoC, pPrt, Port,					PHY_LONE_1000T_STAT,					&ExtStat);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,					("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",					 Port, LpAb, ExtStat));									/* Try next possible mode */				NextMode = SkHWSenseGetNext(pAC, IoC, Port);				SkHWLinkDown(pAC, IoC, Port) ;				if (Done == SK_AND_DUP_CAP) {					/* GoTo next mode */					SkHWSenseSetNext(pAC, IoC, Port,						NextMode);				}				return(SK_HW_PS_RESTART) ;			} else {				/*				 * Dummy Read interrupt status to prevent				 * extra link down/ups				 */				PHY_READ(IoC, pPrt, Port, PHY_LONE_INT_STAT,					&ExtStat);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,					("AutoNeg done Port %d\n", Port));				return(SK_HW_PS_LINK) ;			}		} 				/*		 * AutoNeg not done, but HW link is up. Check for timeouts		 */		pPrt->PAutoNegTimeOut ++;		if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {			/*			 * Timeout occured.			 * What do we need now?			 */			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,				SK_DBGCAT_IRQ,				("AutoNeg timeout Port %d\n",				 Port));			if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&				pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {				/*				 * Timeout occured				 * Set Link manually up.				 */				SkHWSenseSetNext(pAC, IoC, Port,					SK_LMODE_FULL);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,					SK_DBGCAT_IRQ,					("Set manual full duplex Port %d\n",					 Port));			}			/*			 * Do the restart			 */			return(SK_HW_PS_RESTART) ;		}	} else {		/*		 * Link is up and we don't need more.		 */#ifdef	DEBUG		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,				("ERROR: Lipa auto detected on port %d\n",				Port));		}#endif		/*		 * Dummy Read interrupt status to prevent		 * extra link down/ups		 */		PHY_READ(IoC, pPrt, Port, PHY_LONE_INT_STAT, &ExtStat);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,			("Link sync(GP), Port %d\n", Port));		SkHWLinkUp(pAC, IoC, Port) ;		return(SK_HW_PS_LINK) ;	}	return(SK_HW_PS_NONE) ;}/****************************************************************************** * * SkGePortCheckUpNat - Check if the link is up * * return: *	0	o.k. nothing needed *	1	Restart needed on this port *	2	Link came up */static int	SkGePortCheckUpNat(SK_AC	*pAC,		/* Adapters context */SK_IOC	IoC,		/* IO Context */int	Port)		/* Which port should be checked */{	/* todo: National */	return(SK_HW_PS_NONE) ;}/****************************************************************************** * *	Event service routine * * Description: * * Notes: */int	SkGeSirqEvent(SK_AC		*pAC,		/* Adapters context */SK_IOC		IoC,		/* Io Context */SK_U32		Event,		/* Module specific Event */SK_EVPARA	Para)		/* Event specific Parameter */{	SK_U32	Port;	SK_U32	Time;	SK_U8	Val8 ;	int	PortStat;	Port = Para.Para32[0];	switch (Event) {	case SK_HWEV_WATIM:		/* Check whether port came up */		PortStat = SkGePortCheckUp(pAC, IoC, Port);		switch (PortStat) {		case SK_HW_PS_RESTART:			if (pAC->GIni.GP[Port].PHWLinkUp) {				/*				 * Set Link to down.				 */				SkHWLinkDown(pAC, IoC, Port);				/*				 * Signal directly to RLMT to ensure correct				 * sequence of SWITCH and RESET event.				 */				Para.Para32[0] = (SK_U32) Port;				SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);				/* Start workaround Errata #2 timer */				SkTimerStart(pAC, IoC,					&pAC->GIni.GP[Port].PWaTimer,					SK_WA_INA_TIME,					SKGE_HWAC,					SK_HWEV_WATIM,					Para);			}			/* Restart needed */			SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);			break;		case SK_HW_PS_LINK:			/* Signal to RLMT */			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);			break;		}		/* Start again the check Timer */		if (pAC->GIni.GP[Port].PHWLinkUp) {			Time = SK_WA_ACT_TIME;		} else {			Time = SK_WA_INA_TIME;		}		/* todo: still needed for non-Xmac-PHYs ??? */		/* Start workaround Errata #2 timer */		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer, Time,			SKGE_HWAC, SK_HWEV_WATIM, Para);		break;	case SK_HWEV_PORT_START:		if (pAC->GIni.GP[Port].PHWLinkUp) {			/*			 * Signal directly to RLMT to ensure correct			 * sequence of SWITCH and RESET event.			 */			Para.Para32[0] = (SK_U32) Port;			SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);		}		SkHWLinkDown(pAC, IoC, Port) ;		/* Schedule Port RESET */		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);		/* Start workaround Errata #2 timer */		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,			SK_WA_INA_TIME,SKGE_HWAC,SK_HWEV_WATIM,Para);		break;	case SK_HWEV_PORT_STOP:		if (pAC->GIni.GP[Port].PHWLinkUp) {			/*			 * Signal directly to RLMT to ensure correct			 * sequence of SWITCH and RESET event.			 */			Para.Para32[0] = (SK_U32) Port;			SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);		}		/* Stop Workaround Timer */		SkTimerStop(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer) ;		SkHWLinkDown(pAC, IoC, Port) ;		break;	case SK_HWEV_UPDATE_STAT:		/* We do NOT need to update any statistics */		break;	case SK_HWEV_CLEAR_STAT:		/* We do NOT need to clear any statistics */		for (Port = 0; Port < (SK_U32) pAC->GIni.GIMacsFound; Port++) {			pAC->GIni.GP[Port].PPrevRx = 0;			pAC->GIni.GP[Port].PPrevFcs = 0;			pAC->GIni.GP[Port].PPrevShorts = 0;		}		break;	case SK_HWEV_SET_LMODE:		Val8 = (SK_U8) Para.Para32[1];		if (pAC->GIni.GP[Port].PLinkModeConf != Val8) {			/* Set New link mode */			pAC->GIni.GP[Port].PLinkModeConf = Val8;			/* Restart Port */			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);		}		break;	case SK_HWEV_SET_FLOWMODE:		Val8 = (SK_U8) Para.Para32[1];		if (pAC->GIni.GP[Port].PFlowCtrlMode != Val8) {			/* Set New Flow Control mode */			pAC->GIni.GP[Port].PFlowCtrlMode = Val8;			/* Restart Port */			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);		}		break;	case SK_HWEV_SET_ROLE:		Val8 = (SK_U8) Para.Para32[1];		if (pAC->GIni.GP[Port].PMSMode != Val8) {			/* Set New link mode */			pAC->GIni.GP[Port].PMSMode = Val8;			/* Restart Port */			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);		}		break;	default:		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001,			SKERR_SIRQ_E001MSG);		break;	}	return(0) ;}/****************************************************************************** * *	SkPhyIsrBcom - PHY interrupt service routine * * Description: handle all interrupts from BCOM PHY * * Returns: N/A */static void SkPhyIsrBcom(SK_AC		*pAC,		/* Adapters context */SK_IOC		IoC,		/* Io Context */int		Port,		/* Port Num = PHY Num */SK_U16		IStatus)	/* Interrupts masked with PHY-Mask */{	SK_EVPARA	Para;	if (IStatus & PHY_B_IS_PSE) {		/* incorrectable pair swap error */		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E022,			SKERR_SIRQ_E022MSG) ;	}		if (IStatus & PHY_B_IS_MDXI_SC) {		/* not used */	}		if (IStatus & PHY_B_IS_HCT) {		/* not used */	}		if (IStatus & PHY_B_IS_LCT) {		/* not used */	}		if (IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) {		SkHWLinkDown(pAC, IoC, Port);		/* Signal to RLMT */		Para.Para32[0] = (SK_U32) Port;		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);		/* Start workaround Errata #2 timer */		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,			SK_WA_INA_TIME,SKGE_HWAC,SK_HWEV_WATIM,Para);	}	if (IStatus & PHY_B_IS_NO_HDCL) {		/* not used */	}	if (IStatus & PHY_B_IS_NO_HDC) {		/* not used */	}	if (IStatus & PHY_B_IS_NEG_USHDC) {		/* not used */	}	if (IStatus & PHY_B_IS_SCR_S_ER) {		/* not used */	}	if (IStatus & PHY_B_IS_RRS_CHANGE) {		/* not used */	}	if (IStatus & PHY_B_IS_LRS_CHANGE) {		/* not used */	}	if (IStatus & PHY_B_IS_DUP_CHANGE) {		/* not used */	}	if (IStatus & PHY_B_IS_LSP_CHANGE) {		/* not used */	}	if (IStatus & PHY_B_IS_CRC_ER) {		/* not used */	}}/****************************************************************************** * *	SkPhyIsrLone - PHY interrupt service routine * * Description: handle all interrupts from LONE PHY * * Returns: N/A */static void SkPhyIsrLone(SK_AC		*pAC,		/* Adapters context */SK_IOC		IoC,		/* Io Context */int		Port,		/* Port Num = PHY Num */SK_U16		IStatus)	/* Interrupts masked with PHY-Mask */{	SK_EVPARA	Para;	if (IStatus & PHY_L_IS_CROSS) {		/* not used */	}		if (IStatus & PHY_L_IS_POL) {		/* not used */	}		if (IStatus & PHY_L_IS_SS) {		/* not used */	}		if (IStatus & PHY_L_IS_CFULL) {		/* not used */	}		if (IStatus & PHY_L_IS_AN_C) {		/* not used */	}		if (IStatus & PHY_L_IS_SPEED) {		/* not used */	}		if (IStatus & PHY_L_IS_CFULL) {		/* not used */	}		if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {		SkHWLinkDown(pAC, IoC, Port);		/* Signal to RLMT */		Para.Para32[0] = (SK_U32) Port;		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);		/* Start workaround Errata #2 timer */		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,			SK_WA_INA_TIME,SKGE_HWAC,SK_HWEV_WATIM,Para);	}	if (IStatus & PHY_L_IS_MDINT) {		/* not used */	}}/* End of File */

⌨️ 快捷键说明

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