📄 emacphy.c
字号:
NWAYadvertise=NWAY_SEL;
if (*PhyState&SMODE_FD100) NWAYadvertise|=NWAY_FD100;
if (*PhyState&SMODE_HD100) NWAYadvertise|=NWAY_HD100;
if (*PhyState&SMODE_FD10) NWAYadvertise|=NWAY_FD10;
if (*PhyState&SMODE_HD10) NWAYadvertise|=NWAY_HD10;
if (*PhyState&SMODE_LOOP) NWAYadvertise|=PHY_LOOP;
*PhyState&=~(PHY_TIM_MASK|PHY_STATE_MASK);
if ((PhyStatus&NWAY_CAPABLE)&&(*PhyState&SMODE_AUTO)) /*NWAY Phy Detected*/
{
/*For NWAY compliant Phys */
MDIOUSERACCESS=MDIO_GO|MDIO_WRITE|(PHY_CONTROL_REG<<21)|(PhyNum<<16)|AUTO_NEGOTIATE_EN;
_EmacMdioWaitForAccessComplete(macbase);
MDIOUSERACCESS=MDIO_GO|MDIO_WRITE|(NWAY_ADVERTIZE_REG<<21)|(PhyNum<<16)|NWAYadvertise;
_EmacMdioWaitForAccessComplete(macbase);
MDIOUSERACCESS=MDIO_GO|MDIO_WRITE|(PHY_CONTROL_REG<<21)|(PhyNum<<16)|AUTO_NEGOTIATE_EN|RENEGOTIATE;
_EmacMdioWaitForAccessComplete(macbase);
*PhyState|=PHY_CHANGE|PHY_NWST_TO|NWAY_START;
}
else
{
*PhyState&=~SMODE_AUTO; /*The Phy is not capable of auto negotiation! */
m=NWAYadvertise;
/*
for(j=0x8000,i=0;(i<16)&&((j&m)==0);i++,j>>=1);
m=j;
*/
j=0;
if (m&(NWAY_FD100|NWAY_HD100))
{
j=PHY_100;
/*m&=(NWAY_FD100|NWAY_HD100);*/
}
if (m&(NWAY_FD100|NWAY_FD10))
j|=PHY_FD;
if (m&PHY_LOOP)
j|=PHY_LOOP;
MDIOUSERACCESS=MDIO_GO|MDIO_WRITE|(PHY_CONTROL_REG<<21)|(PhyNum<<16)|j; /*Phy Speed and Duplex*/
*PhyState&=~PHY_SPEED_MASK;
if (j&PHY_100)
*PhyState|=(1<<PHY_SPEED_OFFSET);
*PhyState&=~PHY_DUPLEX_MASK;
if (j&PHY_FD)
*PhyState|=(1<<PHY_DUPLEX_OFFSET);
*PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT;
_EmacMdioWaitForAccessComplete(macbase);
}
#ifdef ACPEP
MDIOUSERACCESS = MDIO_GO|MDIO_WRITE|(PHY_LED_REG<<21)|(PhyNum<<16)|0x2132;
_EmacMdioWaitForAccessComplete(macbase);
#endif
}
void _EmacNwayStartState(int macbase,int *PhyState)
{
int PhyNum,PhyMode;
PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
#ifdef ACPEP
MDIOUSERACCESS = MDIO_GO|MDIO_WRITE|(PHY_LED_REG<<21)|(PhyNum<<16)|0x2132;
_EmacMdioWaitForAccessComplete(macbase);
#endif
/*Wait for Negotiation to start */
MDIOUSERACCESS=MDIO_GO|MDIO_READ|(PHY_CONTROL_REG<<21)|(PhyNum<<16);
_EmacMdioWaitForAccessComplete(macbase);
PhyMode=MDIOUSERACCESS;
if((PhyMode&RENEGOTIATE)==0)
{
MDIOUSERACCESS=MDIO_GO|MDIO_READ|(PHY_STATUS_REG<<21)|(PhyNum<<16); /*Flush pending latch bits*/
*PhyState&=~(PHY_STATE_MASK|PHY_TIM_MASK);
*PhyState|=PHY_CHANGE|NWAY_WAIT|PHY_NWDN_TO;
_EmacMdioWaitForAccessComplete(macbase);
}
else
{
if (*PhyState&PHY_TIM_MASK)
*PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET));
else
_EmacMdioPhyTimeOut(macbase, PhyState);
}
}
void _EmacNwayWaitState(int macbase,int *PhyState)
{
int PhyNum,PhyStatus,NWAYadvertise,NegMode,i,j;
PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
MDIOUSERACCESS=MDIO_GO|MDIO_READ|(PHY_STATUS_REG<<21)|(PhyNum<<16);
_EmacMdioWaitForAccessComplete(macbase);
PhyStatus=MDIOUSERACCESS;
if (PhyStatus&NWAY_COMPLETE)
{
*PhyState|=PHY_CHANGE;
*PhyState&=~PHY_SPEED_MASK;
*PhyState&=~PHY_DUPLEX_MASK;
MDIOUSERACCESS=MDIO_GO|MDIO_READ|(NWAY_ADVERTIZE_REG<<21)|(PhyNum<<16);
_EmacMdioWaitForAccessComplete(macbase);
NWAYadvertise=MDIOUSERACCESS;
MDIOUSERACCESS=MDIO_GO|MDIO_READ|(NWAY_REMADVERTISE_REG<<21)|(PhyNum<<16);
_EmacMdioWaitForAccessComplete(macbase);
NegMode=MDIOUSERACCESS&NWAYadvertise;
NegMode&=(NWAY_FD100|NWAY_HD100|NWAY_FD10|NWAY_HD10);
if (NegMode==0)
{
NegMode=(NWAY_HD100|NWAY_HD10)&NWAYadvertise; /*or 10 ?? who knows, Phy is not MII compliant*/
}
for(j=0x8000,i=0;(i<16)&&((j&NegMode)==0);i++,j>>=1);
NegMode=j;
if (NegMode!=0)
{
if (PhyStatus&PHY_LINKED)
*PhyState=(*PhyState&~PHY_STATE_MASK)|LINKED;
else
*PhyState=(*PhyState&~PHY_STATE_MASK)|LINK_WAIT;
if (NegMode&(NWAY_FD100|NWAY_HD100))
*PhyState=(*PhyState&~PHY_SPEED_MASK)|(1<<PHY_SPEED_OFFSET);
if (NegMode&(NWAY_FD100|NWAY_FD10))
*PhyState=(*PhyState&~PHY_DUPLEX_MASK)|(1<<PHY_DUPLEX_OFFSET);
}
}
else
{
if (*PhyState&PHY_TIM_MASK)
*PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET));
else
_EmacMdioPhyTimeOut(macbase, PhyState);
}
}
void _EmacLinkWaitState(int macbase,int *PhyState)
{
int PhyStatus;
int PhyNum;
PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
#ifdef ACPEP
MDIOUSERACCESS = MDIO_GO|MDIO_WRITE|(PHY_LED_REG<<21)|(PhyNum<<16)|0x2132;
_EmacMdioWaitForAccessComplete(macbase);
#endif
MDIOUSERACCESS=MDIO_GO|MDIO_READ|(PHY_STATUS_REG<<21)|(PhyNum<<16);
_EmacMdioWaitForAccessComplete(macbase);
PhyStatus=MDIOUSERACCESS;
if (PhyStatus&PHY_LINKED)
{
*PhyState=(*PhyState&~PHY_STATE_MASK)|LINKED;
*PhyState|=PHY_CHANGE;
}
else
{
if (*PhyState&PHY_TIM_MASK)
*PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET));
else
_EmacMdioPhyTimeOut(macbase, PhyState);
}
}
void _EmacMdioPhyTimeOut(int macbase,int *PhyState)
{
/*Things you may want to do if we cannot establish link, like look for another Phy*/
/* and try it. */
}
void _EmacLinkedState(int macbase,int *PhyState)
{
int PhyNum;
PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
if (MDIOLINK&(1<<PhyNum)) return;
*PhyState&=~(PHY_STATE_MASK|PHY_TIM_MASK);
*PhyState|=PHY_CHANGE|NWAY_WAIT|PHY_NWDN_TO;
}
void _EmacDefaultState(int macbase,int *PhyState)
{
/*Awaiting a EmacMdioInit call */
*PhyState|=PHY_CHANGE;
}
void _EmacMdioWaitForAccessComplete(int macbase)
{
while((MDIOUSERACCESS&MDIO_GO)!=0)
{
}
}
/*User Calles********************************************************* */
void EmacMdioInit(int macbase, int *PhyState, int cpufreq)
{
/*Setup MII MDIO access regs */
MDIOCONTROL = 0x40008000|(cpufreq/1000000); /* Enable MDIO */
*PhyState=INIT;
#ifdef WA100
*PhyState |= ((MARVELL_EMAC_PHY & PHY_DEV_MASK) << PHY_DEV_OFFSET);
#endif
/*_EmacMdioDumpState(macbase,*PhyState); */
}
void EmacMdioSetPhyMode(int macbase,int *PhyState,int PhyMode)
{
int CurrentState;
*PhyState&=~PHY_SMODE_MASK;
if (PhyMode&PHY_LOOP) *PhyState|=SMODE_LOOP;
if (PhyMode&NWAY_AUTO) *PhyState|=SMODE_AUTO;
if (PhyMode&NWAY_FD100) *PhyState|=SMODE_FD100;
if (PhyMode&NWAY_HD100) *PhyState|=SMODE_HD100;
if (PhyMode&NWAY_FD10) *PhyState|=SMODE_FD10;
if (PhyMode&NWAY_HD10) *PhyState|=SMODE_HD10;
CurrentState=*PhyState&PHY_STATE_MASK;
if ((CurrentState==NWAY_START)||
(CurrentState==NWAY_WAIT) ||
(CurrentState==LINK_WAIT) ||
(CurrentState==LINKED) )
*PhyState=(*PhyState&~PHY_STATE_MASK)|FOUND|PHY_CHANGE;
/*_EmacMdioDumpState(macbase,*PhyState);*/
}
/* EmacMdioTic is called every 10 mili seconds to process Phy states */
int EmacMdioTic(int macbase,int *PhyState)
{
int CurrentState;
/*Act on current state of the Phy */
CurrentState=*PhyState;
switch(CurrentState&PHY_STATE_MASK)
{
case INIT: _EmacInitState(macbase,PhyState); break;
case FINDING: _EmacFindingState(macbase,PhyState); break;
case FOUND: _EmacFoundState(macbase,PhyState); break;
case NWAY_START: _EmacNwayStartState(macbase,PhyState); break;
case NWAY_WAIT: _EmacNwayWaitState(macbase,PhyState); break;
case LINK_WAIT: _EmacLinkWaitState(macbase,PhyState); break;
case LINKED: _EmacLinkedState(macbase,PhyState); break;
default: _EmacDefaultState(macbase,PhyState); break;
}
/*Dump state info if a change has been detected */
#if 0
if ((CurrentState&~PHY_TIM_MASK)!=(*PhyState&~PHY_TIM_MASK))
_EmacMdioDumpState(macbase,*PhyState);
#endif
/*Return state change to user */
if (*PhyState&PHY_CHNG_MASK)
{
*PhyState&=~PHY_CHNG_MASK;
return(TRUE);
}
else
return(FALSE);
}
/* EmacMdioGetDuplex is called to retreive the Duplex info */
int EmacMdioGetDuplex(int macbase,int *PhyState)
{
return(*PhyState&PHY_DUPLEX_MASK);
}
/* EmacMdioGetSpeed is called to retreive the Speed info */
int EmacMdioGetSpeed(int macbase,int *PhyState)
{
return(*PhyState&PHY_SPEED_MASK);
}
/* EmacMdioGetPhyNum is called to retreive the Phy Device Adr info */
int EmacMdioGetPhyNum(int macbase,int *PhyState)
{
return((*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET);
}
/* EmacMdioGetLinked is called to Determine if the LINKED state has been reached*/
int EmacMdioGetLinked(int macbase,int *PhyState)
{
return((*PhyState&PHY_STATE_MASK)==LINKED);
}
void EmacMdioLinkChange(int macbase,int *PhyState)
{
int PhyNum,PhyStatus;
PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
if (EmacMdioGetLinked(macbase,PhyState))
{
MDIOUSERACCESS=MDIO_GO|MDIO_READ|(PHY_STATUS_REG<<21)|(PhyNum<<16);
_EmacMdioWaitForAccessComplete(macbase);
PhyStatus=MDIOUSERACCESS;
if ((PhyStatus&PHY_LINKED)==0)
{
*PhyState&=~(PHY_TIM_MASK|PHY_STATE_MASK);
if (*PhyState&SMODE_AUTO)
{
MDIOUSERACCESS=MDIO_GO|MDIO_WRITE|(PHY_CONTROL_REG<<21)|(PhyNum<<16)|AUTO_NEGOTIATE_EN|RENEGOTIATE;
_EmacMdioWaitForAccessComplete(macbase);
*PhyState|=PHY_CHANGE|PHY_NWST_TO|NWAY_START;
}
else
{
*PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -