skxmac2.c

来自「linux 内核源代码」· C语言 代码 · 共 2,599 行 · 第 1/5 页

C
2,599
字号
	if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {		AutoNeg = SK_FALSE;	}	else {		AutoNeg = SK_TRUE;	}		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("InitPhyMarv: Port %d, auto-negotiation %s\n",		 Port, AutoNeg ? "ON" : "OFF"));#ifdef VCPU	VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",		Port, DoLoop);#else /* VCPU */	if (DoLoop) {		/* Set 'MAC Power up'-bit, set Manual MDI configuration */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,			PHY_M_PC_MAC_POW_UP);	}	else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {		/* Read Ext. PHY Specific Control */		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);				ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |			PHY_M_EC_MAC_S_MSK);				ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |			PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,			("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));	}	/* Read PHY Control */	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);	if (!AutoNeg) {		/* Disable Auto-negotiation */		PhyCtrl &= ~PHY_CT_ANE;	}	PhyCtrl |= PHY_CT_RESET;	/* Assert software reset */	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);#endif /* VCPU */	PhyCtrl = 0 /* PHY_CT_COL_TST */;	C1000BaseT = 0;	AutoNegAdv = PHY_SEL_TYPE;	/* manually Master/Slave ? */	if (pPrt->PMSMode != SK_MS_MODE_AUTO) {		/* enable Manual Master/Slave */		C1000BaseT |= PHY_M_1000C_MSE;				if (pPrt->PMSMode == SK_MS_MODE_MASTER) {			C1000BaseT |= PHY_M_1000C_MSC;	/* set it to Master */		}	}		/* Auto-negotiation ? */	if (!AutoNeg) {				if (pPrt->PLinkMode == SK_LMODE_FULL) {			/* Set Full Duplex Mode */			PhyCtrl |= PHY_CT_DUP_MD;		}		/* Set Master/Slave manually if not already done */		if (pPrt->PMSMode == SK_MS_MODE_AUTO) {			C1000BaseT |= PHY_M_1000C_MSE;	/* set it to Slave */		}		/* Set Speed */		switch (pPrt->PLinkSpeed) {		case SK_LSPEED_AUTO:		case SK_LSPEED_1000MBPS:			PhyCtrl |= PHY_CT_SP1000;			break;		case SK_LSPEED_100MBPS:			PhyCtrl |= PHY_CT_SP100;			break;		case SK_LSPEED_10MBPS:			break;		default:			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,				SKERR_HWI_E019MSG);		}		if (!DoLoop) {			PhyCtrl |= PHY_CT_RESET;		}	}	else {		/* Set Auto-negotiation advertisement */				if (pAC->GIni.GICopperType) {			/* Set Speed capabilities */			switch (pPrt->PLinkSpeed) {			case SK_LSPEED_AUTO:				C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;				AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |					PHY_M_AN_10_FD | PHY_M_AN_10_HD;				break;			case SK_LSPEED_1000MBPS:				C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;				break;			case SK_LSPEED_100MBPS:				AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |					/* advertise 10Base-T also */					PHY_M_AN_10_FD | PHY_M_AN_10_HD;				break;			case SK_LSPEED_10MBPS:				AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;				break;			default:				SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,					SKERR_HWI_E019MSG);			}			/* Set Full/half duplex capabilities */			switch (pPrt->PLinkMode) {			case SK_LMODE_AUTOHALF:				C1000BaseT &= ~PHY_M_1000C_AFD;				AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);				break;			case SK_LMODE_AUTOFULL:				C1000BaseT &= ~PHY_M_1000C_AHD;				AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);				break;			case SK_LMODE_AUTOBOTH:				break;			default:				SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,					SKERR_HWI_E015MSG);			}						/* Set Flow-control capabilities */			switch (pPrt->PFlowCtrlMode) {			case SK_FLOW_MODE_NONE:				AutoNegAdv |= PHY_B_P_NO_PAUSE;				break;			case SK_FLOW_MODE_LOC_SEND:				AutoNegAdv |= PHY_B_P_ASYM_MD;				break;			case SK_FLOW_MODE_SYMMETRIC:				AutoNegAdv |= PHY_B_P_SYM_MD;				break;			case SK_FLOW_MODE_SYM_OR_REM:				AutoNegAdv |= PHY_B_P_BOTH_MD;				break;			default:				SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,					SKERR_HWI_E016MSG);			}		}		else {	/* special defines for FIBER (88E1011S only) */						/* Set Full/half duplex capabilities */			switch (pPrt->PLinkMode) {			case SK_LMODE_AUTOHALF:				AutoNegAdv |= PHY_M_AN_1000X_AHD;				break;			case SK_LMODE_AUTOFULL:				AutoNegAdv |= PHY_M_AN_1000X_AFD;				break;			case SK_LMODE_AUTOBOTH:				AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;				break;			default:				SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,					SKERR_HWI_E015MSG);			}						/* Set Flow-control capabilities */			switch (pPrt->PFlowCtrlMode) {			case SK_FLOW_MODE_NONE:				AutoNegAdv |= PHY_M_P_NO_PAUSE_X;				break;			case SK_FLOW_MODE_LOC_SEND:				AutoNegAdv |= PHY_M_P_ASYM_MD_X;				break;			case SK_FLOW_MODE_SYMMETRIC:				AutoNegAdv |= PHY_M_P_SYM_MD_X;				break;			case SK_FLOW_MODE_SYM_OR_REM:				AutoNegAdv |= PHY_M_P_BOTH_MD_X;				break;			default:				SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,					SKERR_HWI_E016MSG);			}		}		if (!DoLoop) {			/* Restart Auto-negotiation */			PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;		}	}	#ifdef VCPU	/*	 * E-mail from Gu Lin (08-03-2002):	 */		/* Program PHY register 30 as 16'h0708 for simulation speed up */	SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);		VCpuWait(2000);#else /* VCPU */		/* Write 1000Base-T Control Register */	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));		/* Write AutoNeg Advertisement Register */	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));#endif /* VCPU */		if (DoLoop) {		/* Set the PHY Loopback bit */		PhyCtrl |= PHY_CT_LOOP;#ifdef XXX		/* Program PHY register 16 as 16'h0400 to force link good */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);#endif /* XXX */#ifndef VCPU		if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {			/* Write Ext. PHY Specific Control */			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,				(SK_U16)((pPrt->PLinkSpeed + 2) << 4));		}#endif /* VCPU */	}#ifdef TEST_ONLY	else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {			/* Write PHY Specific Control */			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,				PHY_M_PC_EN_DET_MSK);	}#endif	/* Write to the PHY Control register */	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));#ifdef VCPU	VCpuWait(2000);#else	LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);	if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {		LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;	}	if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {		LedCtrl |= PHY_M_LEDC_DP_CTRL;	}		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);	if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {		/* only in forced 100 Mbps mode */		if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,				PHY_M_LED_MO_100(MO_LED_ON));		}	}#ifdef SK_DIAG	c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);	c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);	c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);	c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);#endif /* SK_DIAG */#if defined(SK_DIAG) || defined(DEBUG)	/* Read PHY Control */	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));		/* Read 1000Base-T Control Register */	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("1000B-T Ctrl =0x%04X\n", C1000BaseT));		/* Read AutoNeg Advertisement Register */	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));		/* Read Ext. PHY Specific Control */	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));		/* Read PHY Status */	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("PHY Stat Reg.=0x%04X\n", PhyStat));	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("PHY Stat Reg.=0x%04X\n", PhyStat1));		/* Read PHY Specific Status */	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("PHY Spec Stat=0x%04X\n", PhySpecStat));#endif /* SK_DIAG || DEBUG */#ifdef SK_DIAG	c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);	c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);	c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);	c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);	c_print("PHY Stat Reg=0x%04X\n", PhyStat);	c_print("PHY Stat Reg=0x%04X\n", PhyStat1);	c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);#endif /* SK_DIAG */#endif /* VCPU */}	/* SkGmInitPhyMarv */#endif /* YUKON */#ifdef OTHER_PHY/****************************************************************************** * *	SkXmInitPhyLone() - Initialize the Level One Phy registers * * Description:	initializes all the Level One Phy registers * * Note: * * Returns: *	nothing */static void SkXmInitPhyLone(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port,		/* Port Index (MAC_1 + n) */SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */{	SK_GEPORT	*pPrt;	SK_U16		Ctrl1;	SK_U16		Ctrl2;	SK_U16		Ctrl3;	Ctrl1 = PHY_CT_SP1000;	Ctrl2 = 0;	Ctrl3 = PHY_SEL_TYPE;	pPrt = &pAC->GIni.GP[Port];	/* manually Master/Slave ? */	if (pPrt->PMSMode != SK_MS_MODE_AUTO) {		Ctrl2 |= PHY_L_1000C_MSE;				if (pPrt->PMSMode == SK_MS_MODE_MASTER) {			Ctrl2 |= PHY_L_1000C_MSC;		}	}	/* Auto-negotiation ? */	if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {		/*		 * level one spec say: "1000 Mbps: manual mode not allowed"		 * but lets see what happens...		 */		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,			("InitPhyLone: no auto-negotiation Port %d\n", Port));		/* Set DuplexMode in Config register */		if (pPrt->PLinkMode == SK_LMODE_FULL) {			Ctrl1 |= PHY_CT_DUP_MD;		}		/* Determine Master/Slave manually if not already done */		if (pPrt->PMSMode == SK_MS_MODE_AUTO) {			Ctrl2 |= PHY_L_1000C_MSE;	/* set it to Slave */		}		/*		 * Do NOT enable Auto-negotiation here. This would hold		 * the link down because no IDLES are transmitted		 */	}	else {		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,			("InitPhyLone: with auto-negotiation Port %d\n", Port));		/* Set Auto-negotiation advertisement */		/* Set Full/half duplex capabilities */		switch (pPrt->PLinkMode) {		case SK_LMODE_AUTOHALF:			Ctrl2 |= PHY_L_1000C_AHD;			break;		case SK_LMODE_AUTOFULL:			Ctrl2 |= PHY_L_1000C_AFD;			break;		case SK_LMODE_AUTOBOTH:			Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;			break;		default:			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,				SKERR_HWI_E015MSG);		}		/* Set Flow-control capabilities */		switch (pPrt->PFlowCtrlMode) {		case SK_FLOW_MODE_NONE:			Ctrl3 |= PHY_L_P_NO_PAUSE;			break;		case SK_FLOW_MODE_LOC_SEND:			Ctrl3 |= PHY_L_P_ASYM_MD;			break;		case SK_FLOW_MODE_SYMMETRIC:			Ctrl3 |= PHY_L_P_SYM_MD;			break;		case SK_FLOW_MODE_SYM_OR_REM:			Ctrl3 |= PHY_L_P_BOTH_MD;			break;		default:			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,				SKERR_HWI_E016MSG);		}		/* Restart Auto-negotiation */		Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;	}		/* Write 1000Base-T Control Register */	SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));		/* Write AutoNeg Advertisement Register */	SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));	if (DoLoop) {		/* Set the Phy Loopback bit, too */		Ctrl1 |= PHY_CT_LOOP;	}	/* Write to the Phy control register */	SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,		("PHY Control Reg=0x%04X\n", Ctrl1));}	/* SkXmInitPhyLone *//****************************************************************************** * *	SkXmInitPhyNat() - Initialize the National Phy registers * * Description:	initializes all the National Phy registers * * Note: * * Returns: *	nothing */static void SkXmInitPhyNat(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port,		/* Port Index (MAC_1 + n) */SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */{/* todo: National */}	/* SkXmInitPhyNat */#endif /* OTHER_PHY *//****************************************************************************** * *	SkMacInitPhy() - Initialize the PHY registers * * Description:	calls the Init PHY routines dep. on board type * * Note: * * Returns: *	nothing */void SkMacInitPhy(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port,		/* Port Index (MAC_1 + n) */SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */{	SK_GEPORT	*pPrt;	pPrt = &pAC->GIni.GP[Port];#ifdef GENESIS	if (pAC->GIni.GIGenesis) {				switch (pPrt->PhyType) {		case SK_PHY_XMAC:			SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);			break;		case SK_PHY_BCOM:			SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);			break;#ifdef OTHER_PHY		case SK_PHY_LONE:

⌨️ 快捷键说明

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