📄 miilib.c
字号:
int retVal; /* convenient holder for return value */
/* run a check on the status bits of basic registers only */
retVal = miiBasicCheck (pPhyInfo, phyAddr);
if (retVal != OK)
return (retVal);
/* we know the auto-negotiation process has finished */
regAddr = MII_AN_EXP_REG;
MII_READ (phyAddr, regAddr, &phyExp, retVal);
if (retVal != OK)
return (ERROR);
/* check for faults detected by the parallel function */
if ((phyExp & MII_EXP_FAULT) == MII_EXP_FAULT)
{
MII_LOG (MII_DBG_ANY, ("miiAnCheck: fault expStat=0x%x\n"),
phyExp, 0, 0, 0, 0, 0);
return (ERROR);
}
/* check for remote faults */
regAddr = MII_AN_PRTN_REG;
MII_READ (phyAddr, regAddr, &phyPrtn, retVal);
if (retVal != OK)
return (ERROR);
if ((phyPrtn & MII_BP_FAULT) == MII_BP_FAULT)
{
MII_LOG (MII_DBG_ANY, ("miiAnCheck partner stat=0x%x\n"),
phyPrtn, 0, 0, 0, 0, 0);
return (ERROR);
}
regAddr = MII_AN_ADS_REG;
MII_READ (phyAddr, regAddr, &phyAds, retVal);
if (retVal == ERROR)
return (ERROR);
/* store the current registers values */
pPhyInfo->miiRegs.phyAds = phyAds;
pPhyInfo->miiRegs.phyPrtn = phyPrtn;
pPhyInfo->miiRegs.phyExp = phyExp;
/* find out the max common abilities */
negAbility = phyPrtn & phyAds & MII_ADS_TECH_MASK;
MII_LOG (MII_DBG_ANY, ("miiAnCheck phyAds=0x%x
phyPrtn=0x%x common=0x%x phyExp=0x%x\n"),
phyAds,
phyPrtn,
negAbility,
phyExp, 0, 0);
if (negAbility & MII_TECH_100BASE_TX_FD)
{
}
else if ((negAbility & MII_TECH_100BASE_TX) ||
(negAbility & MII_TECH_100BASE_T4))
{
MII_PHY_FLAGS_CLEAR (MII_PHY_FD);
}
else if (negAbility & MII_TECH_10BASE_FD)
{
MII_PHY_FLAGS_CLEAR (MII_PHY_100);
}
else if (negAbility & MII_TECH_10BASE_T)
{
MII_PHY_FLAGS_CLEAR (MII_PHY_FD);
MII_PHY_FLAGS_CLEAR (MII_PHY_100);
}
else
{
MII_LOG (MII_DBG_ANY, ("miiAnCheck fail!\n"),
0, 0, 0, 0, 0, 0);
return (ERROR);
}
/* handle some flags */
if (miiFlagsHandle (pPhyInfo, phyAddr) != OK)
return (ERROR);
MII_LOG (MII_DBG_ANY, ("miiAnCheck OK\n"),
0, 0, 0, 0, 0, 0);
return (OK);
}
/*******************************************************************************
* miiModeForce - force an operating mode for the PHY
*
* This routine forces an operating mode for the PHY whose address is
* specified in the parameter <phyAddr>. It also calls miiBasicCheck()
* to ensure a valid link has been established.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS miiModeForce
(
PHY_INFO * pPhyInfo, /* pointer to PHY_INFO structure */
UINT8 phyAddr /* address of a PHY */
)
{
UINT16 data; /* data to be written to the control reg */
UINT8 regAddr; /* PHY register */
int retVal; /* convenient holder for return value */
MII_LOG (MII_DBG_ANY, ("miiModeForce \n"),
0, 0, 0, 0, 0, 0);
/*
* force as a high priority as possible operating
* mode, not overlooking what the user dictated.
*/
data = MII_CR_NORM_EN;
if (MII_PHY_FLAGS_ARE_SET (MII_PHY_100))
{
data |= MII_CR_100;
}
if (MII_PHY_FLAGS_ARE_SET (MII_PHY_FD))
{
data |= MII_CR_FDX;
}
pPhyInfo->miiRegs.phyCtrl = data;
regAddr = MII_CTRL_REG;
/* try to establish the link */
MII_WRITE (phyAddr, regAddr, data, retVal);
if (retVal != OK)
return (ERROR);
/* run a check on the status bits of basic registers only */
if (miiBasicCheck (pPhyInfo, phyAddr) != OK)
return (ERROR);
/* handle some flags */
if (miiFlagsHandle (pPhyInfo, phyAddr) != OK)
return (ERROR);
return (OK);
}
/*******************************************************************************
* miiDefForce - force a default operating mode for the PHY
*
* This routine forces a default operating mode for the PHY whose address is
* specified in the parameter <phyAddr>. It also calls miiBasicCheck()
* to ensure a valid link has been established.
*
* RETURNS: OK or ERROR.
*
* ERRNO: S_miiLib_PHY_NO_ABLE
*
*/
LOCAL STATUS miiDefForce
(
PHY_INFO * pPhyInfo, /* pointer to PHY_INFO structure */
UINT8 phyAddr /* address of a PHY */
)
{
UINT16 data; /* data to be written to the control reg */
UINT8 regAddr; /* PHY register */
int retVal; /* convenient holder for return value */
UINT16 phyStatus; /* holder for the PHY status */
MII_LOG (MII_DBG_ANY, ("miiDefForce \n"),
0, 0, 0, 0, 0, 0);
/* translate user settings */
data = miiDefLookupTbl [(pPhyInfo->phyDefMode)];
/* find out what abilities the PHY features */
regAddr = MII_STAT_REG;
MII_READ (phyAddr, regAddr, &phyStatus, retVal);
if (retVal == ERROR)
return (ERROR);
if (data & MII_CR_100)
{
if (!(phyStatus & (MII_SR_TX_HALF_DPX
| MII_SR_TX_FULL_DPX
| MII_SR_T4)))
{
errnoSet (S_miiLib_PHY_NO_ABLE);
return (ERROR);
}
MII_PHY_FLAGS_SET (MII_PHY_100);
}
else
{
if (!(phyStatus & (MII_SR_10T_HALF_DPX
| MII_SR_10T_FULL_DPX)))
{
errnoSet (S_miiLib_PHY_NO_ABLE);
return (ERROR);
}
}
if (data & MII_CR_FDX)
{
if (!(phyStatus & (MII_SR_10T_FULL_DPX
| MII_SR_TX_FULL_DPX)))
{
errnoSet (S_miiLib_PHY_NO_ABLE);
return (ERROR);
}
MII_PHY_FLAGS_SET (MII_PHY_FD);
}
else
{
if (!(phyStatus & (MII_SR_10T_HALF_DPX
| MII_SR_TX_HALF_DPX)))
{
errnoSet (S_miiLib_PHY_NO_ABLE);
return (ERROR);
}
}
pPhyInfo->miiRegs.phyCtrl = data;
regAddr = MII_CTRL_REG;
/* force this specific operating mode, but do not check the link */
MII_WRITE (phyAddr, regAddr, data, retVal);
/* handle some flags */
if (miiFlagsHandle (pPhyInfo, phyAddr) != OK)
return (ERROR);
return (OK);
}
/**************************************************************************
*
* miiAbilFlagSet - set some ability flags
*
* This routine sets some ability flags for a later use.
*
* RETURNS: OK, always.
*/
LOCAL STATUS miiAbilFlagSet
(
PHY_INFO * pPhyInfo, /* pointer to PHY_INFO structure */
UINT8 phyAddr /* address of a PHY */
)
{
UINT8 regAddr; /* PHY register */
UINT16 phyStatus; /* holder for the PHY status */
int retVal; /* convenient holder for return value */
/* find out what abilities the PHY features */
regAddr = MII_STAT_REG;
MII_READ (phyAddr, regAddr, &phyStatus, retVal);
if (retVal == ERROR)
return (ERROR);
/* handle phy flags */
if (!(phyStatus & (MII_SR_TX_HALF_DPX
| MII_SR_TX_FULL_DPX
| MII_SR_T4)))
{
MII_PHY_FLAGS_CLEAR (MII_PHY_100);
}
if (!(phyStatus & (MII_SR_10T_FULL_DPX
| MII_SR_TX_FULL_DPX)))
{
MII_PHY_FLAGS_CLEAR (MII_PHY_FD);
}
if (!(phyStatus & (MII_SR_10T_HALF_DPX
| MII_SR_10T_FULL_DPX)))
{
MII_PHY_FLAGS_CLEAR (MII_PHY_10);
}
if (!(phyStatus & (MII_SR_TX_HALF_DPX
| MII_SR_10T_HALF_DPX)))
{
MII_PHY_FLAGS_CLEAR (MII_PHY_HD);
}
if (!(phyStatus & MII_SR_AUTO_SEL))
{
MII_LOG (MII_DBG_ANY, ("miiAbilFlagSet phy not
auto neg capable\n"),
0, 0, 0, 0, 0, 0);
MII_PHY_FLAGS_CLEAR (MII_PHY_AUTO);
}
return (OK);
}
/**************************************************************************
*
* miiPhyOptFuncSet - set the pointer to the MII optional registers handler
*
* This routine sets the function pointer in <optRegsFunc> to the MII
* optional, PHY-specific registers handler. The handler will be executed
* before the PHY's technology abilities are negotiated.
*
* RETURNS: N/A.
*/
void miiPhyOptFuncSet
(
FUNCPTR optRegsFunc /* function pointer */
)
{
if (optRegsFunc != NULL)
pPhyOptRegsRtn = optRegsFunc;
else
pPhyOptRegsRtn = NULL;
}
#ifdef MII_DBG
/**************************************************************************
*
* miiShow - show routine for MII library
*
* This is a show routine for the MII library
*
* RETURNS: OK, always.
*/
void miiShow
(
PHY_INFO * pPhyInfo /* pointer to PHY_INFO structure */
)
{
MII_LOG (MII_DBG_ANY, ("miiShow phyCtrl=0x%x phyStat =0x%x phyAds=0x%x
phyPrtn=0x%x phyExp=0x%x phyNpt=0x%x\n"),
pPhyInfo->miiRegs.phyCtrl,
pPhyInfo->miiRegs.phyStatus,
pPhyInfo->miiRegs.phyAds,
pPhyInfo->miiRegs.phyPrtn,
pPhyInfo->miiRegs.phyExp,
pPhyInfo->miiRegs.phyNext);
MII_LOG (MII_DBG_ANY, ("miiShow phyAddr=0x%x phyFlags=0x%x phySpeed=%d
phyMode=%s\n pDrvCtrl=0x%x \n"),
pPhyInfo->phyAddr,
pPhyInfo->phyFlags,
pPhyInfo->phySpeed,
pPhyInfo->phyMode,
pPhyInfo->pDrvCtrl,
0);
}
/**************************************************************************
*
* miiRegsGet - get the contents of MII registers
*
* This routine gets the contents of the first <regNum> MII registers,
* and, if <buff> is not NULL, copies them to the space pointed to
* by <buff>.
*
* RETURNS: OK, or ERROR if could not perform the read.
*/
STATUS miiRegsGet
(
PHY_INFO * pPhyInfo, /* pointer to PHY_INFO structure */
UINT regNum, /* number of registers to display */
UCHAR * buff /* where to read registers to */
)
{
int retVal; /* convenient holder for return value */
int i; /* a counter */
if (buff == NULL)
return (OK);
regNum = (regNum > MII_MAX_REG_NUM) ? MII_MAX_REG_NUM : regNum;
/* Read all the registers the user specified */
for (i = 0; i < regNum; i++)
{
MII_READ (pPhyInfo->phyAddr, i, (UINT16 *) &buff [2 * i], retVal);
if (retVal != OK)
return (ERROR);
}
return (OK);
}
#endif /* MII_DBG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -