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

📄 skgesirq.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 4 页
字号:
	pPrt = &pAC->GIni.GP[Port];	/* Clear IRQ */	SK_OUT16(IoC, MR_ADDR(Port,TX_MFF_CTRL1), MFF_CLR_PERR);	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 */	Len = sizeof(SK_U64);	SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_MAX, (char *)&TxMax,		&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),		pAC->Rlmt.Port[Port].Net->NetNumber);	if (TxMax > 0) {		/* From now on check the parity */		pPrt->PCheckPar = SK_TRUE;	}}	/* SkMacParity *//****************************************************************************** * *	Hardware Error service routine * * Description: * * Notes: */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) || (HwStatus & IS_IRQ_STAT)) {		if (HwStatus & IS_IRQ_STAT) {			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_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);		SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);		SK_OUT16(IoC, PCI_C(PCI_STATUS), 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);	}	if (HwStatus & IS_NO_STAT_M1) {		/* 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) {		/* 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) {		/* 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) {		/* Ignore it */		/* This situation is also indicated in the descriptor */		SK_OUT16(IoC, MR_ADDR(MAC_2,RX_MFF_CTRL1), MFF_CLR_INTIST);	}	if (HwStatus & IS_RAM_RD_PAR) {		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) {		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) {		SkMacParity(pAC, IoC, MAC_1);	}	if (HwStatus & IS_M2_PAR_ERR) {		SkMacParity(pAC, IoC, MAC_2);	}	if (HwStatus & IS_R1_PAR_ERR) {		/* 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) {		/* 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 *//****************************************************************************** * *	Interrupt service routine * * Description: * * Notes: */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_U16		XmIsr;	if (Istatus & IS_HW_ERR) {		SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);		SkGeHwErr(pAC, IoC, RegVal32);	}	/*	 * Packet Timeout interrupts	 */	/* Check whether XMACs are correctly initialized */	if ((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) &&		!pAC->GIni.GP[MAC_1].PState) {		/* XMAC was not initialized but Packet timeout occured */		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,			SKERR_SIRQ_E004MSG);	}	if ((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) &&	    !pAC->GIni.GP[MAC_2].PState) {		/* XMAC was not initialized but Packet timeout occured */		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,			SKERR_SIRQ_E005MSG);	}	if (Istatus & IS_PA_TO_RX1) {		/* Means network is filling us up */		SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,			SKERR_SIRQ_E002MSG);		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);	}	if (Istatus & IS_PA_TO_RX2) {		/* Means network is filling us up */		SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,			SKERR_SIRQ_E003MSG);		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);	}	if (Istatus & IS_PA_TO_TX1) {		unsigned int	Len;		SK_U64		Octets;		SK_GEPORT	*pPrt = &pAC->GIni.GP[0];		/* May be a normal situation in a server with a slow network */		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);		/*		 * workaround: if in half duplex mode, check for tx hangup.		 * Read number of TX'ed bytes, wait for 10 ms, then compare		 * the number with current value. If nothing changed, we		 * assume that tx is hanging and do a FIFO flush (see event		 * routine).		 */		if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || 		    pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&		    !pPrt->HalfDupTimerActive) {			/* 			 * many more pack. arb. timeouts may come in between,			 * we ignore those			 */			pPrt->HalfDupTimerActive = SK_TRUE;			Len = sizeof(SK_U64);			SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *) &Octets,				&Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 0),				pAC->Rlmt.Port[0].Net->NetNumber);			pPrt->LastOctets = Octets;			Para.Para32[0] = 0;			SkTimerStart(pAC, IoC,				&pPrt->HalfDupChkTimer,				SK_HALFDUP_CHK_TIME,				SKGE_HWAC,				SK_HWEV_HALFDUP_CHK,				Para);		}	}	if (Istatus & IS_PA_TO_TX2) {		unsigned int	Len;		SK_U64		Octets;		SK_GEPORT	*pPrt = &pAC->GIni.GP[1];		/* May be a normal situation in a server with a slow network */		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);		/*		 * workaround: see above		 */		if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || 		    pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&		    !pPrt->HalfDupTimerActive) {			pPrt->HalfDupTimerActive = SK_TRUE;			Len = sizeof(SK_U64);			SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *) &Octets,				&Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 1),				pAC->Rlmt.Port[1].Net->NetNumber);			pPrt->LastOctets = Octets;			Para.Para32[0] = 1;			SkTimerStart(pAC, IoC,				&pPrt->HalfDupChkTimer,				SK_HALFDUP_CHK_TIME,				SKGE_HWAC,				SK_HWEV_HALFDUP_CHK,				Para);		}	}	/*	 * Check interrupts of the particular queues.	 */	if (Istatus & IS_R1_C) {		/* Clear IRQ */		SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,			SKERR_SIRQ_E006MSG);		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 (Istatus & IS_R2_C) {		/* Clear IRQ */		SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,			SKERR_SIRQ_E007MSG);		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);	}	if (Istatus & IS_XS1_C) {		/* Clear IRQ */		SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,			SKERR_SIRQ_E008MSG);		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 (Istatus & IS_XA1_C) {		/* Clear IRQ */		SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,			SKERR_SIRQ_E009MSG);		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 (Istatus & IS_XS2_C) {		/* Clear IRQ */		SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,			SKERR_SIRQ_E010MSG);		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);	}	if (Istatus & IS_XA2_C) {		/* Clear IRQ */		SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,			SKERR_SIRQ_E011MSG);		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);	}	/*	 * External reg interrupt.	 */	if (Istatus & IS_EXT_REG) {		SK_U16 	PhyInt;		SK_U16 	PhyIMsk;		int		i;		SK_GEPORT	*pPrt;		/* GIni Port struct pointer */		/* Test IRQs from PHY. */		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {			pPrt = &pAC->GIni.GP[i];			switch (pPrt->PhyType) {			case SK_PHY_XMAC:				break;			case SK_PHY_BCOM:				if (pPrt->PState) {					PHY_READ(IoC, pPrt, i, PHY_BCOM_INT_STAT, &PhyInt);					PHY_READ(IoC, pPrt, i, PHY_BCOM_INT_MASK, &PhyIMsk);#ifdef xDEBUG					if (PhyInt & PhyIMsk) {						CMSMPrintString(							pAC->pConfigTable,							MSG_TYPE_RUNTIME_INFO,							"SirqIsr - Stat: %x",							(void *)PhyInt,							(void *)NULL);					}#endif	/* DEBUG */										if (PhyInt & ~PhyIMsk) {						SK_DBG_MSG(							pAC,							SK_DBGMOD_HWM,							SK_DBGCAT_IRQ,							("Port %d Bcom Int: %x Mask: %x\n",								i, PhyInt, PhyIMsk));						SkPhyIsrBcom(pAC, IoC, i, PhyInt);					}				}				break;			case SK_PHY_LONE:				PHY_READ(IoC, pPrt, i, PHY_LONE_INT_STAT, &PhyInt);				PHY_READ(IoC, pPrt, i, PHY_LONE_INT_ENAB, &PhyIMsk);								if (PhyInt & PhyIMsk) {					SK_DBG_MSG(						pAC,						SK_DBGMOD_HWM,						SK_DBGCAT_IRQ,						("Port %d  Lone Int: %x Mask: %x\n",						i, PhyInt, PhyIMsk));					SkPhyIsrLone(pAC, IoC, i, PhyInt);				}				break;			case SK_PHY_NAT:				/* todo: National */				break;			}		}	}	/*	 * I2C Ready interrupt	 */	if (Istatus & IS_I2C_READY) {		SkI2cIsr(pAC, IoC);	}	if (Istatus & IS_LNK_SYNC_M1) {		/*		 * We do NOT need the Link Sync interrupt, because it shows		 * us only a link going down.		 */		/* clear interrupt */		SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);	}	/* Check MAC after link sync counter */	if (Istatus & IS_MAC1) {		XM_IN16(IoC, MAC_1, XM_ISRC, &XmIsr);		SkXmIrq(pAC, IoC, MAC_1, XmIsr);	}	if (Istatus & IS_LNK_SYNC_M2) {		/*		 * We do NOT need the Link Sync interrupt, because it shows		 * us only a link going down.		 */		/* clear interrupt */		SK_OUT8(IoC, MR_ADDR(MAC_2,LNK_SYNC_CTRL), LED_CLR_IRQ);	}	/* Check MAC after link sync counter */	if (Istatus & IS_MAC2) {		XM_IN16(IoC, MAC_2, XM_ISRC, &XmIsr);		SkXmIrq(pAC, IoC, MAC_2, XmIsr);	}	/*	 * Timer interrupt	 *  To be served last	 */	if (Istatus & IS_TIMINT) {		SkHwtIsr(pAC, IoC);	}}	/* SkGeSirqIsr *//****************************************************************************** * * SkGePortCheckShorts - Implementing of the Workaround Errata # 2 * * return: *	0	o.k. nothing needed *	1	Restart needed on this port */int	SkGePortCheckShorts(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* IO Context */int		Port)		/* Which port should be checked */{	SK_U64		Shorts;			/* Short Event Counter */	SK_U64		CheckShorts;	/* Check value for Short Event Counter */	SK_U64		RxCts;			/* RX Counter (packets on network) */	SK_U64		RxTmp;			/* RX temp. Counter */	SK_U64		FcsErrCts;		/* FCS Error Counter */	SK_GEPORT	*pPrt;			/* GIni Port struct pointer */	unsigned 	Len;	int			Rtv;			/* Return value */	int			i;	pPrt = &pAC->GIni.GP[Port];	/* Default: no action */	Rtv = SK_HW_PS_NONE;	/*	 * Extra precaution: check for short Event counter	 */	Len = sizeof(SK_U64);	SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_SHORTS, (char *)&Shorts,		&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),		pAC->Rlmt.Port[Port].Net->NetNumber);	/*	 * Read RX counter (packets seen on the network and not neccesarily	 * really received.	 */	Len = sizeof(SK_U64);	RxCts = 0;	for (i = 0; i < sizeof(SkGeRxOids)/sizeof(SK_U32); i++) {		SkPnmiGetVar(pAC, IoC, SkGeRxOids[i], (char *)&RxTmp,			&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),			pAC->Rlmt.Port[Port].Net->NetNumber);		RxCts += RxTmp;	}	/* On default: check shorts against zero */	CheckShorts = 0;	/*	 * Extra extra precaution on active links:	 */	if (pPrt->PHWLinkUp) {		/*		 * Reset Link Restart counter		 */		pPrt->PLinkResCt = 0;		pPrt->PAutoNegTOCt = 0;		/* If link is up check for 2 */		CheckShorts = 2;		Len = sizeof(SK_U64);		SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_FCS,			(char *)&FcsErrCts, &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),			pAC->Rlmt.Port[Port].Net->NetNumber);				if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&		    pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&		    (pPrt->PLinkMode == SK_LMODE_HALF ||			 pPrt->PLinkMode == SK_LMODE_FULL)) {			/*			 * This is autosensing and we are in the fallback			 * manual full/half duplex mode.			 */			if (RxCts == pPrt->PPrevRx) {				/*				 * Nothing received				 * restart link				 */				pPrt->PPrevFcs = FcsErrCts;				pPrt->PPrevShorts = Shorts;				return (SK_HW_PS_RESTART);			}			else {				pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;			}		}		if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||		    (!(FcsErrCts - pPrt->PPrevFcs))) {			/*			 * Note: The compare with zero above has to be done the way shown,			 * otherwise the Linux driver will have a problem.			 */			/*			 * We received a bunch of frames or no CRC error occured on the			 * network -> ok.			 */			pPrt->PPrevRx = RxCts;			pPrt->PPrevFcs = FcsErrCts;			pPrt->PPrevShorts = Shorts;			return (SK_HW_PS_NONE);		}		pPrt->PPrevFcs = FcsErrCts;	}	if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,			("Short Event Count Restart Port %d \n", Port));		Rtv = SK_HW_PS_RESTART;	}	pPrt->PPrevShorts = Shorts;	pPrt->PPrevRx = RxCts;	return (Rtv);}	/* SkGePortCheckShorts*/

⌨️ 快捷键说明

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