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

📄 skgeinit.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
 *	Dir =	SK_STOP_TX 	Stops the transmit path only and resets the MAC. *				The receive queue is still active and *				the pending Rx frames may be still transferred *				into the RxD. *		SK_STOP_RX	Stop the receive path. The tansmit path *				has to be stopped once before. *		SK_STOP_ALL	SK_STOP_TX + SK_STOP_RX * *	RstMode = SK_SOFT_RST	Resets the MAC. The PHY is still alive. *			SK_HARD_RST	Resets the MAC and the PHY. * * Example: *	1) A Link Down event was signaled for a port. Therefore the activity *	of this port should be stopped and a hardware reset should be issued *	to enable the workaround of XMAC Errata #2. But the received frames *	should not be discarded. *		... *		SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST); *		(transfer all pending Rx frames) *		SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST); *		... * *	2) An event was issued which request the driver to switch *	the 'virtual active' link to an other already active port *	as soon as possible. The frames in the receive queue of this *	port may be lost. But the PHY must not be reset during this *	event. *		... *		SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST); *		... * * Extended Description: *	If SK_STOP_TX is set, *		o disable the MAC's receive and transmitter to prevent *		  from sending incomplete frames *		o stop the port's transmit queues before terminating the *		  BMUs to prevent from performing incomplete PCI cycles *		  on the PCI bus *		- The network Rx and Tx activity and PCI Tx transfer is *		  disabled now. *		o reset the MAC depending on the RstMode *		o Stop Interval Timer and Limit Counter of Tx Arbiter, *		  also disable Force Sync bit and Enable Alloc bit. *		o perform a local reset of the port's Tx path *			- reset the PCI FIFO of the async Tx queue *			- reset the PCI FIFO of the sync Tx queue *			- reset the RAM Buffer async Tx queue *			- reset the RAM Buffer sync Tx queue *			- reset the MAC Tx FIFO *		o switch Link and Tx LED off, stop the LED counters * *	If SK_STOP_RX is set, *		o stop the port's receive queue *		- The path data transfer activity is fully stopped now. *		o perform a local reset of the port's Rx path *			- reset the PCI FIFO of the Rx queue *			- reset the RAM Buffer receive queue *			- reset the MAC Rx FIFO *		o switch Rx LED off, stop the LED counter * *	If all ports are stopped, *		o reset the RAM Interface. * * Notes: *	o This function may be called during the driver states RESET_PORT and *	  SWITCH_PORT. */void SkGeStopPort(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* I/O context */int		Port,	/* port to stop (MAC_1 + n) */int		Dir,	/* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */int		RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */{#ifndef SK_DIAG	SK_EVPARA Para;#endif /* !SK_DIAG */	SK_GEPORT *pPrt;	SK_U32	DWord;	SK_U32	XsCsr;	SK_U32	XaCsr;	SK_U64	ToutStart;	int		i;	int		ToutCnt;	pPrt = &pAC->GIni.GP[Port];	if ((Dir & SK_STOP_TX) != 0) {		/* disable receiver and transmitter */		SkMacRxTxDisable(pAC, IoC, Port);				/* stop both transmit queues */		/*		 * If the BMU is in the reset state CSR_STOP will terminate		 * immediately.		 */		SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);		SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);		ToutStart = SkOsGetTime(pAC);		ToutCnt = 0;		do {			/*			 * Clear packet arbiter timeout to make sure			 * this loop will terminate.			 */			SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?				PA_CLR_TO_TX1 : PA_CLR_TO_TX2));			/*			 * If the transfer stucks at the MAC the STOP command will not			 * terminate if we don't flush the XMAC's transmit FIFO !			 */			SkMacFlushTxFifo(pAC, IoC, Port);			XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);			XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);			if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {				/*				 * Timeout of 1/18 second reached.				 * This needs to be checked at 1/18 sec only.				 */				ToutCnt++;				if (ToutCnt > 1) {					/* Might be a problem when the driver event handler					 * calls StopPort again. XXX.					 */					/* Fatal Error, Loop aborted */					SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,						SKERR_HWI_E018MSG);#ifndef SK_DIAG					Para.Para64 = Port;					SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);#endif /* !SK_DIAG */					return;				}				/*				 * Cache incoherency workaround: Assume a start command				 * has been lost while sending the frame.				 */				ToutStart = SkOsGetTime(pAC);				if ((XsCsr & CSR_STOP) != 0) {					SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);				}				if ((XaCsr & CSR_STOP) != 0) {					SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);				}			}			/*			 * Because of the ASIC problem report entry from 21.08.1998 it is			 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.			 */		} while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||				 (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);		/* Reset the MAC depending on the RstMode */		if (RstMode == SK_SOFT_RST) {			SkMacSoftRst(pAC, IoC, Port);		}		else {			SkMacHardRst(pAC, IoC, Port);		} 				/* Disable Force Sync bit and Enable Alloc bit */		SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),			TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);				/* Stop Interval Timer and Limit Counter of Tx Arbiter */		SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);		SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);		/* Perform a local reset of the port's Tx path */		/* Reset the PCI FIFO of the async Tx queue */		SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);		/* Reset the PCI FIFO of the sync Tx queue */		SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);		/* Reset the RAM Buffer async Tx queue */		SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);		/* Reset the RAM Buffer sync Tx queue */		SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);				/* Reset Tx MAC FIFO */#ifdef GENESIS		if (pAC->GIni.GIGenesis) {			/* Note: MFF_RST_SET does NOT reset the XMAC ! */			SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);			/* switch Link and Tx LED off, stop the LED counters */			/* Link LED is switched off by the RLMT and the Diag itself */			SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);		}#endif /* GENESIS */	#ifdef YUKON		if (pAC->GIni.GIYukon) {			/* Reset TX MAC FIFO */			SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);		}#endif /* YUKON */	}	if ((Dir & SK_STOP_RX) != 0) {		/*		 * The RX Stop Command will not terminate if no buffers		 * are queued in the RxD ring. But it will always reach		 * the Idle state. Therefore we can use this feature to		 * stop the transfer of received packets.		 */		/* stop the port's receive queue */		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);				i = 100;		do {			/*			 * Clear packet arbiter timeout to make sure			 * this loop will terminate			 */			SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?				PA_CLR_TO_RX1 : PA_CLR_TO_RX2));			DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);			/* timeout if i==0 (bug fix for #10748) */			if (--i == 0) {				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,					SKERR_HWI_E024MSG);				break;			}			/*			 * because of the ASIC problem report entry from 21.08.98			 * it is required to wait until CSR_STOP is reset and			 * CSR_SV_IDLE is set.			 */		} while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);		/* The path data transfer activity is fully stopped now */		/* Perform a local reset of the port's Rx path */		 /*	Reset the PCI FIFO of the Rx queue */		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);		/* Reset the RAM Buffer receive queue */		SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);		/* Reset Rx MAC FIFO */#ifdef GENESIS		if (pAC->GIni.GIGenesis) {						SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);			/* switch Rx LED off, stop the LED counter */			SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);		}#endif /* GENESIS */	#ifdef YUKON		if (pAC->GIni.GIYukon) {			/* Reset Rx MAC FIFO */			SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);		}#endif /* YUKON */	}}	/* SkGeStopPort *//****************************************************************************** * *	SkGeInit0() - Level 0 Initialization * * Description: *	- Initialize the BMU address offsets * * Returns: *	nothing */static void SkGeInit0(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC)		/* IO context */{	int i;	SK_GEPORT *pPrt;	for (i = 0; i < SK_MAX_MACS; i++) {		pPrt = &pAC->GIni.GP[i];		pPrt->PState = SK_PRT_RESET;		pPrt->PRxQOff = QOffTab[i].RxQOff;		pPrt->PXsQOff = QOffTab[i].XsQOff;		pPrt->PXaQOff = QOffTab[i].XaQOff;		pPrt->PCheckPar = SK_FALSE;		pPrt->PIsave = 0;		pPrt->PPrevShorts = 0;		pPrt->PLinkResCt = 0;		pPrt->PAutoNegTOCt = 0;		pPrt->PPrevRx = 0;		pPrt->PPrevFcs = 0;		pPrt->PRxLim = SK_DEF_RX_WA_LIM;		pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;		pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS;		pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS;		pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN;		pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE;		pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;		pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |			SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;		pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;		pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;		pPrt->PMSCap = 0;		pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO;		pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET;		pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;		pPrt->PAutoNegFail = SK_FALSE;		pPrt->PHWLinkUp = SK_FALSE;		pPrt->PLinkBroken = SK_TRUE; /* See WA code */		pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;		pPrt->PMacColThres = TX_COL_DEF;		pPrt->PMacJamLen = TX_JAM_LEN_DEF;		pPrt->PMacJamIpgVal	= TX_JAM_IPG_DEF;		pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;		pPrt->PMacIpgData = IPG_DATA_DEF;		pPrt->PMacLimit4 = SK_FALSE;	}	pAC->GIni.GIPortUsage = SK_RED_LINK;	pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;	pAC->GIni.GIValIrqMask = IS_ALL_MSK;}	/* SkGeInit0*/#ifdef SK_PCI_RESET/****************************************************************************** * *	SkGePciReset() - Reset PCI interface * * Description: *	o Read PCI configuration. *	o Change power state to 3. *	o Change power state to 0. *	o Restore PCI configuration. * * Returns: *	0:	Success. *	1:	Power state could not be changed to 3. */static int SkGePciReset(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC)		/* IO context */{	int		i;	SK_U16	PmCtlSts;	SK_U32	Bp1;	SK_U32	Bp2;	SK_U16	PciCmd;	SK_U8	Cls;	SK_U8	Lat;	SK_U8	ConfigSpace[PCI_CFG_SIZE];	/*	 * Note: Switching to D3 state is like a software reset.	 *		 Switching from D3 to D0 is a hardware reset.	 *		 We have to save and restore the configuration space.	 */	for (i = 0; i < PCI_CFG_SIZE; i++) {		SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]);	}	/* We know the RAM Interface Arbiter is enabled. */	SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3);	SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);		if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) {		return(1);	}	/* Return to D0 state. */	SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0);	/* Check for D0 state. */	SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);		if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) {		return(1);	}	/* Check PCI Config Registers. */	SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd);	SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls);	SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1);	SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2);	SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat);		if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 ||		(Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) {		return(1);	}	/* Restore PCI Config Space. */	for (i = 0; i < PCI_CFG_SIZE; i++) {		SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]);	}	return(0);}	/* SkGePciReset */#endif /* SK_PCI_RESET *//****************************************************************************** * *	SkGeInit1() - Level 1 Initialization * * Description: *	o Do a software reset. *	o Clear all reset bits. *	o Verify that the detected hardware is present. *	  Return an error if not. *	o Get the hardware configuration *		+ Read the number of MACs/Ports. *		+ Read the RAM size. *		+ Read the PCI Revision Id. *		+ Find out the adapters host clock speed *		+ Read and check the PHY type * * Returns: *	0:	success *	5:	Unexpected PHY type detected *	6:	HW self test failed */static int SkGeInit1(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC)		/* IO context */{	SK_U8	Byte;	SK_U16	Word;	SK_U16	CtrlStat;	SK_U32	DWord;	int	RetVal;	int	i;	RetVal = 0;	/* save CLK_RUN bits (YUKON-Lite) */	SK_IN16(IoC, B0_CTST, &CtrlStat);#ifdef SK_PCI_RESET	(void)SkGePciReset(pAC, IoC);#endif /* SK_PCI_RESET */	/* do the SW-reset */	SK_OUT8(IoC, B0_CTST, CS_RST_SET);	/* release the SW-reset */	SK_OUT8(IoC, B0_CTST, CS_RST_CLR);	/* reset all error bits in the PCI STATUS register */	/*	 * Note: PCI Cfg cycles cannot be used, because they are not	 *		 available on some platforms after 'boot time'.	 */	SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);	SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));	SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);	/* release Master Reset */	SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);#ifdef CLK_RUN	CtrlStat |= CS_CLK_RUN_ENA;#endif /* CLK_RUN */	/* restore CLK_RUN bits */	SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &		(CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));	/* read Chip Identification Number */	SK_IN8(IoC, B2_CHIP_ID, &Byte);	pAC->GIni.GIChipId = Byte;		/* read number of MACs */	SK_IN8(IoC, B2_MAC_CFG, &Byte);	pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;		/* get Chip Revision Number */	pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);	/* get diff. PCI parameters */	SK_IN16(IoC, B0_CTST, &CtrlStat);		/* read the adapters RAM size */	SK_IN8(IoC, B2_E_0, &Byte);		pAC->GIni.GIGenesis = SK_FALSE;	pAC->GIni.GIYukon = SK_FALSE;	pAC->GIni.GIYukonLite = SK_FALSE;#ifdef GENESIS	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {		pAC->GIni.GIGenesis = SK_TRUE;		if (Byte == (SK_U8)3) {									/* special case: 4 x 64k x 36, offset = 0x80000 */			pAC->GIni.GIRamSize = 1024;			pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;		}		else {			pAC->GIni.GIRamSize = (int)Byte * 512;			pAC->GIni.GIRamOffs = 0;		}		/* all GE adapters work with 53.125 MHz host clock */		pAC->GIni.GIHstClkFact = SK_FACT_53;				/* set Descr. Poll Timer Init Value to 250 ms */		pAC->GIni.GIPollTimerVal =			SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;	}#endif /* GENESIS */	#ifdef YUKON	if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {				pAC->GIni.GIYukon = SK_TRUE;				pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;				pAC->GIni.GIRamOffs = 0;				/* WA for chip Rev. A */		pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&			pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;

⌨️ 快捷键说明

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