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

📄 skgesirq.c

📁 这是Marvell Technology Group Ltd. 4355 (rev 12)网卡在linux下的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		if ((DWord & (PEX_FATAL_ERRORS | PEX_POIS_TLP)) != 0) {			/*			 * Stop only, if the uncorrectable error is fatal or			 * Poisoned TLP occurred			 */			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Header Log:"));			for (i = 0; i < 4; i++) {				/* get TLP Header from Log Registers */				SK_IN32(IoC, PCI_C(pAC, PEX_HEADER_LOG + i*4), &TlpHead[i]);				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,					(" 0x%08lX", TlpHead[i]));			}			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("\n"));			/* check for vendor defined broadcast message */			if (TlpHead[0] == 0x73004001 && (SK_U8)TlpHead[1] == 0x7f) {				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,					("Vendor defined broadcast message\n"));			}			else {				Para.Para64 = 0;				SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);				pAC->GIni.GIValHwIrqMask &= ~Y2_IS_PCI_EXP;				/* Rewrite HW IRQ mask */				SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask);			}		}		/* clear any PEX errors */		SK_TST_MODE_ON(IoC);		SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL);		SK_TST_MODE_OFF(IoC);		SK_IN32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), &DWord);		if ((DWord & PEX_RX_OV) != 0) {			/* Dev #4.205 occurred */			pAC->GIni.GIValHwIrqMask &= ~Y2_IS_PCI_EXP;			pAC->GIni.GIValIrqMask &= ~Y2_IS_HW_ERR;		}	}	for (i = 0; i < pAC->GIni.GIMacsFound; i++) {		SkYuk2HwPortErr(pAC, IoC, HwStatus, i);	}}	/* SkYuk2HwErr */#endif /* YUK2 *//****************************************************************************** * *	SkGeSirqIsr() - Wrapper for Special Interrupt Service Routine * * Description: calls the preselected special ISR (slow path) * * Returns: N/A */void SkGeSirqIsr(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O context */SK_U32	Istatus)	/* Interrupt status word */{	pAC->GIni.GIFunc.pSkGeSirqIsr(pAC, IoC, Istatus);}#ifndef DISABLE_YUKON_I/****************************************************************************** * *	SkGeYuSirqIsr() - Special Interrupt Service Routine * * Description: handles all non data transfer specific interrupts (slow path) * * Returns: N/A */void SkGeYuSirqIsr(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O 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;	int			Rtv;	if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {		/* read the HW Error Interrupt source */		SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);		SkGeYuHwErr(pAC, IoC, RegVal32);	}	/*	 * Packet Timeout interrupts	 */	/* Check whether MACs are correctly initialized */	if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&		pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {		/* MAC 1 was not initialized but Packet timeout occurred */		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)) != 0) &&		pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {		/* MAC 2 was not initialized but Packet timeout occurred */		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,			SKERR_SIRQ_E005MSG);	}	if ((Istatus & IS_PA_TO_RX1) != 0) {		/* 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) != 0) {		/* 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) != 0) {		pPrt = &pAC->GIni.GP[MAC_1];		/* 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) != 0) {		pPrt = &pAC->GIni.GP[MAC_2];		/* 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) != 0) {		/* 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) != 0) {		/* 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) != 0) {		/* 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) != 0) {		/* 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) != 0) {		/* 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) != 0) {		/* 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) != 0) {		/* Test IRQs from PHY */		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {			pPrt = &pAC->GIni.GP[i];			if (pPrt->PState == SK_PRT_RESET) {				continue;			}			/* Read PHY Interrupt Status */			Rtv = SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);			if (Rtv == 0 && (PhyInt & PHY_M_DEF_MSK) != 0) {				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,					("Port %d PHY Int: 0x%04X\n", i, PhyInt));				SkPhyIsrGmac(pAC, IoC, i, PhyInt);			}		}	}	/* TWSI Ready interrupt */	if ((Istatus & IS_I2C_READY) != 0) {#ifdef SK_SLIM		/* clear TWSI IRQ */		SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);#else /* SK_SLIM */		SkI2cIsr(pAC, IoC);#endif /* !SK_SLIM */	}	/* SW forced interrupt */	if ((Istatus & IS_IRQ_SW) != 0) {		/* clear the software IRQ */		SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);	}	if ((Istatus & IS_LNK_SYNC_M1) != 0) {		/*		 * We do NOT need the Link Sync interrupt, because it shows		 * only a link going down.		 */		/* clear interrupt */		SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LNK_CLR_IRQ);	}	/* Check MAC after link sync counter */	if ((Istatus & IS_MAC1) != 0) {		/* IRQ from MAC 1 */		SkMacIrq(pAC, IoC, MAC_1);	}	if ((Istatus & IS_LNK_SYNC_M2) != 0) {		/*		 * 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), LNK_CLR_IRQ);	}	/* Check MAC after link sync counter */	if ((Istatus & IS_MAC2) != 0) {		/* IRQ from MAC 2 */		SkMacIrq(pAC, IoC, MAC_2);	}	/* Timer interrupt (served last) */	if ((Istatus & IS_TIMINT) != 0) {		/* check for HW Errors */		if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {			/* read the HW Error Interrupt source */			SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);			SkGeYuHwErr(pAC, IoC, RegVal32);		}		SkHwtIsr(pAC, IoC);	}}	/* SkGeYuSirqIsr */#endif /* !DISABLE_YUKON_I */#ifdef YUK2/****************************************************************************** * *	SkYuk2PortSirq() - Service HW Errors for specified port (Yukon-2 only) * * Description: handles the HW Error interrupts for a specific port. * * Returns: N/A */static void SkYuk2PortSirq(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O Context */SK_U32	IStatus,	/* Interrupt status word */int		Port)		/* Port Index (MAC_1 + n) */{	SK_EVPARA	Para;	int			Queue;	int			Rtv;	SK_U16		PhyInt;	if (Port == MAC_2) {		IStatus >>= 8;	}	/* Interrupt from PHY */	if ((IStatus & Y2_IS_IRQ_PHY1) != 0 &&		pAC->GIni.GP[Port].PState != SK_PRT_RESET) {		/* Read PHY Interrupt Status */		Rtv = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyInt);		if (Rtv == 0 && (PhyInt & PHY_M_DEF_MSK) != 0) {			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,				("Port %d PHY Int: 0x%04X\n", Port, PhyInt));			SkPhyIsrGmac(pAC, IoC, Port, PhyInt);		}	}	/* Interrupt from MAC */	if ((IStatus & Y2_IS_IRQ_MAC1) != 0) {		SkMacIrq(pAC, IoC, Port);	}	if ((IStatus & (Y2_IS_CHK_RX1 | Y2_IS_CHK_TXS1 | Y2_IS_CHK_TXA1)) != 0) {		if ((IStatus & Y2_IS_CHK_RX1) != 0) {			if (Port == MAC_1) {				Queue = Q_R1;				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E006,					SKERR_SIRQ_E006MSG);			}			else {				Queue = Q_R2;				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E007,					SKERR_SIRQ_E007MSG);			}			/* Clear IRQ */			SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);		}		if ((IStatus & Y2_IS_CHK_TXS1) != 0) {			if (Port == MAC_1) {				Queue = Q_XS1;				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E008,					SKERR_SIRQ_E008MSG);			}			else {				Queue = Q_XS2;				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E010,					SKERR_SIRQ_E010MSG);			}			/* Clear IRQ */			SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);		}		if ((IStatus & Y2_IS_CHK_TXA1) != 0) {			if (Port == MAC_1) {				Queue = Q_XA1;				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E009,					SKERR_SIRQ_E009MSG);			}			else {				Queue = Q_XA2;				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E011,					SKERR_SIRQ_E011MSG);			}			/* Clear IRQ */			SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);		}		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);	}}	/* SkYuk2PortSirq */#endif /* YUK2 *//****************************************************************************** * *	SkYuk2SirqIsr() - Special Interrupt Service Routine (Yukon-2 only) * * Description: handles all non data transfer specific interrupts (slow path) * * Returns: N/A */void SkYuk2SirqIsr(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O Context */SK_U32	Istatus)	/* Interrupt status word */{#ifdef YUK2	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_EVPARA	Para;	SK_U8		Byte;	SK_U16		Word;	SK_U32		DWord;	SK_U32		RegVal32;	/* Read register value */	pPrt = &pAC->GIni.GP[MAC_1];	/* HW Error indicated ? */	if (((Istatus & Y2_IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {		/* read the HW Error Interrupt source */		SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);		SkYuk2HwErr(pAC, IoC, RegVal32);	}	/* Interrupt from ASF Subsystem */	if ((Istatus & Y2_IS_ASF) != 0) {		/* clear IRQ */		/* later on clearing should be done in ASF ISR handler */		SK_IN8(IoC, B28_Y2_ASF_STAT_CMD, &Byte);		SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, Byte | Y2_ASF_CLR_HSTI);		/* Call IRQ handler in ASF Module */		/* TBD */	}	/* check IRQ from polling unit */	if ((Istatus & Y2_IS_POLL_CHK) != 0) {		/* Clear IRQ */		SK_OUT8(IoC, POLL_CTRL, PC_CLR_IRQ_CHK);		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E036,			SKERR_SIRQ_E036MSG);		Para.Para64 = 0;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);	}	/* TWSI Ready interrupt */	if ((Istatus & Y2_IS_TWSI_RDY) != 0) {		/* clear TWSI IRQ */		SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);		/* TWSI IRQ is Pause Packet IRQ */		if (HW_FEATURE(pAC, HWF_NEW_FLOW_CONTROL) &&			pPrt->PLinkSpeedUsed == (SK_U8)SK_LSPEED_STAT_1000MBPS) {			/* get number of Xmitted Pause Packets */			(void)SkGmMacStatistic(pAC, IoC, MAC_1, GM_TXF_MPAUSE, &DWord);			Word = (SK_U16)(DWord - pPrt->PPauseTxCnt);			/* save the value */			pPrt->PPauseTxCnt = DWord;#ifdef DEBUG			if (Word != 1) {				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,					("Pause Packets ON & OFF, %u\n", Word));			}#endif /* DEBUG */			if ((Word % 2) == 1) {				/* toggle Pause Packet (On/Off) */				pPrt->PPauseFlag ^= SK_TRUE;			}			/* get Rx GMAC FIFO Write Level */			SK_IN16(IoC, RX_GMF_WLEV, &Word);			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,				("Pause Packet IRQ, Level: 0x%03X, Cnt = %u, Pause %s\n",				 Word, DWord, pPrt->PPauseFlag ? "ON" : "off"));			if (pPrt->PPauseFlag) {				/* check if a stopped 30ms timer IRQ is pending */				if ((Istatus & Y2_IS_TIMINT) != 0) {					/* clear timer IRQ */					SK_OUT8(IoC, B2_TI_CTRL, TIM_CLR_IRQ);					/* to avoid handling this timer IRQ */					Istatus &= ~Y2_IS_TIMINT;				}				if (Word > (SK_U16)SK_ECU_LLPP) {					/* start a 30 ms timer */					Para.Para32[0] = 0;					SkTimerStart(pAC, IoC, &pPrt->PPauseTimer,						SK_PAUSE_PKT_TIME, SKGE_HWAC, SK_HWEV_PAUSE_PACKET,						Para);					SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,						("start timer\n"));				}			}			else if (pPrt->PPauseTimer.TmActive) {				/* stop the 30 ms timer */				SkTimerStop(pAC, IoC, &pPrt->PPauseTimer);				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,					("stop timer\n"));			}		}#ifndef SK_SLIM		else {			SkI2cIsr(pAC, IoC);		}#endif	}	/* SW forced interrupt */	if ((Istatus & Y2_IS_IRQ_SW) != 0) {		/* clear the software IRQ */		SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);	}	if ((Istatus & Y2_IS_L1_MASK) != 0) {		SkYuk2PortSirq(pAC, IoC, Istatus, MAC_1);	}	if ((Istatus & Y2_IS_L2_MASK) != 0) {		SkYuk2PortSirq(pAC, IoC, Istatus, MAC_2);	}	/* Timer interrupt (served last) */	if ((Istatus & Y2_IS_TIMINT) != 0) {		if (((Istatus & Y2_IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {			/* read the HW Error Interrupt source */			SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);			/* otherwise we would generate error log entries periodically */			RegVal32 &= pAC->GIni.GIValHwIrqMask;			if (RegVal32 != 0) {				SkYuk2HwErr(pAC, IoC, RegVal32);			}		}		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,			("Timer Int: 0x%08lX\n", Istatus));		SkHwtIsr(pAC, IoC);	}#endif /* YUK2 */}	/* SkYuk2SirqIsr *//****************************************************************************** * * SkGePortCheckUp() - Check if the link is up * * return: *	0	o.k. nothing needed *	1	Restart needed on this port *	2	Link came up */static int SkGePortCheckUp(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O Context */int		Port)		/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_BOOL		AutoNeg;	/* Is Auto-negotiation used ? */	int			Rtv;		/* Return value */	Rtv = SK_HW_PS_NONE;	pPrt = &pAC->GIni.GP[Port];

⌨️ 快捷键说明

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