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

📄 skxmac2.c

📁 广州斯道2410普及版II的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	SK_U16	ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};	XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);}	/* SkXmClrHashAddr*//****************************************************************************** * *	SkXmFlushTxFifo() - Flush the XMACs transmit FIFO * * Description: *	Flush the transmit FIFO of the XMAC specified by the index 'Port' * * Returns: *	nothing */void SkXmFlushTxFifo(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* IO context */int		Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */{	SK_U32	MdReg;	XM_IN32(IoC, Port, XM_MODE, &MdReg);	MdReg |= XM_MD_FTF;	XM_OUT32(IoC, Port, XM_MODE, MdReg);}	/* SkXmFlushTxFifo *//****************************************************************************** * *	SkXmFlushRxFifo() - Flush the XMACs receive FIFO * * Description: *	Flush the receive FIFO of the XMAC specified by the index 'Port' * * Returns: *	nothing */void SkXmFlushRxFifo(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* IO context */int		Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */{	SK_U32	MdReg;	XM_IN32(IoC, Port, XM_MODE, &MdReg);	MdReg |= XM_MD_FRF;	XM_OUT32(IoC, Port, XM_MODE, MdReg);}	/* SkXmFlushRxFifo*//****************************************************************************** * *	SkXmSoftRst() - Do a XMAC software reset * * Description: *	The PHY registers should not be destroyed during this *	kind of software reset. Therefore the XMAC Software Reset *	(XM_GP_RES_MAC bit in XM_GP_PORT) must not be used! * *	The software reset is done by *		- disabling the Rx and Tx state maschine, *		- reseting the statistics module, *		- clear all other significant XMAC Mode, *		  Command, and Control Registers *		- clearing the Hash Register and the *		  Exact Match Address registers, and *		- flushing the XMAC's Rx and Tx FIFOs. * * Note: *	Another requirement when stopping the XMAC is to *	avoid sending corrupted frames on the network. *	Disabling the Tx state maschine will NOT interrupt *	the currently transmitted frame. But we must take care *	that the tx FIFO is cleared AFTER the current frame *	is complete sent to the network. * *	It takes about 12ns to send a frame with 1538 bytes. *	One PCI clock goes at least 15ns (66MHz). Therefore *	after reading XM_GP_PORT back, we are sure that the *	transmitter is disabled AND idle. And this means *	we may flush the transmit FIFO now. * * Returns: *	nothing */void SkXmSoftRst(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* IO context */int		Port)	/* port to stop (MAC_1 + n) */{	SK_GEPORT	*pPrt;	SK_U16		Word;	pPrt = &pAC->GIni.GP[Port];	/* disable the receiver and transmitter */	XM_IN16(IoC, Port, XM_MMU_CMD, &Word);	XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX|XM_MMU_ENA_TX));	/* reset the statistics module */	XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);	/*	 * clear all other significant XMAC Mode,	 * Command, and Control Registers	 */	XM_OUT16(IoC, Port, XM_IMSK, 0xffff);		/* disable all IRQs */	XM_OUT32(IoC, Port, XM_MODE, 0x00000000);	/* clear Mode Reg */	XM_OUT16(IoC, Port, XM_TX_CMD, 0x0000);		/* reset TX CMD Reg */	XM_OUT16(IoC, Port, XM_RX_CMD, 0x0000);		/* reset RX CMD Reg */		/* disable all PHY IRQs */	switch (pAC->GIni.GP[Port].PhyType) {	case SK_PHY_BCOM:			PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 0xffff);			break;		case SK_PHY_LONE:			PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 0x0);			break;		case SK_PHY_NAT:			/* todo: National			 PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, 				0xffff); */			break;	}	/* clear the Hash Register */	SkXmClrHashAddr(pAC, IoC, Port);	/* clear the Exact Match Address registers */	SkXmClrExactAddr(pAC, IoC, Port, 0, 15);	SkXmClrSrcCheck(pAC, IoC, Port);	/* flush the XMAC's Rx and Tx FIFOs */	SkXmFlushTxFifo(pAC, IoC, Port);	SkXmFlushRxFifo(pAC, IoC, Port);	pAC->GIni.GP[Port].PState = SK_PRT_STOP;}	/* SkXmSoftRst*//****************************************************************************** * *	SkXmHardRst() - Do a XMAC hardware reset * * Description: *	The XMAC of the specified 'Port' and all connected devices *	(PHY and SERDES) will receive a reset signal on its *Reset *	pins. *	External PHYs must be reset be clearing a bit in the GPIO *	register (Timing requirements: Broadcom: 400ns, Level One: *	none, National: 80ns). * * ATTENTION: * 	It is absolutely neccessary to reset the SW_RST Bit first *	before calling this function. * * Returns: *	nothing */void SkXmHardRst(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* IO context */int		Port)	/* port to stop (MAC_1 + n) */{	SK_U32	Reg;	int		i;	int		TOut;	SK_U16	Word;	for (i = 0; i < 4; i++) {		/* TX_MFF_CTRL1 is a 32 bit register but only the lowest 16 */		/* bit contains buttoms to press */		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), (SK_U16)MFF_CLR_MAC_RST);		TOut = 0;		do {			TOut ++;			if (TOut > 10000) {				/*				 * Adapter seems to be in RESET state.				 * Registers cannot be written.				 */				return;			}			SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1),				(SK_U16) MFF_SET_MAC_RST);			SK_IN16(IoC,MR_ADDR(Port,TX_MFF_CTRL1), &Word);		} while ((Word & MFF_SET_MAC_RST) == 0);	}	/* For external PHYs there must be special handling */	if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {		/* reset external PHY */		SK_IN32(IoC, B2_GP_IO, &Reg);		if (Port == 0) {			Reg |= GP_DIR_0; /* set to output */			Reg &= ~GP_IO_0;		}		else {			Reg |= GP_DIR_2; /* set to output */			Reg &= ~GP_IO_2;		}		SK_OUT32(IoC, B2_GP_IO, Reg);		/* short delay */		SK_IN32(IoC, B2_GP_IO, &Reg);	}	pAC->GIni.GP[Port].PState = SK_PRT_RESET;}	/* SkXmHardRst *//****************************************************************************** * *	SkXmInitMac() - Initialize the XMAC II * * Description: *	Initialize all the XMAC of the specified port. *	The XMAC must be reset or stopped before calling this function. * * Note: *	The XMAC's Rx and Tx state machine is still disabled when returning. * * Returns: *	nothing */void SkXmInitMac(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port)		/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;	SK_U32		Reg;	int			i;	SK_U16		SWord;	SK_U16		PhyId;	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PState == SK_PRT_STOP) {		/* Port State: SK_PRT_STOP */		/* Verify that the reset bit is cleared */		SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);		if (SWord & (SK_U16)MFF_SET_MAC_RST) {			/* PState does not match HW state */			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);			/* Correct it. */			pPrt->PState = SK_PRT_RESET;		}	}	if (pPrt->PState == SK_PRT_RESET) {		/*		 * clear HW reset		 * Note: The SW reset is self clearing, therefore there is		 *	 nothing to do here.		 */		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), (SK_U16)MFF_CLR_MAC_RST);		/* Ensure that XMAC reset release is done (errata from LReinbold?). */		SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);		/* Clear PHY reset. */		if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {			SK_IN32(IoC, B2_GP_IO, &Reg);			if (Port == 0) {				Reg |= GP_DIR_0; /* Set to output. */				Reg |= GP_IO_0;			}			else {				Reg |= GP_DIR_2; /* Set to output. */				Reg |= GP_IO_2;			}			SK_OUT32(IoC, B2_GP_IO, Reg);			/* Enable GMII interface. */			XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);			PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &PhyId);#ifdef xDEBUG			if (SWord == 0xFFFF) {				i = 1;				do {					PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &SWord);					i++;					/* Limit retries; else machine may hang. */				} while (SWord == 0xFFFF && i < 500000);				CMSMPrintString(					pAC->pConfigTable,					MSG_TYPE_RUNTIME_INFO,					"ID1 is %x after %d reads.",					(void *)SWord,					(void *)i);				/* Trigger PCI analyzer */				/* SK_IN32(IoC, 0x012c, &Reg); */			}#endif	/* DEBUG */			/*			 * Optimize MDIO transfer by suppressing preamble.			 * Must be done AFTER first access to BCOM chip.			 */			XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);			XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);			if (PhyId == 0x6044) {				/* Workaround BCOM Errata for the C0 type. */				/* Write magic patterns to reserved registers. */				i = 0;				while (BcomRegC0Hack[i].PhyReg != 0) {					PHY_WRITE(IoC, pPrt, Port, BcomRegC0Hack[i].PhyReg,						BcomRegC0Hack[i].PhyVal);					i++;				}			}			else if (PhyId == 0x6041) {				/* Workaround BCOM Errata for the A1 type. */				/* Write magic patterns to reserved registers. */				i = 0;				while (BcomRegA1Hack[i].PhyReg != 0) {					PHY_WRITE(IoC, pPrt, Port, BcomRegA1Hack[i].PhyReg,						BcomRegA1Hack[i].PhyVal);					i++;				}			}			/* Workaround BCOM Errata (#10523) for all BCom PHYs. */			/* Disable Power Management after reset. */			PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);#ifdef xDEBUG			if (SWord == 0xFFFF) {				i = 1;				do {					PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);					i++;					/* Limit retries; else machine may hang. */				} while (SWord == 0xFFFF && i < 500000);				CMSMPrintString(					pAC->pConfigTable,					MSG_TYPE_RUNTIME_INFO,					"AUX_CTRL is %x after %d reads.",					(void *)SWord,					(void *)i);				/* Trigger PCI analyzer */				/* SK_IN32(IoC, 0x012c, &Reg); */			}#endif	/* DEBUG */			PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,				SWord | PHY_B_AC_DIS_PM);			/* PHY LED initialization is done in SkGeXmitLED(), not here. */		}		/* Dummy read the Interrupt source register */		XM_IN16(IoC, Port, XM_ISRC, &SWord);				/*		 * The autonegotiation process starts immediately after		 * clearing the reset. The autonegotiation process should be		 * started by the SIRQ, therefore stop it here immediately.		 */		SkXmInitPhy(pAC, IoC, Port, SK_FALSE);#if 0		/* temp. code: enable signal detect */		/* WARNING: do not override GMII setting above */		XM_OUT16(pAC, Port, XM_HW_CFG, XM_HW_COM4SIG);#endif	}	/*	 * configure the XMACs Station Address	 * B2_MAC_2 = xx xx xx xx xx x1 is programed to XMAC A	 * B2_MAC_3 = xx xx xx xx xx x2 is programed to XMAC B	 */	for (i = 0; i < 3; i++) {		/*		 * The following 2 statements are together endianess		 * independant. Remember this when changing.		 */		SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);		XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);	}	/* Tx Inter Packet Gap (XM_TX_IPG):	use default */	/* Tx High Water Mark (XM_TX_HI_WM):	use default */	/* Tx Low Water Mark (XM_TX_LO_WM):	use default */	/* Host Request Threshold (XM_HT_THR):	use default */	/* Rx Request Threshold (XM_RX_THR):	use default */	/* Rx Low Water Mark (XM_RX_LO_WM):	use default */	/* configure Rx High Water Mark (XM_RX_HI_WM) */	XM_OUT16(IoC, Port, XM_RX_HI_WM, 0x05aa);	if (pAC->GIni.GIMacsFound > 1) {		switch (pAC->GIni.GIPortUsage) {		case SK_RED_LINK:			/* Configure Tx Request Threshold for red. link */			XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_REDL);			break;		case SK_MUL_LINK:			/* Configure Tx Request Threshold for load bal. */			XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_MULL);			break;		case SK_JUMBO_LINK:			/* Configure Tx Request Threshold for jumbo frames */			XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_JUMBO);			break;		default:			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014,				SKERR_HWI_E014MSG);			break;		}	}	else {		/* Configure Tx Request Threshold for single port */		XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_SL);	}	/*	 * setup register defaults for the Rx Command Register	 *	- Enable Automatic Frame Padding on Tx side	 */	XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);	/*	 * setup register defaults for the Rx Command Register,	 * program value of PRxCmd	 */	XM_OUT16(IoC, Port, XM_RX_CMD, pPrt->PRxCmd);	/*	 * setup register defaults for the Mode Register	 *	- Don't strip error frames to avoid Store & Forward

⌨️ 快捷键说明

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