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

📄 skgesirq.c

📁 D-link 千兆网卡 dge530t for linux 驱动,完全基于LINUX/UNIX下的.
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if ((Istatus & IS_PA_TO_TX2) != 0) {				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) != 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;			}						if (pAC->GIni.GIGenesis) {								switch (pPrt->PhyType) {								case SK_PHY_XMAC:					break;								case SK_PHY_BCOM:					SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);						if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {						SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,							("Port %d Bcom Int: 0x%04X\n",							i, PhyInt));						SkPhyIsrBcom(pAC, IoC, i, PhyInt);					}					break;#ifdef OTHER_PHY				case SK_PHY_LONE:					SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);										if ((PhyInt & PHY_L_DEF_MSK) != 0) {						SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,							("Port %d Lone Int: %x\n",							i, PhyInt));						SkPhyIsrLone(pAC, IoC, i, PhyInt);					}					break;#endif /* OTHER_PHY */				}			}			else {				SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);				if ((PhyInt & PHY_M_DEF_MSK) != 0) {					SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,						("Port %d Marv Int: 0x%04X\n",						i, PhyInt));					SkPhyIsrGmac(pAC, IoC, i, PhyInt);				}			}		}	}	/* I2C Ready interrupt */	if ((Istatus & IS_I2C_READY) != 0) {		SkI2cIsr(pAC, IoC);	}	/* 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		 * 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) != 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), LED_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);			SkGeHwErr(pAC, IoC, RegVal32);		}		SkHwtIsr(pAC, IoC);	}}	/* SkGeSirqIsr *//****************************************************************************** * * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2 * * return: *	0	o.k. nothing needed *	1	Restart needed on this port */static int SkGePortCheckShorts(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* IO Context */int		Port)		/* Which port should be checked */{	SK_U32		Shorts;			/* Short Event Counter */	SK_U32		CheckShorts;	/* Check value for Short Event Counter */	SK_U64		RxCts;			/* Rx Counter (packets on network) */	SK_U32		RxTmp;			/* Rx temp. Counter */	SK_U32		FcsErrCts;		/* FCS Error Counter */	SK_GEPORT	*pPrt;			/* GIni Port struct pointer */	int			Rtv;			/* Return value */	int			i;	pPrt = &pAC->GIni.GP[Port];	/* Default: no action */	Rtv = SK_HW_PS_NONE;	(void)SkXmUpdateStats(pAC, IoC, Port);	/* Extra precaution: check for short Event counter */	(void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);	/*	 * Read Rx counter (packets seen on the network and not necessarily	 * really received.	 */	RxCts = 0;	for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {		(void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);		RxCts += (SK_U64)RxTmp;	}	/* On default: check shorts against zero */	CheckShorts = 0;	/* 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;		(void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);				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 *//****************************************************************************** * * 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,		/* IO Context */int		Port)		/* Which port should be checked */{	if (pAC->GIni.GIGenesis) {		switch (pAC->GIni.GP[Port].PhyType) {		case SK_PHY_XMAC:			return(SkGePortCheckUpXmac(pAC, IoC, Port));		case SK_PHY_BCOM:			return(SkGePortCheckUpBcom(pAC, IoC, Port));#ifdef OTHER_PHY		case SK_PHY_LONE:			return(SkGePortCheckUpLone(pAC, IoC, Port));		case SK_PHY_NAT:			return(SkGePortCheckUpNat(pAC, IoC, Port));#endif /* OTHER_PHY */		default:			return(SK_HW_PS_NONE);		}	}	else {		return(SkGePortCheckUpGmac(pAC, IoC, Port));	}}	/* SkGePortCheckUp *//****************************************************************************** * * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2 * * return: *	0	o.k. nothing needed *	1	Restart needed on this port *	2	Link came up */static int SkGePortCheckUpXmac(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* IO Context */int		Port)		/* Which port should be checked */{	SK_U32		Shorts;		/* Short Event Counter */	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	int			Done;	SK_U32		GpReg;		/* General Purpose register value */	SK_U16		Isrc;		/* Interrupt source register */	SK_U16		IsrcSum;	/* Interrupt source register sum */	SK_U16		LpAb;		/* Link Partner Ability */	SK_U16		ResAb;		/* Resolved Ability */	SK_U16		ExtStat;	/* Extended Status Register */	SK_BOOL		AutoNeg;	/* Is Auto-negotiation used ? */	SK_U8		NextMode;	/* Next AutoSensing Mode */	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PHWLinkUp) {		if (pPrt->PhyType != SK_PHY_XMAC) {			return(SK_HW_PS_NONE);		}		else {			return(SkGePortCheckShorts(pAC, IoC, Port));		}	}	IsrcSum = pPrt->PIsave;	pPrt->PIsave = 0;	/* Now wait for each port's link */	if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {		AutoNeg = SK_FALSE;	}	else {		AutoNeg = SK_TRUE;	}	if (pPrt->PLinkBroken) {		/* Link was broken */		XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);		if ((GpReg & XM_GP_INP_ASS) == 0) {			/* The Link is in sync */			XM_IN16(IoC, Port, XM_ISRC, &Isrc);			IsrcSum |= Isrc;			SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);						if ((Isrc & XM_IS_INP_ASS) == 0) {				/* It has been in sync since last time */				/* Restart the PORT */				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,					("Link in sync Restart Port %d\n", Port));				(void)SkXmUpdateStats(pAC, IoC, Port);				/* We now need to reinitialize the PrevShorts counter */				(void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);				pPrt->PPrevShorts = Shorts;				pPrt->PLinkBroken = SK_FALSE;				/*				 * Link Restart Workaround:				 *  it may be possible that the other Link side				 *  restarts its link as well an we detect				 *  another LinkBroken. To prevent this				 *  happening we check for a maximum number				 *  of consecutive restart. If those happens,				 *  we do NOT restart the active link and				 *  check whether the link is now o.k.				 */				pPrt->PLinkResCt++;								pPrt->PAutoNegTimeOut = 0;				if (pPrt->PLinkResCt < SK_MAX_LRESTART) {					return(SK_HW_PS_RESTART);				}				pPrt->PLinkResCt = 0;								SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,					("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));			}			else {				pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);								SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,					("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));				/* Do nothing more if link is broken */				return(SK_HW_PS_NONE);			}		}		else {			/* Do nothing more if link is broken */			return(SK_HW_PS_NONE);		}	}	else {		/* Link was not broken, check if it is */		XM_IN16(IoC, Port, XM_ISRC, &Isrc);		IsrcSum |= Isrc;		if ((Isrc & XM_IS_INP_ASS) != 0) {

⌨️ 快捷键说明

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