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

📄 skgesirq.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL;		} else {			pPrt->PLinkModeStatus = SK_LMODE_STAT_HALF;		}		/* No flow control without autonegotiation */		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE ;		/* RX/TX enable */		SkXmRxTxEnable(pAC, IoC, Port);	}}/****************************************************************************** * * SkMacParity	- does everything to handle MAC parity errors correctly * */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_U64		TxMax;		/* TxMax Counter */	unsigned int	Len;	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(Port));	if (TxMax > 0) {		/* From now on check the parity */		pPrt->PCheckPar = SK_TRUE;	}}/****************************************************************************** * *	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;	if (HwStatus & IS_IRQ_STAT) {		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E013,			SKERR_SIRQ_E013MSG) ;		Para.Para64 = 0;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);	}	if (HwStatus & IS_IRQ_MST_ERR) {		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E012,			SKERR_SIRQ_E012MSG) ;		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);	}}/****************************************************************************** * *	Interrupt service routine * * Description: * * Notes: */void	SkGeSirqIsr(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */SK_U32	Istatus)	/* Interrupt status word */{	SK_U32		RegVal32;	/* Read register Value */	SK_EVPARA	Para;	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) {		/* May be a normal situation in a server with a slow network */		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1) ;	}	if (Istatus & IS_PA_TO_TX2) {		/* May be a normal situation in a server with a slow network */		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2) ;	}	/*	 * 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;		/* test IRQs from PHY */		for (i=0; i<pAC->GIni.GIMacsFound; i++) {			switch (pAC->GIni.GP[i].PhyType) {			case SK_PHY_XMAC:				break;			case SK_PHY_BCOM:	    			if(pAC->GIni.GP[i].PState) {					PHY_READ(IoC, &pAC->GIni.GP[i], i,						PHY_BCOM_INT_STAT, &PhyInt);					PHY_READ(IoC, &pAC->GIni.GP[i], i,						PHY_BCOM_INT_MASK, &PhyIMsk);										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,							(SK_U16) 							(PhyInt & (~PhyIMsk)));					}				}				else {				}				break;			case SK_PHY_LONE:				PHY_READ(IoC, &pAC->GIni.GP[i], i,					PHY_LONE_INT_STAT, &PhyInt);				PHY_READ(IoC, &pAC->GIni.GP[i], 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,						(SK_U16) (PhyInt & PhyIMsk));				}				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);	}}/* * Define an array of RX counter which are checked * in AutoSense mode to check whether a link is not able to autonegotiate. */static const SK_U32 SkGeRxOids[]= {	OID_SKGE_STAT_RX_64,	OID_SKGE_STAT_RX_127,	OID_SKGE_STAT_RX_255,	OID_SKGE_STAT_RX_511,	OID_SKGE_STAT_RX_1023,	OID_SKGE_STAT_RX_MAX,} ;/****************************************************************************** * * SkGePortCheckShorts - Implementing of the Workaround Errata # 2 * * return: *	0	o.k. nothing needed *	1	Restart needed on this port */int	SkGePortCheckShorts(SK_AC	*pAC,		/* Adapters 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 int	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(Port));	/*	 * 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(Port));		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;		/* 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(Port));				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

⌨️ 快捷键说明

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