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

📄 skgesirq.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * * Name:	skgesirq.c * Project:	Gigabit Ethernet Adapters, Common Modules * Version:	$Revision: 1.92 $ * Date:	$Date: 2003/09/16 14:37:07 $ * Purpose:	Special IRQ module * ******************************************************************************//****************************************************************************** * *	(C)Copyright 1998-2002 SysKonnect. *	(C)Copyright 2002-2003 Marvell. * *	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. * ******************************************************************************//* *	Special Interrupt handler * *	The following abstract should show how this module is included *	in the driver path: * *	In the ISR of the driver the bits for frame transmission complete and *	for receive complete are checked and handled by the driver itself. *	The bits of the slow path mask are checked after that and then the *	entry into the so-called "slow path" is prepared. It is an implementors *	decision whether this is executed directly or just scheduled by *	disabling the mask. In the interrupt service routine some events may be *	generated, so it would be a good idea to call the EventDispatcher *	right after this ISR. * *	The Interrupt source register of the adapter is NOT read by this module. *  SO if the drivers implementor needs a while loop around the *	slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for *	each loop entered. * *	However, the MAC Interrupt status registers are read in a while loop. * */#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))static const char SysKonnectFileId[] =	"@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";#endif#include "h/skdrv1st.h"		/* Driver Specific Definitions */#ifndef SK_SLIM#include "h/skgepnmi.h"		/* PNMI Definitions */#include "h/skrlmt.h"		/* RLMT Definitions */#endif#include "h/skdrv2nd.h"		/* Adapter Control and Driver specific Def. *//* local function prototypes */#ifdef GENESISstatic int	SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);static int	SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL);static void	SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);#endif /* GENESIS */#ifdef YUKONstatic int	SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL);static void	SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);#endif /* YUKON */#ifdef OTHER_PHYstatic int	SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL);static int	SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL);static void	SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);#endif /* OTHER_PHY */#ifdef GENESIS/* * array of Rx counter from XMAC which are checked * in AutoSense mode to check whether a link is not able to auto-negotiate. */static const SK_U16 SkGeRxRegs[]= {	XM_RXF_64B,	XM_RXF_127B,	XM_RXF_255B,	XM_RXF_511B,	XM_RXF_1023B,	XM_RXF_MAX_SZ} ;#endif /* GENESIS */#ifdef __C2MAN__/* *	Special IRQ function * *	General Description: * */intro(){}#endif/****************************************************************************** * *	SkHWInitDefSense() - Default Autosensing mode initialization * * Description: sets the PLinkMode for HWInit * * Returns: N/A */static void SkHWInitDefSense(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* IO context */int		Port)	/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	pPrt = &pAC->GIni.GP[Port];	pPrt->PAutoNegTimeOut = 0;	if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {		pPrt->PLinkMode = pPrt->PLinkModeConf;		return;	}	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,		("AutoSensing: First mode %d on Port %d\n",		(int)SK_LMODE_AUTOFULL, Port));	pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;	return;}	/* SkHWInitDefSense */#ifdef GENESIS/****************************************************************************** * *	SkHWSenseGetNext() - Get Next Autosensing Mode * * Description: gets the appropriate next mode * * Note: * */static SK_U8 SkHWSenseGetNext(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* IO context */int		Port)	/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	pPrt = &pAC->GIni.GP[Port];	pPrt->PAutoNegTimeOut = 0;    if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {		/* Leave all as configured */		return(pPrt->PLinkModeConf);	}    if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {		/* Return next mode AUTOBOTH */        return ((SK_U8)SK_LMODE_AUTOBOTH);	}	/* Return default autofull */    return ((SK_U8)SK_LMODE_AUTOFULL);}	/* SkHWSenseGetNext *//****************************************************************************** * *	SkHWSenseSetNext() - Autosensing Set next mode * * Description:	sets the appropriate next mode * * Returns: N/A */static void SkHWSenseSetNext(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port,		/* Port Index (MAC_1 + n) */SK_U8	NewMode)	/* New Mode to be written in sense mode */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	pPrt = &pAC->GIni.GP[Port];	pPrt->PAutoNegTimeOut = 0;    if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {		return;	}	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,		("AutoSensing: next mode %d on Port %d\n",		(int)NewMode, Port));	pPrt->PLinkMode = NewMode;	return;}	/* SkHWSenseSetNext */#endif /* GENESIS *//****************************************************************************** * *	SkHWLinkDown() - Link Down handling * * Description: handles the hardware link down signal * * Returns: N/A */void SkHWLinkDown(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port)		/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	pPrt = &pAC->GIni.GP[Port];	/* Disable all MAC interrupts */	SkMacIrqDisable(pAC, IoC, Port);	/* Disable Receiver and Transmitter */	SkMacRxTxDisable(pAC, IoC, Port);		/* Init default sense mode */	SkHWInitDefSense(pAC, IoC, Port);	if (pPrt->PHWLinkUp == SK_FALSE) {		return;	}	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,		("Link down Port %d\n", Port));	/* Set Link to DOWN */	pPrt->PHWLinkUp = SK_FALSE;	/* Reset Port stati */    pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;    pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;	pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;	/* Re-init Phy especially when the AutoSense default is set now */	SkMacInitPhy(pAC, IoC, Port, SK_FALSE);	/* GP0: used for workaround of Rev. C Errata 2 */	/* Do NOT signal to RLMT */	/* Do NOT start the timer here */}	/* SkHWLinkDown *//****************************************************************************** * *	SkHWLinkUp() - Link Up handling * * Description: handles the hardware link up signal * * Returns: N/A */void SkHWLinkUp(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* IO context */int		Port)	/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PHWLinkUp) {		/* We do NOT need to proceed on active link */		return;	}	pPrt->PHWLinkUp = SK_TRUE;	pPrt->PAutoNegFail = SK_FALSE;    pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;    if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&        pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&        pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {		/* Link is up and no Auto-negotiation should be done */		/* Link speed should be the configured one */		switch (pPrt->PLinkSpeed) {		case SK_LSPEED_AUTO:			/* default is 1000 Mbps */		case SK_LSPEED_1000MBPS:			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;			break;		case SK_LSPEED_100MBPS:			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;			break;		case SK_LSPEED_10MBPS:			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;			break;		}		/* Set Link Mode Status */		if (pPrt->PLinkMode == SK_LMODE_FULL) {			pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;		}		else {            pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;		}		/* No flow control without auto-negotiation */        pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;		/* enable Rx/Tx */        (void)SkMacRxTxEnable(pAC, IoC, Port);	}}	/* SkHWLinkUp *//****************************************************************************** * *	SkMacParity() - MAC parity workaround * * Description: handles MAC parity errors correctly * * Returns: N/A */static void SkMacParity(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* IO context */int		Port)	/* Port Index of the port failed */{	SK_EVPARA	Para;	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_U32		TxMax;		/* Tx Max Size Counter */	pPrt = &pAC->GIni.GP[Port];	/* Clear IRQ Tx Parity Error */#ifdef GENESIS	if (pAC->GIni.GIGenesis) {		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);	}#endif /* GENESIS */	#ifdef YUKON	if (pAC->GIni.GIYukon) {		/* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */		SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),			(SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON &&			pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));	}#endif /* YUKON */		if (pPrt->PCheckPar) {		if (Port == MAC_1) {			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);		}		else {			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);		}		Para.Para64 = Port;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);				Para.Para32[0] = Port;		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);		return;	}	/* Check whether frames with a size of 1k were sent */#ifdef GENESIS	if (pAC->GIni.GIGenesis) {		/* Snap statistic counters */		(void)SkXmUpdateStats(pAC, IoC, Port);				(void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);	}#endif /* GENESIS */	#ifdef YUKON	if (pAC->GIni.GIYukon) {		(void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);	}#endif /* YUKON */		if (TxMax > 0) {		/* From now on check the parity */		pPrt->PCheckPar = SK_TRUE;	}}	/* SkMacParity *//****************************************************************************** * *	SkGeHwErr() - Hardware Error service routine * * Description: handles all HW Error interrupts * * Returns: N/A */static void SkGeHwErr(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */SK_U32	HwStatus)	/* Interrupt status word */{	SK_EVPARA	Para;	SK_U16		Word;	if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {		/* PCI Errors occured */		if ((HwStatus & IS_IRQ_STAT) != 0) {			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);		}		else {			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);		}		/* Reset all bits in the PCI STATUS register */		SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);        SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);		Para.Para64 = 0;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);	}#ifdef GENESIS	if (pAC->GIni.GIGenesis) {		if ((HwStatus & IS_NO_STAT_M1) != 0) {			/* Ignore it */			/* This situation is also indicated in the descriptor */			SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);		}		if ((HwStatus & IS_NO_STAT_M2) != 0) {			/* Ignore it */			/* This situation is also indicated in the descriptor */			SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);		}		if ((HwStatus & IS_NO_TIST_M1) != 0) {			/* Ignore it */			/* This situation is also indicated in the descriptor */			SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);		}		if ((HwStatus & IS_NO_TIST_M2) != 0) {			/* Ignore it */			/* This situation is also indicated in the descriptor */			SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);		}	}#endif /* GENESIS */	#ifdef YUKON	if (pAC->GIni.GIYukon) {		/* This is necessary only for Rx timing measurements */		if ((HwStatus & IS_IRQ_TIST_OV) != 0) {			/* increment Time Stamp Timer counter (high) */			pAC->GIni.GITimeStampCnt++;			/* Clear Time Stamp Timer IRQ */			SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);		}		if ((HwStatus & IS_IRQ_SENSOR) != 0) {			/* no sensors on 32-bit Yukon */			if (pAC->GIni.GIYukon32Bit) {				/* disable HW Error IRQ */				pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;			}		}	}#endif /* YUKON */	if ((HwStatus & IS_RAM_RD_PAR) != 0) {		SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);		Para.Para64 = 0;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);	}	if ((HwStatus & IS_RAM_WR_PAR) != 0) {		SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);		Para.Para64 = 0;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);	}	if ((HwStatus & IS_M1_PAR_ERR) != 0) {		SkMacParity(pAC, IoC, MAC_1);	}	if ((HwStatus & IS_M2_PAR_ERR) != 0) {		SkMacParity(pAC, IoC, MAC_2);	}	if ((HwStatus & IS_R1_PAR_ERR) != 0) {		/* Clear IRQ */		SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);		Para.Para64 = MAC_1;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);				Para.Para32[0] = MAC_1;		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);	}	if ((HwStatus & IS_R2_PAR_ERR) != 0) {		/* Clear IRQ */		SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);		Para.Para64 = MAC_2;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);				Para.Para32[0] = MAC_2;		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);	}}	/* SkGeHwErr *//****************************************************************************** * *	SkGeSirqIsr() - Special Interrupt Service Routine * * Description: handles all non data transfer specific interrupts (slow path) * * Returns: N/A */void SkGeSirqIsr(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */SK_U32	Istatus)	/* Interrupt status word */{	SK_EVPARA	Para;	SK_U32		RegVal32;	/* Read register value */	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_U16 		PhyInt;	int			i;	if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {		/* read the HW Error Interrupt source */		SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);				SkGeHwErr(pAC, IoC, RegVal32);	}	/*	 * Packet Timeout interrupts	 */	/* Check whether MACs are correctly initialized */

⌨️ 快捷键说明

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