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

📄 mplphy.c

📁 NATIONAL公司DP83816芯片Linux下驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
      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 + -