📄 miilib.c
字号:
MII_WRITE (phyAddr, regAddr, data, retVal);
if (retVal != OK)
return (ERROR);
while (ix++ < pPhyInfo->phyMaxDelay)
{
MII_SYS_DELAY (pPhyInfo->phyDelayParm);
MII_READ (phyAddr, regAddr, &data, retVal);
if (retVal == ERROR)
return (ERROR);
if (!(data & MII_CR_RESET))
break;
}
if (ix >= pPhyInfo->phyMaxDelay)
{
MII_LOG (MII_DBG_ANY, ("miiDiag reset fail\n"),
0, 0, 0, 0, 0, 0);
return (ERROR);
}
/* re-enable the chip */
data = MII_CR_NORM_EN;
MII_WRITE (phyAddr, regAddr, data, retVal);
if (retVal != OK)
{
MII_LOG (MII_DBG_ANY, ("miiDiag write fail\n"),
0, 0, 0, 0, 0, 0);
return (ERROR);
}
/* check isolate bit is deasserted */
ix = 0;
while (ix++ < pPhyInfo->phyMaxDelay)
{
MII_SYS_DELAY (pPhyInfo->phyDelayParm);
MII_READ (phyAddr, regAddr, &data, retVal);
if (retVal != OK)
{
MII_LOG (MII_DBG_ANY, ("miiDiag read fail\n"),
0, 0, 0, 0, 0, 0);
return (ERROR);
}
if (!(data & MII_CR_ISOLATE))
break;
}
if (ix >= pPhyInfo->phyMaxDelay)
{
MII_LOG (MII_DBG_ANY, ("miiDiag de-isolate fail\n"),
0, 0, 0, 0, 0, 0);
return (ERROR);
}
MII_LOG (MII_DBG_ANY, ("miiDiag... ends\n"),
0, 0, 0, 0, 0, 0);
return (OK);
}
/*******************************************************************************
* miiPhyIsolate - isolate the PHY device
*
* This routine isolates the PHY device whose address is specified in
* the parameter <isoPhyAddr>.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS miiPhyIsolate
(
PHY_INFO * pPhyInfo, /* pointer to PHY_INFO structure */
UINT8 isoPhyAddr /* address of a PHY to be isolated */
)
{
UINT8 regAddr; /* PHY register */
UINT16 ix = 0; /* a counter */
UINT16 data; /* data to be written to the control reg */
int retVal; /* convenient holder for return value */
if (isoPhyAddr == MII_PHY_NULL)
return (OK);
data = MII_CR_ISOLATE;
regAddr = MII_CTRL_REG;
MII_WRITE (isoPhyAddr, regAddr, data, retVal);
if (retVal != OK)
return (ERROR);
/* check isolate bit is asserted */
while (ix++ < pPhyInfo->phyMaxDelay)
{
MII_SYS_DELAY (pPhyInfo->phyDelayParm);
MII_READ (isoPhyAddr, regAddr, &data, retVal);
if (retVal != OK)
return (ERROR);
if ((data & MII_CR_ISOLATE))
break;
}
if (ix >= pPhyInfo->phyMaxDelay)
{
MII_LOG (MII_DBG_ANY, ("miiPhyIsolate fail\n"),
0, 0, 0, 0, 0, 0);
return (ERROR);
}
MII_LOG (MII_DBG_ANY, ("miiPhyIsolate... ends\n"),
0, 0, 0, 0, 0, 0);
return (OK);
}
/*******************************************************************************
* miiPhyFeatureSet - set some generic features for the PHYs
*
* This routine sets some generic features for the PHYs.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS miiPhyFeatureSet
(
PHY_INFO * pPhyInfo /* pointer to PHY_INFO structure */
)
{
UINT16 ix = 0; /* a counter */
int retVal; /* convenient holder for return value */
if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_PWR_DOWN))
&& !(MII_PHY_FLAGS_ARE_SET (MII_PHY_ISO)))
return (OK);
for (ix = 0; ix < MII_MAX_PHY_NUM; ix++)
{
/* check the PHY is there */
retVal = miiProbe (pPhyInfo, ix);
/* deal with the error condition if possible */
if (retVal == ERROR)
{
if (errno != S_miiLib_PHY_NULL)
return (ERROR);
else
{
if (ix == (MII_MAX_PHY_NUM - 1))
return (ERROR);
/* no PHY was found with this address: keep scanning */
errno = 0;
continue;
}
}
/* set it in power down mode */
if (MII_PHY_FLAGS_ARE_SET (MII_PHY_PWR_DOWN))
{
if (miiPhyPwrDown (pPhyInfo, ix) == ERROR)
return (ERROR);
}
/* eletrically isolate it from the MII interface */
if (MII_PHY_FLAGS_ARE_SET (MII_PHY_ISO))
{
if (miiPhyIsolate (pPhyInfo, ix) == ERROR)
return (ERROR);
}
}
return (OK);
}
/*******************************************************************************
* miiPhyPwrDown - put the PHY in power down mode
*
* This routine puts the PHY specified in <phyAddr> in power down mode.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS miiPhyPwrDown
(
PHY_INFO * pPhyInfo, /* pointer to PHY_INFO structure */
UINT8 phyAddr /* phy to be put in power down mode */
)
{
int retVal; /* convenient holder for return value */
UINT8 regAddr; /* PHY register */
UINT16 data; /* data to be written to the control reg */
if (phyAddr == MII_PHY_NULL)
return (OK);
data = MII_CR_POWER_DOWN;
regAddr = MII_CTRL_REG;
MII_WRITE (phyAddr, regAddr, data, retVal);
return (retVal);
}
/*******************************************************************************
* miiPhyBestModeSet - set the best operating mode for a PHY
*
* This routine sets the best operating mode for a PHY looking at the
* parameters in <pPhyInfo>. It may call miiAutoNegotiate (), and/or miiModeForce ().
*
* SEE ALSO: miiAutoNegotiate (), miiModeForce ().
*
* RETURNS: OK or ERROR.
*
* ERRNO: S_miiLib_PHY_LINK_DOWN
*
*/
LOCAL STATUS miiPhyBestModeSet
(
PHY_INFO * pPhyInfo /* pointer to PHY_INFO structure */
)
{
UINT16 ix; /* a counter */
int retVal; /* holder for return value */
UINT8 phyAddr; /* address of a PHY */
UINT32 phyFlags; /* default PHY's flags */
BOOL found = FALSE; /* no PHY has been found */
/* store the default phy's flags */
phyFlags = pPhyInfo->phyFlags;
/*
* there may be as many as 32 PHYs, with distinct logical addresses
* Start with the one the user suggested and, in case of failure in
* establishink a valid link, scan the whole range.
*/
for (ix = 0; ix < MII_MAX_PHY_NUM; ix++)
{
phyAddr = (ix + pPhyInfo->phyAddr) % MII_MAX_PHY_NUM;
/* check the PHY is there */
retVal = miiProbe (pPhyInfo, phyAddr);
MII_LOG (MII_DBG_ANY,
("miiPhyBestModeSet called miiProbe, ix=%d, retVal=%d\n"),
((int)ix),((int)retVal),0,0,0,0);
/* deal with the error condition if possible */
if (retVal == ERROR)
{
if (errno != S_miiLib_PHY_NULL)
return (ERROR);
else
{
if (ix == (MII_MAX_PHY_NUM - 1))
return (ERROR);
/* no PHY was found with this address: keep scanning */
errno = 0;
continue;
}
}
MII_LOG (MII_DBG_ANY,
("miiPhyBestModeSet FOUND THE PHY.\n"),0,0,0,0,0,0);
found = TRUE;
/* run some diagnostics */
if (miiDiag (pPhyInfo, phyAddr) != OK)
return (ERROR);
/* restore the default flags, miiAbilFlagSet may change them */
pPhyInfo->phyFlags = phyFlags;
/* find out the PHY's abilities and set flags accordingly */
if (miiAbilFlagSet (pPhyInfo, phyAddr) != OK)
return (ERROR);
/* chek with the BSP if we need to do something else before
* we try and establish the link
*/
if (pPhyOptRegsRtn != NULL)
(* pPhyOptRegsRtn) (pPhyInfo);
/*
* start the auto-negotiation process,
* unless the user dictated the contrary.
*/
if (pPhyInfo->phyFlags & MII_PHY_AUTO)
if (miiAutoNegotiate (pPhyInfo, phyAddr) == OK)
{
/* store this PHY and return */
pPhyInfo->phyAddr = phyAddr;
return (OK);
}
/*
* the auto-negotiation process did not succeed
* in establishing a valid link: try to do it
* manually, enabling as many high priority abilities
* as possible.
*/
if (miiModeForce (pPhyInfo, phyAddr) == OK)
{
/* store this PHY and return */
pPhyInfo->phyAddr = phyAddr;
return (OK);
}
}
/* restore the default flags, miiAbilFlagSet may have changed them */
pPhyInfo->phyFlags = phyFlags;
/* set errno, since we did not establish a valid link */
errnoSet (S_miiLib_PHY_LINK_DOWN);
return (ERROR);
}
/*******************************************************************************
* miiPhyDefModeSet - set the default operating mode for a PHY
*
* This routine sets the default operating mode for a PHY looking at the
* parameters in <pPhyInfo>. It calls miiDefForce () for each PHY found.
*
* SEE ALSO: miiDefForce ().
*
* RETURNS: OK or ERROR.
*
*/
LOCAL STATUS miiPhyDefModeSet
(
PHY_INFO * pPhyInfo /* pointer to PHY_INFO structure */
)
{
UINT16 ix; /* a counter */
int retVal; /* holder for return value */
UINT8 phyAddr; /* address of a PHY */
/* try to establish a default operating mode, do not check the link! */
for (ix = 0; ix < MII_MAX_PHY_NUM; ix++)
{
phyAddr = (ix + pPhyInfo->phyAddr) % MII_MAX_PHY_NUM;
/* check the PHY is there */
retVal = miiProbe (pPhyInfo, phyAddr);
/* deal with the error condition if possible */
if (retVal == ERROR)
{
if (errno != S_miiLib_PHY_NULL)
return (ERROR);
else
{
if (ix == (MII_MAX_PHY_NUM - 1))
return (ERROR);
/* no PHY was found with this address: keep scanning */
errno = 0;
continue;
}
}
/*
* Force default parameters: field phyDefMode in the PHY info
* structure. Return OK even if the link is not up.
*/
retVal = miiDefForce (pPhyInfo, phyAddr);
if (retVal == OK)
{
/* store this PHY and return */
pPhyInfo->phyAddr = phyAddr;
return (OK);
}
/* if the PHY does not have the default abilities... */
if (errno == S_miiLib_PHY_NO_ABLE)
{
if (ix == (MII_MAX_PHY_NUM - 1))
return (ERROR);
errno = 0;
continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -