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

📄 skgesirq.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif /* DEBUG */	if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {		return(SK_HW_PS_NONE);	}		if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||		(PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {		/* Downshift detected */		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);				Para.Para64 = Port;		SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,			("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));	}	pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?		SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;		pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);		if (AutoNeg) {		/* Auto-Negotiation Over ? */		if ((PhyStat & PHY_ST_AN_OVER) != 0) {						SkHWLinkUp(pAC, IoC, Port);						Done = SkMacAutoNegDone(pAC, IoC, Port);						if (Done != SK_AND_OK) {				return(SK_HW_PS_RESTART);			}						return(SK_HW_PS_LINK);		}	}	else {	/* !AutoNeg */		/* 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 /* DEBUG */		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,			("Link sync, Port %d\n", Port));		SkHWLinkUp(pAC, IoC, Port);				return(SK_HW_PS_LINK);	}	return(SK_HW_PS_NONE);}	/* SkGePortCheckUpGmac */#endif /* YUKON */#ifdef OTHER_PHY/****************************************************************************** * * SkGePortCheckUpLone() - Check if the link is up on Level One PHY * * return: *	0	o.k. nothing needed *	1	Restart needed on this port *	2	Link came up */static int SkGePortCheckUpLone(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* IO Context */int		Port,		/* Which port should be checked */SK_BOOL	AutoNeg)	/* Is Auto-negotiation used ? */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	int			Done;	SK_U16		Isrc;		/* Interrupt source register */	SK_U16		LpAb;		/* Link Partner Ability */	SK_U16		ExtStat;	/* Extended Status Register */	SK_U16		PhyStat;	/* Phy Status Register */	SK_U16		StatSum;	SK_U8		NextMode;	/* Next AutoSensing Mode */	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PHWLinkUp) {		return(SK_HW_PS_NONE);	}	StatSum = pPrt->PIsave;	pPrt->PIsave = 0;	/*	 * here we usually can check whether the link is in sync and	 * auto-negotiation is done.	 */	SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);	StatSum |= PhyStat;	SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);		if ((PhyStat & PHY_ST_LSYNC) == 0) {		/* Save Auto-negotiation Done bit */		pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);#ifdef DEBUG		if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,				("AutoNeg done rescheduled Port %d\n", Port));		}#endif /* DEBUG */		return(SK_HW_PS_NONE);	}	if (AutoNeg) {		if ((StatSum & PHY_ST_AN_OVER) != 0) {			SkHWLinkUp(pAC, IoC, Port);			Done = SkMacAutoNegDone(pAC, IoC, Port);			if (Done != SK_AND_OK) {				/* Get PHY parameters, for debugging only */				SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);				SkXmPhyRead(pAC, IoC, Port, PHY_LONE_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));									/* 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 interrupt status to prevent				 * extra link down/ups				 */				SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);				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 */			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) {				/* 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 /* DEBUG */		/*		 * Dummy Read interrupt status to prevent		 * extra link down/ups		 */		SkXmPhyRead(pAC, IoC, Port, PHY_LONE_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);}	/* SkGePortCheckUpLone *//****************************************************************************** * * SkGePortCheckUpNat() - Check if the link is up on National PHY * * return: *	0	o.k. nothing needed *	1	Restart needed on this port *	2	Link came up */static int SkGePortCheckUpNat(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* IO Context */int		Port,		/* Which port should be checked */SK_BOOL	AutoNeg)	/* Is Auto-negotiation used ? */{	/* todo: National */	return(SK_HW_PS_NONE);}	/* SkGePortCheckUpNat */#endif /* OTHER_PHY *//****************************************************************************** * *	SkGeSirqEvent() - Event Service Routine * * Description: * * Notes: */int	SkGeSirqEvent(SK_AC		*pAC,		/* Adapter Context */SK_IOC		IoC,		/* Io Context */SK_U32		Event,		/* Module specific Event */SK_EVPARA	Para)		/* Event specific Parameter */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_U32		Port;	SK_U32		Val32;	int			PortStat;	SK_U8		Val8;#ifdef GENESIS	SK_U64		Octets;#endif /* GENESIS */	Port = Para.Para32[0];	pPrt = &pAC->GIni.GP[Port];	switch (Event) {	case SK_HWEV_WATIM:		if (pPrt->PState == SK_PRT_RESET) {					PortStat = SK_HW_PS_NONE;		}		else {			/* Check whether port came up */			PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);		}		switch (PortStat) {		case SK_HW_PS_RESTART:			if (pPrt->PHWLinkUp) {				/* Set Link to down */				SkHWLinkDown(pAC, IoC, (int)Port);				/*				 * Signal directly to RLMT to ensure correct				 * sequence of SWITCH and RESET event.				 */				SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);			}			/* Restart needed */			SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);			break;		case SK_HW_PS_LINK:			/* Signal to RLMT */			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);			break;		}				/* Start again the check Timer */		if (pPrt->PHWLinkUp) {			Val32 = SK_WA_ACT_TIME;		}		else {			Val32 = SK_WA_INA_TIME;		}		/* Todo: still needed for non-XMAC PHYs??? */		/* Start workaround Errata #2 timer */		SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,			SKGE_HWAC, SK_HWEV_WATIM, Para);		break;	case SK_HWEV_PORT_START:		if (pPrt->PHWLinkUp) {			/*			 * Signal directly to RLMT to ensure correct			 * sequence of SWITCH and RESET event.			 */			SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);		}		SkHWLinkDown(pAC, IoC, (int)Port);		/* Schedule Port RESET */		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);		/* Start workaround Errata #2 timer */		SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,			SKGE_HWAC, SK_HWEV_WATIM, Para);		break;	case SK_HWEV_PORT_STOP:		if (pPrt->PHWLinkUp) {			/*			 * Signal directly to RLMT to ensure correct			 * sequence of SWITCH and RESET event.			 */			SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);		}		/* Stop Workaround Timer */		SkTimerStop(pAC, IoC, &pPrt->PWaTimer);		SkHWLinkDown(pAC, IoC, (int)Port);		break;	case SK_HWEV_UPDATE_STAT:		/* We do NOT need to update any statistics */		break;	case SK_HWEV_CLEAR_STAT:		/* We do NOT need to clear any statistics */		for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {			pPrt->PPrevRx = 0;			pPrt->PPrevFcs = 0;			pPrt->PPrevShorts = 0;		}		break;	case SK_HWEV_SET_LMODE:		Val8 = (SK_U8)Para.Para32[1];		if (pPrt->PLinkModeConf != Val8) {			/* Set New link mode */			pPrt->PLinkModeConf = Val8;			/* Restart Port */			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);		}		break;	case SK_HWEV_SET_FLOWMODE:		Val8 = (SK_U8)Para.Para32[1];		if (pPrt->PFlowCtrlMode != Val8) {			/* Set New Flow Control mode */			pPrt->PFlowCtrlMode = Val8;			/* Restart Port */			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);		}		break;	case SK_HWEV_SET_ROLE:		/* not possible for fiber */		if (!pAC->GIni.GICopperType) {			break;		}		Val8 = (SK_U8)Para.Para32[1];		if (pPrt->PMSMode != Val8) {			/* Set New Role (Master/Slave) mode */			pPrt->PMSMode = Val8;			/* Restart Port */			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);		}		break;	case SK_HWEV_SET_SPEED:		if (pPrt->PhyType != SK_PHY_MARV_COPPER) {			break;		}		Val8 = (SK_U8)Para.Para32[1];		if (pPrt->PLinkSpeed != Val8) {			/* Set New Speed parameter */			pPrt->PLinkSpeed = Val8;			/* Restart Port */			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);		}		break;#ifdef GENESIS	case SK_HWEV_HALFDUP_CHK:		if (pAC->GIni.GIGenesis) {			/*			 * half duplex hangup workaround.			 * See packet arbiter timeout interrupt for description			 */			pPrt->HalfDupTimerActive = SK_FALSE;			if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||				pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {#ifdef XXX				Len = sizeof(SK_U64);				SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,					&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),					pAC->Rlmt.Port[Port].Net->NetNumber);#endif /* XXX */				/* Snap statistic counters */				(void)SkXmUpdateStats(pAC, IoC, Port);				(void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);				Octets = (SK_U64)Val32 << 32;								(void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);				Octets += Val32;								if (pPrt->LastOctets == Octets) {					/* Tx hanging, a FIFO flush restarts it */					SkMacFlushTxFifo(pAC, IoC, Port);				}			}		}		break;#endif /* GENESIS */		default:		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);		break;	}	return(0);}	/* SkGeSirqEvent */#ifdef GENESIS/****************************************************************************** * *	SkPhyIsrBcom() - PHY interrupt service routine * * Description: handles all interrupts from BCom PHY * * Returns: N/A */static void SkPhyIsrBcom(SK_AC		*pAC,		/* Adapter Context */SK_IOC		IoC,		/* Io Context */int			Port,		/* Port Num = PHY Num */SK_U16		IStatus)	/* Interrupt Status */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_EVPARA	Para;	pPrt = &pAC->GIni.GP[Port];	if ((IStatus & PHY_B_IS_PSE) != 0) {		/* Incorrectable pair swap error */		SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,			SKERR_SIRQ_E022MSG);	}		if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {		SkHWLinkDown(pAC, IoC, Port);		Para.Para32[0] = (SK_U32)Port;		/* Signal to RLMT */		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);		/* Start workaround Errata #2 timer */		SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,			SKGE_HWAC, SK_HWEV_WATIM, Para);	}}	/* SkPhyIsrBcom */#endif /* GENESIS */#ifdef YUKON/****************************************************************************** * *	SkPhyIsrGmac() - PHY interrupt service routine * * Description: handles all interrupts from Marvell PHY * * Returns: N/A */static void SkPhyIsrGmac(SK_AC		*pAC,		/* Adapter Context */SK_IOC		IoC,		/* Io Context */int			Port,		/* Port Num = PHY Num */SK_U16		IStatus)	/* Interrupt Status */{	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */	SK_EVPARA	Para;	SK_U16		Word;	pPrt = &pAC->GIni.GP[Port];	if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {		SkHWLinkDown(pAC, IoC, Port);		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,			("AutoNeg.Adv: 0x%04X\n", Word));				/* Set Auto-negotiation advertisement */		if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {			/* restore Asymmetric Pause bit */			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,				(SK_U16)(Word | PHY_M_AN_ASP));		}				Para.Para32[0] = (SK_U32)Port;		/* Signal to RLMT */		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);	}		if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {		/* Auto-Negotiation Error */		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);	}		if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {		/* FIFO Overflow/Underrun Error */		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);	}	}	/* SkPhyIsrGmac */#endif /* YUKON */#ifdef OTHER_PHY/****************************************************************************** * *	SkPhyIsrLone() - PHY interrupt service routine * * Description: handles all interrupts from LONE PHY * * Returns: N/A */static void SkPhyIsrLone(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* Io Context */int		Port,		/* Port Num = PHY Num */SK_U16	IStatus)	/* Interrupt Status */{	SK_EVPARA	Para;	if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {				SkHWLinkDown(pAC, IoC, Port);		Para.Para32[0] = (SK_U32)Port;		/* Signal to RLMT */		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);	}}	/* SkPhyIsrLone */#endif /* OTHER_PHY *//* End of File */

⌨️ 快捷键说明

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