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

📄 skxmac2.c

📁 ARM S3C2410 linux2.4 内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * * Description: *	Initialize 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 LOOback be set-up? */{	SK_GEPORT	*pPrt;	SK_U16		Ctrl1;	SK_U16		Ctrl2;	SK_U16		Ctrl3;	Ctrl1 = PHY_L_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;		}	}	/* Autonegotiation ? */	if (pPrt->PLinkMode == SK_LMODE_HALF ||	    pPrt->PLinkMode == SK_LMODE_FULL) {		/*		 * level one spec say: "1000Mbps: manual mode not allowed"		 * but lets see what happens...		 */		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,			0, "Level One PHY only works with Autoneg");		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,			("InitPhyLone: no autonegotiation Port %d\n", Port));		/* No Autonegiotiation */		/* Set DuplexMode in Config register */		Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);		/* 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 Autonegotiation 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 autonegotiation Port %d\n", Port));		/* Set Autonegotiation 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);		}		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 Autonegotiation */		Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;	}		/* Initialize LED register here ? */	/* No. Please do it in SkDgXmitLed() (if required) and swap	   init order of LEDs and XMAC. (MAl) */		/* Write 1000Base-T Control Register */	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_1000T_CTRL, Ctrl2);	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,		("1000Base-T Control Reg = %x\n", Ctrl2));		/* Write AutoNeg Advertisement Register */	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_AUNE_ADV, Ctrl3);	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,		("AutoNeg Advertisment Reg = %x\n", Ctrl3));		if (DoLoop) {		/* Set the Phy Loopback bit, too */		Ctrl1 |= PHY_CT_LOOP;	}	if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {		/*		 * nothing to do for Level one.		 * PHY supports frames up to 10k.		 */	}		/* Write to the Phy control register */	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_CTRL, Ctrl1);	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,		("PHY Control Reg = %x\n", Ctrl1));}	/* SkXmInitPhyLone*//****************************************************************************** * *	SkXmInitPhyNat() - Initialize the National Phy registers * * Description: *	Initialize 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 LOOback be set-up? */{/* todo: National */}	/* SkXmInitPhyNat*//****************************************************************************** * *	SkXmAutoNegLipaXmac() - Decides whether Link Partner could do autoneg * *	This function analyses the Interrupt status word. If any of the *	Autonegotiating interrupt bits are set, the PLipaAutoNeg variable *	is set true. */void	SkXmAutoNegLipaXmac(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port,		/* Port Index (MAC_1 + n) */SK_U16	IStatus)	/* Interrupt Status word to analyse */{	SK_GEPORT	*pPrt;	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&		(IStatus & (XM_IS_LIPA_RC|XM_IS_RX_PAGE|XM_IS_AND))) {		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,			("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, IStatus));		pPrt->PLipaAutoNeg = SK_LIPA_AUTO;	}}	/* SkXmAutoNegLipaXmac*//****************************************************************************** * *	SkXmAutoNegLipaBcom() - Decides whether Link Partner could do autoneg * *	This function analyses the PHY status word. If any of the *	Autonegotiating bits are set, The PLipaAutoNeg variable *	is set true. */void	SkXmAutoNegLipaBcom(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port,		/* Port Index (MAC_1 + n) */SK_U16	PhyStat)	/* PHY Status word to analyse */{	SK_GEPORT	*pPrt;	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && (PhyStat & PHY_ST_AN_OVER)) {		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,			("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat));		pPrt->PLipaAutoNeg = SK_LIPA_AUTO;	}}	/* SkXmAutoNegLipaBcom*//****************************************************************************** * *	SkXmAutoNegLipaLone() - Decides whether Link Partner could do autoneg * *	This function analyses the PHY status word. If any of the *	Autonegotiating bits are set, The PLipaAutoNeg variable *	is set true. */void	SkXmAutoNegLipaLone(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int	Port,		/* Port Index (MAC_1 + n) */SK_U16	PhyStat)	/* PHY Status word to analyse */{	SK_GEPORT	*pPrt;	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&		(PhyStat & (PHY_ST_AN_OVER))) {		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,			("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat));		pPrt->PLipaAutoNeg = SK_LIPA_AUTO;	}}	/* SkXmAutoNegLipaLone*//****************************************************************************** * *	SkXmAutoNegLipaNat() - Decides whether Link Partner could do autoneg * *	This function analyses the PHY status word. If any of the *	Autonegotiating bits are set, The PLipaAutoNeg variable *	is set true. */void	SkXmAutoNegLipaNat(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port,		/* Port Index (MAC_1 + n) */SK_U16	PhyStat)	/* PHY Status word to analyse */{	SK_GEPORT	*pPrt;	pPrt = &pAC->GIni.GP[Port];	if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&		(PhyStat & (PHY_ST_AN_OVER))) {		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,			("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat));		pPrt->PLipaAutoNeg = SK_LIPA_AUTO;	}}	/* SkXmAutoNegLipaNat*//****************************************************************************** * *	SkXmAutoNegDone() - Auto negotiation handling * * Description: *	This function handles the autonegotiation if the Done bit is set. * * Note: *	o The XMACs interrupt source register is NOT read here. *	o This function is public because it is used in the diagnostics *	  tool, too. * * Returns: *	SK_AND_OK	o.k. *	SK_AND_DUP_CAP 	Duplex capability error happened *	SK_AND_OTHER 	Other error happened */int	SkXmAutoNegDone(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port)		/* Port Index (MAC_1 + n) */{	switch (pAC->GIni.GP[Port].PhyType) {	case SK_PHY_XMAC:		return (SkXmAutoNegDoneXmac(pAC, IoC, Port));	case SK_PHY_BCOM:		return (SkXmAutoNegDoneBcom(pAC, IoC, Port));	case SK_PHY_LONE:		return (SkXmAutoNegDoneLone(pAC, IoC, Port));	case SK_PHY_NAT:		return (SkXmAutoNegDoneNat(pAC, IoC, Port));	}	return (SK_AND_OTHER);}	/* SkXmAutoNegDone*//****************************************************************************** * *	SkXmAutoNegDoneXmac() - Auto negotiation handling * * Description: *	This function handles the autonegotiation if the Done bit is set. * * Note: *	o The XMACs interrupt source register is NOT read here. * * Returns: *	SK_AND_OK	o.k. *	SK_AND_DUP_CAP 	Duplex capability error happened *	SK_AND_OTHER 	Other error happened */static int	SkXmAutoNegDoneXmac(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port)		/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;	SK_U16		ResAb;		/* Resolved Ability */	SK_U16		LPAb;		/* Link Partner Ability */	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneXmac"		"Port %d\n",Port));	pPrt = &pAC->GIni.GP[Port];	/* Get PHY parameters */	PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_LP, &LPAb);	PHY_READ(IoC, pPrt, Port, PHY_XMAC_RES_ABI, &ResAb);	if (LPAb & PHY_X_AN_RFB) {		/* At least one of the remote fault bit is set */		/* Error */		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,			("AutoNegFail: Remote fault bit set Port %d\n", Port));		pPrt->PAutoNegFail = SK_TRUE;		return (SK_AND_OTHER);	}	/* Check Duplex mismatch */	if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;	}	else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;	}	else {		/* Error */		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,			("AutoNegFail: Duplex mode mismatch port %d\n", Port));		pPrt->PAutoNegFail = SK_TRUE;		return (SK_AND_DUP_CAP);	}	/* Check PAUSE mismatch */	/* We are NOT using chapter 4.23 of the Xaqti manual */	/* We are using IEEE 802.3z/D5.0 Table 37-4 */	if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||	     pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&	    (LPAb & PHY_X_P_SYM_MD)) {		/* Symmetric PAUSE */		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;	}	else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&		   (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {		/* Enable PAUSE receive, disable PAUSE transmit */		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;	}	else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&		   (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {		/* Disable PAUSE receive, enable PAUSE transmit */		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;	}	else {		/* PAUSE mismatch -> no PAUSE */		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;	}	/* We checked everything and may now enable the link */	pPrt->PAutoNegFail = SK_FALSE;	SkXmRxTxEnable(pAC, IoC, Port);	return (SK_AND_OK);}	/* SkXmAutoNegDoneXmac*//****************************************************************************** * *	SkXmAutoNegDoneBcom() - Auto negotiation handling * * Description: *	This function handles the autonegotiation if the Done bit is set. * * Note: *	o The XMACs interrupt source register is NOT read here. * * Returns: *	SK_AND_OK	o.k. *	SK_AND_DUP_CAP 	Duplex capability error happened *	SK_AND_OTHER 	Other error happened */static int	SkXmAutoNegDoneBcom(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* IO context */int		Port)		/* Port Index (MAC_1 + n) */{	SK_GEPORT	*pPrt;	SK_U16		LPAb;		/* Link Partner Ability */	SK_U16		AuxStat;	/* Auxiliary Status */#if 001-Sep-2000 RA;:;:	SK_U16		ResAb;		/* Resolved Ability */#endif	/* 0 */	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,		("AutoNegDoneBcom, Port %d\n", Port));	pPrt = &pAC->GIni.GP[Port];	/* Get PHY parameters. */	PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUNE_LP, &LPAb);#if 001-Sep-2000 RA;:;:	PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);#endif	/* 0 */	PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_STAT, &AuxStat);	if (LPAb & PHY_B_AN_RF) {		/* Remote fault bit is set: Error. */		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,			("AutoNegFail: Remote fault bit set Port %d\n", Port));		pPrt->PAutoNegFail = SK_TRUE;		return (SK_AND_OTHER);	}

⌨️ 快捷键说明

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