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

📄 skgesirq.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			 * 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);}/****************************************************************************** * * SkGePortCheckUp - Implementing of the Workaround Errata # 2 * * return: *	0	o.k. nothing needed *	1	Restart needed on this port *	2	Link came up */int	SkGePortCheckUp(SK_AC	*pAC,		/* Adapters context */SK_IOC	IoC,		/* IO Context */int	Port)		/* Which port should be checked */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	pPrt = &pAC->GIni.GP[Port];	switch (pPrt->PhyType) {	case SK_PHY_XMAC:		return (SkGePortCheckUpXmac(pAC, IoC, Port));	case SK_PHY_BCOM:		return (SkGePortCheckUpBcom(pAC, IoC, Port));	case SK_PHY_LONE:		return (SkGePortCheckUpLone(pAC, IoC, Port));	case SK_PHY_NAT:		return (SkGePortCheckUpNat(pAC, IoC, Port));	}		return(SK_HW_PS_NONE) ;}/****************************************************************************** * * 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,		/* Adapters context */SK_IOC	IoC,		/* IO Context */int	Port)		/* Which port should be checked */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */	SK_U16		Isrc;		/* Interrupt source register */	SK_U32		GpReg;		/* General Purpose register value */	SK_U16		IsrcSum;	/* Interrupt source register sum */	SK_U16		LpAb;		/* Link Partner Ability */	SK_U16		ResAb;		/* Resolved Ability */	SK_U64		Shorts;		/* Short Event Counter */	unsigned int	Len;	SK_U8		NextMode;	/* Next AutoSensing Mode */	SK_U16		ExtStat;	/* Extended Status Register */	int		Done;	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 ports 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));				/*				 * We now need to reinitialize the PrevSHorts				 * counter.				 */				Len = sizeof(SK_U64);				SkPnmiGetVar(pAC, IoC,					OID_SKGE_STAT_RX_SHORTS,					(char *) &Shorts,					&Len,					(SK_U32) SK_PNMI_PORT_PHYS2INST(Port));				pPrt->PPrevShorts = Shorts;				pAC->GIni.GP[Port].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 lionk is now o.k.				 */				pAC->GIni.GP[Port].PLinkResCt ++;				pPrt->PAutoNegTimeOut = 0;				if (pAC->GIni.GP[Port].PLinkResCt <					SK_MAX_LRESTART) {					return(SK_HW_PS_RESTART) ;				}				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,					("Do NOT restart on Port %d %x %x\n",					Port, Isrc, IsrcSum));				pAC->GIni.GP[Port].PLinkResCt = 0;			} 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) == XM_IS_INP_ASS) {			XM_IN16(IoC,Port,XM_ISRC, &Isrc) ;			IsrcSum |= Isrc;			if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) {				XM_IN16(IoC,Port,XM_ISRC, &Isrc) ;				IsrcSum |= Isrc;				if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) {					pPrt->PLinkBroken = SK_TRUE ;					/*					 * Re-Init Link partner Autoneg flag					 */					pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;					SK_DBG_MSG(pAC,SK_DBGMOD_HWM,					   SK_DBGCAT_IRQ,					   ("Link broken Port %d\n",						 Port));					/* cable removed-> reinit Sensemode */					/* Init default sense mode */					SkHWInitDefSense(pAC, IoC, Port);					return(SK_HW_PS_RESTART) ;				}			}		} else {			SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);			if (SkGePortCheckShorts(pAC, IoC, Port) ==				SK_HW_PS_RESTART) {				return(SK_HW_PS_RESTART) ;			}		}	}	/*	 * here we usually can check whether the link is in sync and	 * autonegotiation is done.	 */	XM_IN32(IoC,Port,XM_GP_PORT, &GpReg) ;	XM_IN16(IoC,Port,XM_ISRC, &Isrc) ;	IsrcSum |= Isrc;	SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);	if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {		if ((GpReg & XM_GP_INP_ASS) == 0) {			/*			 * Save Autonegotiation Done interrupt only if link 			 * is in sync			 */			pPrt->PIsave = (SK_U16) (IsrcSum & (XM_IS_AND));		}#ifdef	DEBUG		if (pPrt->PIsave & (XM_IS_AND)) {			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,				("AutoNeg done rescheduled Port %d\n", Port));		}#endif		return(SK_HW_PS_NONE) ;	}	if (AutoNeg) {		if (IsrcSum & XM_IS_AND) {			SkHWLinkUp(pAC, IoC, Port) ;			Done = SkXmAutoNegDone(pAC,IoC,Port);			if (Done != SK_AND_OK) {				/* Get PHY parameters, for debuging only */				PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_LP,					&LpAb);				PHY_READ(IoC, pPrt, Port, PHY_XMAC_RES_ABI,					&ResAb);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,					("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",					 Port, LpAb, ResAb));									/* Try next possible mode */				NextMode = SkHWSenseGetNext(pAC, IoC, Port);				SkHWLinkDown(pAC, IoC, Port) ;				if (Done == SK_AND_DUP_CAP) {					/* GoTo next mode */					SkHWSenseSetNext(pAC, IoC, Port,						NextMode);				}				return(SK_HW_PS_RESTART) ;			} else {				/*				 * Dummy Read extended status to prevent				 * extra link down/ups				 * (clear Page Received bit if set)				 */				PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_EXP, &ExtStat);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,					("AutoNeg done Port %d\n", Port));				return(SK_HW_PS_LINK) ;			}		} 				/*		 * AutoNeg not done, but HW link is up. Check for timeouts		 */		pPrt->PAutoNegTimeOut ++;		if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {			/*			 * Timeout occured.			 * What do we need now?			 */			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,				SK_DBGCAT_IRQ,				("AutoNeg timeout Port %d\n",				 Port));			if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&				pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {				/*				 * Timeout occured				 * Set Link manually up.				 */				SkHWSenseSetNext(pAC, IoC, Port,					SK_LMODE_FULL);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,					SK_DBGCAT_IRQ,					("Set manual full duplex Port %d\n",					 Port));			}			/*			 * Do the restart			 */			return(SK_HW_PS_RESTART) ;		}	} else {		/*		 * Link is up and we don't need more.		 */#ifdef	DEBUG		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,				("ERROR: Lipa auto detected on port %d\n",				Port));		}#endif		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,			("Link sync(GP), Port %d\n", Port));		SkHWLinkUp(pAC, IoC, Port) ;		return(SK_HW_PS_LINK) ;	}	return(SK_HW_PS_NONE) ;}/****************************************************************************** * * SkGePortCheckUpBcom - Check, if the link is up * * return: *	0	o.k. nothing needed *	1	Restart needed on this port *	2	Link came up */static int	SkGePortCheckUpBcom(SK_AC	*pAC,		/* Adapters context */SK_IOC	IoC,		/* IO Context */int	Port)		/* Which port should be checked */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */	SK_U16		Isrc;		/* Interrupt source register */	SK_U16		LpAb;		/* Link Partner Ability */	SK_U16		ExtStat;	/* Extended Status Register */	SK_U16		PhyStat;	/* Phy Status Register */	int		Done;	SK_U16		ResAb;	SK_U16		SWord;	pPrt = &pAC->GIni.GP[Port];	/* Check for No HCD Link events (#10523) */	PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &Isrc);	if ((Isrc & PHY_B_IS_NO_HDCL) == PHY_B_IS_NO_HDCL) {		/* Workaround BCOM Errata */		/* enable and disable Loopback mode if NO HCD occurs */		PHY_READ(IoC, pPrt, Port, PHY_BCOM_CTRL, &SWord);		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, SWord | PHY_CT_LOOP);		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, SWord & ~PHY_CT_LOOP);		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,			("No HCD Link event, Port %d\n", Port));	}	PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat);	if (pPrt->PHWLinkUp) {		return(SK_HW_PS_NONE) ;	}	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;	}	/*	 * here we usually can check whether the link is in sync and	 * autonegotiation is done.	 */	XM_IN16(IoC, Port, XM_ISRC, &Isrc) ;	PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat);	SkXmAutoNegLipaBcom(pAC, IoC, Port, PhyStat);		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("AutoNeg:%d, PhyStat: %Xh.\n", AutoNeg, PhyStat));	PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);	if ((PhyStat & PHY_ST_LSYNC) == 0) {		if (ResAb & (PHY_B_1000S_MSF)) {			/* Error */			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,				("Master/Slave Fault port %d\n", Port));			pPrt->PAutoNegFail = SK_TRUE;			pPrt->PMSStatus = SK_MS_STAT_FAULT;			return (SK_AND_OTHER);		}		return (SK_HW_PS_NONE);	}		if (ResAb & (PHY_B_1000S_MSF)) {		/* Error */		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,			("Master/Slave Fault port %d\n", Port));		pPrt->PAutoNegFail = SK_TRUE;		pPrt->PMSStatus = SK_MS_STAT_FAULT;		return (SK_AND_OTHER);	} else if (ResAb & PHY_B_1000S_MSR) {		pPrt->PMSStatus = SK_MS_STAT_MASTER;	} else {		pPrt->PMSStatus = SK_MS_STAT_SLAVE;	}		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("AutoNeg:%d, PhyStat: %Xh.\n", AutoNeg, PhyStat));	if (AutoNeg) {		if (PhyStat & PHY_ST_AN_OVER) {			SkHWLinkUp(pAC, IoC, Port);			Done = SkXmAutoNegDone(pAC,IoC,Port);			if (Done != SK_AND_OK) {				/* Get PHY parameters, for debuging only */				PHY_READ(IoC, pPrt, Port,					PHY_BCOM_AUNE_LP,					&LpAb);				PHY_READ(IoC, pPrt, Port,					PHY_BCOM_1000T_STAT,					&ExtStat);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,					("AutoNeg FAIL Port %d (LpAb %x, "					"1000TStat %x)\n",					 Port, LpAb, ExtStat));				return(SK_HW_PS_RESTART) ;			} else {				/*				 * Dummy Read interrupt status to prevent				 * extra link down/ups				 */				PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT,					&ExtStat);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,					("AutoNeg done Port %d\n", Port));				return(SK_HW_PS_LINK) ;			}		} 	} else {		/*		 * Link is up and we don't need more.		 */#ifdef	DEBUG		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,				("ERROR: Lipa auto detected on port %d\n",				Port));		}#endif#if 0		PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);		if (ResAb & (PHY_B_1000S_MSF)) {			/* Error */			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,				("Master/Slave Fault port %d\n", Port));			pPrt->PAutoNegFail = SK_TRUE;			pPrt->PMSStatus = SK_MS_STAT_FAULT;			return (SK_AND_OTHER);		} else if (ResAb & PHY_B_1000S_MSR) {			pPrt->PMSStatus = SK_MS_STAT_MASTER ;		} else {			pPrt->PMSStatus = SK_MS_STAT_SLAVE ;		}#endif	/* 0 */		/*		 * Dummy Read interrupt status to prevent		 * extra link down/ups		 */		PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &ExtStat);				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,			("Link sync(GP), Port %d\n", Port));		SkHWLinkUp(pAC, IoC, Port) ;		return(SK_HW_PS_LINK) ;	}	return(SK_HW_PS_NONE) ;}

⌨️ 快捷键说明

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