📄 mplphy.c
字号:
NS_UINT32 volatile *regAddr;
// Using internal PHY
regAddr = (NS_UINT32 volatile *) ((NS_UINT8 *)pMplCtx->pRegsBase +
PHY_MII_REG_BASE + (regIndex << 2));
regData = MPL_LTOH32(OaiIoRead32(pMplCtx->pClientHandle, regAddr));
}
#else
{
// Using external PHY - Go thru MDIO
regData = mdioReadReg(pMplCtx, phyDevAddr, regIndex);
}
#endif // MPL_EXTERNAL_PHY
return regData;
}
//*****************************************************************************
// MplPhyMdioWrite
// Write Phy register
//
// Parameters
// pMplHandle
// MPL device handle
// phyDevAddr
// Device addr of the Phy
// regIndex
// Register to write(in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1)
// regData
// Data to write
//
// Return Value
// None
//
//*****************************************************************************
NS_VOID
MplPhyMdioWrite(
IN NS_VOID *pMplHandle,
IN NS_UINT phyDevAddr,
IN NS_UINT regIndex,
IN NS_UINT32 regData
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
// If we are using the internal PHY then go thru the simple register
// API to access the PHY registers, if not do bit-banging on MDIO
#ifndef MPL_EXTERNAL_PHY
{
NS_UINT32 volatile *regAddr;
// Using internal PHY
regAddr = (NS_UINT32 volatile *) ((NS_UINT8 *)pMplCtx->pRegsBase +
PHY_MII_REG_BASE + (regIndex << 2));
OaiIoWrite32(pMplCtx->pClientHandle, regAddr, MPL_HTOL32(regData));
}
#else
{
// Use MDIO for external PHY
mdioWriteReg(pMplCtx, phyDevAddr, regIndex, (NS_UINT16)regData);
}
#endif // MPL_EXTERNAL_PHY
return;
}
//*****************************************************************************
// phyTimerHandler
// Applies short cable patch at the end of 100msec
//
// Parameters
// pMplCtx
// MPL device handle
//
// Return Value
// None
//
//*****************************************************************************
NS_VOID
phyTimerHandler(
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
NS_UINT32 regVal;
ENTER(MplPhyTimer);
MPL_WRITE32(pMplCtx, PAGE, 0x0001);
regVal = MPL_READ32(pMplCtx, DSPCFG);
regVal &= 0x0FFF;
MPL_WRITE32(pMplCtx, DSPCFG, regVal | 0x1000);
OaiSleep(100); //100usec
regVal = MPL_READ32(pMplCtx, TDATA);
regVal &= 0xFF;
if (regVal < 0x80 || regVal > 0xd7 )
{
MPL_WRITE32(pMplCtx, TDATA, 0x00E8);
regVal = MPL_READ32(pMplCtx, DSPCFG);
MPL_WRITE32(pMplCtx, DSPCFG, regVal | 0x0020);
}
MPL_WRITE32(pMplCtx, PAGE, 0x0);
EXIT(MplPhyTimer);
return;
}
#ifndef MPL_EXTERNAL_PHY
//*****************************************************************************
// phyAdjust
// Apply optimization patch
//
// Parameters
// pMplCtx
// MPL device context
//
// Return Value
// None
//
//*****************************************************************************
static
NS_VOID
phyAdjust(
IN MPL_CONTEXT *pMplCtx
)
{
NS_UINT32 regVal;
if (pMplCtx->srr == 0x0200)
{
// MacPhy-1
MPL_WRITE32(pMplCtx, PAGE, 0x0001);
MPL_WRITE32(pMplCtx, PMDCSR, 0x0802);
MPL_WRITE32(pMplCtx, FCOCTL, 0x0010);
MPL_WRITE32(pMplCtx, SDCFG, 0x0333);
MPL_WRITE32(pMplCtx, PGMCGM, 0x0860);
MPL_WRITE32(pMplCtx, TMR, 0x2100);
MPL_WRITE32(pMplCtx, CDCT12, 0x4f48);
MPL_WRITE32(pMplCtx, PAGE, 0x0);
regVal = MPL_READ32(pMplCtx, TENBT);
MPL_WRITE32(pMplCtx, TENBT, regVal | 0x04);
}
else if ((pMplCtx->srr & 0xFF00) == 0x0300)
{
// MacPhy-1
MPL_WRITE32(pMplCtx, PAGE, 0x0001);
MPL_WRITE32(pMplCtx, PMDCSR, 0x189c);
MPL_WRITE32(pMplCtx, TDATA, 0x0000);
MPL_WRITE32(pMplCtx, DSPCFG, 0x5040);
MPL_WRITE32(pMplCtx, SDCFG, 0x008c);
MPL_WRITE32(pMplCtx, PAGE, 0x0);
}
else if (((pMplCtx->srr & 0xFF00) == 0x0400) ||
((pMplCtx->srr & 0xFF00) == 0x0500))
{
// MacPhy-2
MPL_WRITE32(pMplCtx, PAGE, 0x0001);
MPL_WRITE32(pMplCtx, PMDCSR , 0x189C );
MPL_WRITE32(pMplCtx, PAGE, 0x0);
}
return;
}
//*****************************************************************************
// atanPatchUp
// Apply ATAN switch link-up patch
//
// Parameters
// pMplCtx
// MPL device context
//
// Return Value
// None
//
//*****************************************************************************
static
NS_VOID
atanPatchUp(
IN MPL_CONTEXT *pMplCtx
)
{
MPL_WRITE32(pMplCtx, PAGE, 0x0001);
MPL_WRITE32(pMplCtx, DSPTST, 0x80b7);
MPL_WRITE32(pMplCtx, PAGE, 0x0);
return;
}
//*****************************************************************************
// atanPatchDown
// Remove ATAN switch link-up patch
//
// Parameters
// pMplCtx
// MPL device context
//
// Return Value
// None
//
//*****************************************************************************
static
NS_VOID
atanPatchDown(
IN MPL_CONTEXT *pMplCtx
)
{
MPL_WRITE32(pMplCtx, PAGE, 0x0001);
MPL_WRITE32(pMplCtx, DSPTST, 0x00b7);
MPL_WRITE32(pMplCtx, PAGE, 0x0);
return;
}
#endif //MPL_EXTERNAL_PHY
//*****************************************************************************
// mdioIdle
// MDIO clk delay
//
// Parameters
// pMplCtx
// MPL device context
//
// Return Value
// None
//
//*****************************************************************************
static
NS_VOID
mdioIdle(
IN MPL_CONTEXT *pMplCtx
)
{
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR);
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR | MDCLK);
return;
}
//*****************************************************************************
// mdioSync
// MDIO bus sync
//
// Parameters
// pMplCtx
// MPL device context
//
// Return Value
// None
//
//*****************************************************************************
static
NS_VOID
mdioSync(
IN MPL_CONTEXT *pMplCtx
)
{
NS_UINT32 i;
// Write 32 logic ones
for (i = 0x0; i < 32; i++)
mdioIdle(pMplCtx);
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR);
return;
}
#ifdef MPL_EXTERNAL_PHY
//*****************************************************************************
// mdioReadReg
// Read a Phy register via MDIO
//
// Parameters
// pMplHandle
// MPL device handle
// phyDevAddr
// Device addr of the Phy
// regIndex
// Register to read (in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1)
//
// Return Value
// Reg data
//
//*****************************************************************************
NS_UINT16
mdioReadReg(
IN MPL_CONTEXT *pMplCtx,
IN NS_UINT phyDevAddr,
IN NS_UINT regIndex
)
{
NS_UINT32 mdioCmd;
NS_UINT32 oData = 0x0, iData, i;
// Create the read cmd seq
mdioCmd = MII_READ | (phyDevAddr << MII_ADDR_OFF) |
(regIndex << MII_REG_OFF);
// Sync up the bus
mdioSync(pMplCtx);
// Send Start + Read Cmd + Phy Addr + Reg Offset
for (i = 0x0; i < 15 ; i++)
{
if (mdioCmd & 0x80000000)
{
// Write a 1-bit
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDDIR));// Clk Low,Data High
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDCLK | MDDIR));//Clk Hi,Data High
}
else
{
// Write a 0-bit
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, MDDIR);// Clk Low, Data Low
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, (MDCLK | MDDIR));// Clk Hi, Data Low
}
// Next bit
mdioCmd <<= 1;
}
// Read-in data
for (i = 0x0; i < 16; i++)
{
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, MDIO); // Clock Low, Data High
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDCLK)); // Clock High, Data High
iData = MPL_READ32(pMplCtx, MEAR);
oData <<= 1;
if (iData & MDIO)
oData |= 1;
}
// Write an idle bit
mdioIdle(pMplCtx);
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR);
return (NS_UINT16)oData;
}
//*****************************************************************************
// mdioWriteReg
// Write Phy register
//
// Parameters
// pMplHandle
// MPL device handle
// phyDevAddr
// Device addr of the Phy
// regIndex
// Register to write(in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1)
// regData
// Data to write
//
// Return Value
// None
//
//*****************************************************************************
NS_VOID
mdioWriteReg(
IN MPL_CONTEXT *pMplCtx,
IN NS_UINT phyDevAddr,
IN NS_UINT regIndex,
IN NS_UINT16 regData
)
{
NS_UINT32 mdioCmd, i;
// Create the read cmd seq
mdioCmd = MII_WRITE | (phyDevAddr << MII_ADDR_OFF) |
(regIndex << MII_REG_OFF) | regData;
// Sync up the bus
mdioSync(pMplCtx);
// Send Start + Write Cmd + Phy Addr + Reg Offset + Reg Data
for (i = 0x0; i < 32; i++)
{
if (mdioCmd & 0x80000000)
{
// Write a 1-bit
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDDIR));// Clk Low,Data High
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDCLK | MDDIR));//Clk Hi,Data High
}
else
{
// Write a 0-bit
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, MDDIR);// Clk Low, Data Low
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, (MDCLK | MDDIR));// Clk Hi, Data Low
}
// Next bit
mdioCmd <<= 1;
}
// Write an idle bit
mdioIdle(pMplCtx);
OaiSleep(1);
MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR);
return;
}
#endif // MPL_EXTERNAL_PHY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -