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

📄 skxmac2.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 5 页
字号:
 * * 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;	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 & MFF_SET_MAC_RST) != 0) {			/* 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), 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 (pPrt->PhyType != SK_PHY_XMAC) {			SK_IN32(IoC, B2_GP_IO, &Reg);			if (Port == 0) {				Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */			}			else {				Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */			}			SK_OUT32(IoC, B2_GP_IO, Reg);			/* Enable GMII interface */			XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);			/* read Id from external PHY (all have the same address) */			SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);			/*			 * 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 (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {				/*				 * Workaround BCOM Errata for the C0 type.				 * Write magic patterns to reserved registers.				 */				i = 0;				while (BcomRegC0Hack[i].PhyReg != 0) {					SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,						BcomRegC0Hack[i].PhyVal);					i++;				}			}			else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {				/*				 * Workaround BCOM Errata for the A1 type.				 * Write magic patterns to reserved registers.				 */				i = 0;				while (BcomRegA1Hack[i].PhyReg != 0) {					SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,						BcomRegA1Hack[i].PhyVal);					i++;				}			}			/*			 * Workaround BCOM Errata (#10523) for all BCom PHYs.			 * Disable Power Management after reset.			 */			SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);			SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,				(SK_U16)(SWord | PHY_B_AC_DIS_PM));			/* PHY LED initialization is done in SkGeXmitLED() */		}		/* Dummy read the Interrupt source register */		XM_IN16(IoC, Port, XM_ISRC, &SWord);		/*		 * The auto-negotiation process starts immediately after		 * clearing the reset. The auto-negotiation process should be		 * started by the SIRQ, therefore stop it here immediately.		 */		SkMacInitPhy(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 programmed to XMAC A	 * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B	 */	for (i = 0; i < 3; i++) {		/*		 * The following 2 statements are together endianess		 * independent. 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, SK_XM_RX_HI_WM);	/* Configure Tx Request Threshold */	SWord = SK_XM_THR_SL;				/* for single port */	if (pAC->GIni.GIMacsFound > 1) {		switch (pAC->GIni.GIPortUsage) {		case SK_RED_LINK:			SWord = SK_XM_THR_REDL;		/* redundant link */			break;		case SK_MUL_LINK:			SWord = SK_XM_THR_MULL;		/* load balancing */			break;		case SK_JUMBO_LINK:			SWord = SK_XM_THR_JUMBO;	/* jumbo frames */			break;		default:			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);			break;		}	}	XM_OUT16(IoC, Port, XM_TX_THR, SWord);	/* setup register defaults for the Tx Command Register */	XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);	/* setup register defaults for the Rx Command Register */	SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;	if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {		SWord |= XM_RX_BIG_PK_OK;	}	if (pPrt->PLinkModeConf == SK_LMODE_HALF) {		/*		 * If in manual half duplex mode the other side might be in		 * full duplex mode, so ignore if a carrier extension is not seen		 * on frames received		 */		SWord |= XM_RX_DIS_CEXT;	}	XM_OUT16(IoC, Port, XM_RX_CMD, SWord);	/*	 * setup register defaults for the Mode Register	 *	- Don't strip error frames to avoid Store & Forward	 *	  on the Rx side.	 *	- Enable 'Check Station Address' bit	 *	- Enable 'Check Address Array' bit	 */	XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);	/*	 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)	 *	- Enable all bits excepting 'Octets Rx OK Low CntOv'	 *	  and 'Octets Rx OK Hi Cnt Ov'.	 */	XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);	/*	 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)	 *	- Enable all bits excepting 'Octets Tx OK Low CntOv'	 *	  and 'Octets Tx OK Hi Cnt Ov'.	 */	XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);	/*	 * Do NOT init XMAC interrupt mask here.	 * All interrupts remain disable until link comes up!	 */	/*	 * Any additional configuration changes may be done now.	 * The last action is to enable the Rx and Tx state machine.	 * This should be done after the auto-negotiation process	 * has been completed successfully.	 */}	/* SkXmInitMac *//****************************************************************************** * *	SkGmInitMac() - Initialize the GMAC * * Description: *	Initialize the GMAC of the specified port. *	The GMAC must be reset or stopped before calling this function. * * Note: *	The GMAC's Rx and Tx state machine is still disabled when returning. * * Returns: *	nothing */void SkGmInitMac(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port)		/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;	int			i;	SK_U16		SWord;	SK_U32		DWord;	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PState == SK_PRT_STOP) {		/* Port State: SK_PRT_STOP */		/* Verify that the reset bit is cleared */		SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);		if ((DWord & GMC_RST_SET) != 0) {			/* 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) {		/* set GPHY Control reset */		SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);		/* set GMAC Control reset */		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);		/* clear GMAC Control reset */		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);		/* set GMAC Control reset */		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);		/* set HWCFG_MODE */		DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |			GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |			(pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :			GPC_HWCFG_GMII_FIB);		/* set GPHY Control reset */		SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);		/* release GPHY Control reset */		SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);		/* clear GMAC Control reset */		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);		/* Dummy read the Interrupt source register */		SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);#ifndef VCPU		/* read Id from PHY */		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);		SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);#endif /* VCPU */	}	(void)SkGmResetCounter(pAC, IoC, Port);	SWord =  0;	/* speed settings */	switch (pPrt->PLinkSpeed) {	case SK_LSPEED_AUTO:	case SK_LSPEED_1000MBPS:		SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;		break;	case SK_LSPEED_100MBPS:		SWord |= GM_GPCR_SPEED_100;		break;	case SK_LSPEED_10MBPS:		break;	}	/* duplex settings */	if (pPrt->PLinkMode != SK_LMODE_HALF) {		/* set full duplex */		SWord |= GM_GPCR_DUP_FULL;	}	/* flow control settings */	switch (pPrt->PFlowCtrlMode) {	case SK_FLOW_MODE_NONE:		/* disable auto-negotiation for flow-control */		SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS;		break;	case SK_FLOW_MODE_LOC_SEND:		SWord |= GM_GPCR_FC_RX_DIS;		break;	case SK_FLOW_MODE_SYMMETRIC:		/* TBD */	case SK_FLOW_MODE_SYM_OR_REM:		/* enable auto-negotiation for flow-control and */		/* enable Rx and Tx of pause frames */		break;	}	/* Auto-negotiation ? */	if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {		/* disable auto-update for speed, duplex and flow-control */		SWord |= GM_GPCR_AU_ALL_DIS;	}	/* setup General Purpose Control Register */	GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);	/* setup Transmit Control Register */	GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR);	/* setup Receive Control Register */	GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |		GM_RXCR_CRC_DIS);	/* setup Transmit Flow Control Register */	GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);	/* setup Transmit Parameter Register */#ifdef VCPU	GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);#endif /* VCPU */	SWord = JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26);	GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);	/* configure the Serial Mode Register */#ifdef VCPU	GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);#endif /* VCPU */	SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH;	if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {		/* enable jumbo mode (Max. Frame Length = 9018) */		SWord |= GM_SMOD_JUMBO_ENA;	}	GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);	/*	 * configure the GMACs Station Addresses	 * in PROM you can find our addresses at:	 * B2_MAC_1 = xx xx xx xx xx x0 virtual address	 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A	 * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort	 */	for (i = 0; i < 3; i++) {		/*		 * The following 2 statements are together endianess		 * independent. Remember this when changing.		 */		/* physical address: will be used for pause frames */		SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);#ifdef WA_DEV_16		/* WA for deviation #16 */		if (pAC->GIni.GIChipRev == 0) {			/* swap the address bytes */			SWord = ((SWord & 0xff00) >> 8)	| ((SWord & 0x00ff) << 8);			/* write to register in reversed order */			GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);		}		else {			GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);		}#else		GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);#endif /* WA_DEV_16 */		/* virtual address: will be used for data */		SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);		GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);		/* reset Multicast filtering Hash registers 1-3 */		GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);	}	/* reset Multicast filtering Hash register 4 */	GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);	/* enable interrupt mask for counter overflows */	GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);	GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);	GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);	/* read General Purpose Status */	GM_IN16(IoC, Port, GM_GP_STAT, &SWord);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("MAC Stat Reg=0x%04X\n", SWord));#ifdef SK_DIAG	c_print("MAC Stat Reg=0x%04X\n", SWord);#endif /* SK_DIAG */}	/* SkGmInitMac *//****************************************************************************** * *	SkXmInitDupMd() - Initialize the XMACs Duplex Mode * * Description: *	This function initializes the XMACs Duplex Mode. *	It should be called after successfully finishing *	the Auto-negotiation Process * * Returns: *	nothing */void SkXmInitDupMd(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port)		/* Port Index (MAC_1 + n) */{	switch (pAC->GIni.GP[Port].PLinkModeStatus) {	case SK_LMODE_STAT_AUTOHALF:	case SK_LMODE_STAT_HALF:		/* Configuration Actions for Half Duplex Mode */		/*		 * XM_BURST = default value. We are probable not quick		 * 	enough at the 'XMAC' bus to burst 8kB.		 *	The XMAC stops bursting if no transmit frames		 *	are available or the burst limit is exceeded.		 */		/* XM_TX_RT_LIM = default value (15) */		/* XM_TX_STIME = default value (0xff = 4096 bit times) */		break;	case SK_LMODE_STAT_AUTOFULL:	case SK_LMODE_STAT_FULL:		/* Configuration Actions for Full Duplex Mode */		/*		 * The duplex mode is configured by the PHY,

⌨️ 快捷键说明

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