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

📄 mpllink.c

📁 NATIONAL公司DP83816芯片Linux下驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
//      NS_STATUS_FAILURE
//         The link state is not UP.
//
//*****************************************************************************
MPL_STATUS
   MplLinkUpComplete (
      IN NS_VOID      *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
   NS_UINT32 txCfgVal, rxCfgVal;

   ENTER(MplLinkUpComplete);

   // Check if the link is really up
   if (pMplCtx->linkStatus != MPL_LINK_STATUS_UP)
   {
      EXIT(MplLinkUpComplete);
      return NS_STATUS_FAILURE;
   }

   // Finish PHY link setup
   if (MplPhyLinkSetupComplete(pMplHandle) == NS_FALSE)
   {
      EXIT(MplLinkUpComplete);
      return NS_STATUS_FAILURE;
   }

   // Setup MAC operations
   txCfgVal = MPL_READ32(pMplCtx, TXCFG);
   rxCfgVal = MPL_READ32(pMplCtx, RXCFG);
   if (pMplCtx->linkCfg.duplex == MPL_LINK_DUPLEX_FULL)
   {
      // Set MAC to full duplex operation

      // Tx Engine - Ignore : Carrier Sense and Heartbeat
      MPL_WRITE32(pMplCtx, TXCFG, txCfgVal | CARRIER_IGNORE | SQE_IGNORE);

      // Rx Engine - Enable : FD operation
      MPL_WRITE32(pMplCtx, RXCFG, rxCfgVal | FULLDUPLEX_EN);
   }
   else
   {
      // Set MAC to half duplex operation

      // Tx Engine - Enable : Carrier Sense and Heartbeat
      MPL_WRITE32(pMplCtx, TXCFG, (txCfgVal & ~(CARRIER_IGNORE | SQE_IGNORE)));

      // Rx Engine - Disable : FD operation
      MPL_WRITE32(pMplCtx, RXCFG, (rxCfgVal & ~(FULLDUPLEX_EN)));
   }

   // Set Pause configuration on the MAC
   setPause(pMplCtx);

   EXIT(MplLinkUpComplete);
   return NS_STATUS_SUCCESS;
}

//*****************************************************************************
//   MplLinkInterrupt
//      Processes an incoming link related interrupt
//      At this time this is an MPL internal function (called from
//       MplIntteruptDoneInternal) 
//
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize
//
//   Return Value
//      NS_STATUS_SUCCESS
//         The interrupt was successfully fielded.
//
//*****************************************************************************
MPL_STATUS
   MplLinkInterrupt(
      IN NS_VOID   *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
  
   // Notify NSM, it will ensure further processing after
   //  taking care of synchronization issues
   NsmLinkStatusChange(pMplCtx->pClientHandle);
   
   return NS_STATUS_SUCCESS;
}

//*****************************************************************************
//        
//   linkCompare
//      Check if the requested link configuration matches the one on the 
//       device
//
//   Parameters
//      pMplCtx
//         Pointer to MPL Context
//
//   Return Value
//      NS_TRUE
//        The requested link configuration matches the one on the device
//      NS_FALSE
//        The requested link configuration does NOT match the one on the device
//
//*****************************************************************************
static
NS_BOOLEAN
   linkCompare(
      IN MPL_CONTEXT    *pMplCtx,
      IN MPL_LINK_CFG   *pLinkCfg
      )
{
   NS_BOOLEAN autoDone;

   ENTER(linkCompare);

   // FM: Check if this version of the PHY would need some patch work
   // If so, then we need to reestablish link
   if (MplPhyRequiresPatch(pMplCtx) == NS_TRUE)
   {
      EXIT(linkCompare);
      return NS_FALSE;
   }

   // Check if link is up, if not no match
   if (MplPhyGetLinkStatus(pMplCtx) != MPL_LINK_STATUS_UP)
   {
      EXIT(linkCompare);
      return NS_FALSE;
   }

   // Check if speed matches
   if (MplPhyGetLinkSpeed(pMplCtx) != pLinkCfg->speed)
   {
      EXIT(linkCompare);
      return NS_FALSE;
   }

   // Check if duplex matches
   if (MplPhyGetLinkDuplex(pMplCtx) != pLinkCfg->duplex)
   {
      EXIT(linkCompare);
      return NS_FALSE;
   }

   // Check if current pause matches
   if (pMplCtx->pauseType != pLinkCfg->pauseType)
   {
      EXIT(linkCompare);
      return NS_FALSE;
   }

   // Check if Auto-Neg is requested, but prev setup was in forced mode
   autoDone = MplPhyAutoNegDone(pMplCtx);
   if ((pLinkCfg->mode == MPL_LINK_MODE_AUTO) && (autoDone == NS_FALSE))
   {
      EXIT(linkCompare);
      return NS_FALSE;
   }

   // Check if forced mode is requested, but prev setup was in Auto-Neg mode
   if ((pLinkCfg->mode == MPL_LINK_MODE_FORCED) && (autoDone == NS_TRUE))
   {
      EXIT(linkCompare);
      return NS_FALSE;
   }

   // All OK, link cfg matches
   return NS_TRUE;
}

//*****************************************************************************
//        
//   setPause
//      Set the pause configurations on the MAC
//
//   Parameters
//      pMplCtx
//         Pointer to MPL Context
//
//   Return Value
//      None
//
//*****************************************************************************
static
NS_VOID
   setPause(
      IN MPL_CONTEXT    *pMplCtx
      )
{
   NS_UINT32 pcrVal = 0x0;
   MPL_LINK_CFG *pLinkCfg = &pMplCtx->linkCfg;

   ENTER(setPause);

   // Check if pause frame reception is enabled
   if (pMplCtx->pauseType & MPL_LINK_PAUSE_RECEIVE)
   {
      pcrVal |= RXPAUSE_EN | PS_MCAST | PS_DA;
   }

   // Check if pause frame transmission is enabled
   if (pMplCtx->pauseType & MPL_LINK_PAUSE_TRANSMIT)
   {
      // Status FIFO - Lower Threshold
      if (pLinkCfg->pauseRxSTLO == 0x0) 
         pcrVal |= PTHRESHLO_SFIFO_DIS; 
      else if (pLinkCfg->pauseRxSTLO < 2) 
              pcrVal |= PTHRESHLO_SFIFO2PKTS; 
           else if (pLinkCfg->pauseRxSTLO < 4) 
                   pcrVal |= PTHRESHLO_SFIFO4PKTS; 
                else 
                   pcrVal |= PTHRESHLO_SFIFO8PKTS; 
       
      
      // Status FIFO - Higher Threshold
      if (pLinkCfg->pauseRxSTHI < pLinkCfg->pauseRxSTLO) 
         pLinkCfg->pauseRxSTHI = pLinkCfg->pauseRxSTLO;

      if (pLinkCfg->pauseRxSTHI == 0x0) 
         pcrVal |= PTHRESHHI_SFIFO_DIS; 
      else if (pLinkCfg->pauseRxSTHI >= 4) 
              pcrVal |= PTHRESHHI_SFIFO8PKTS; 
           else if (pLinkCfg->pauseRxSTHI >= 2) 
                   pcrVal |= PTHRESHHI_SFIFO4PKTS; 
                else 
                   pcrVal |= PTHRESHHI_SFIFO2PKTS; 

      // Data FIFO - Lower Threshold
      if (pLinkCfg->pauseRxDALO == 0x0) 
         pcrVal |= PTHRESHLO_DFIFO_DIS; 
      else if (pLinkCfg->pauseRxDALO < 512) 
              pcrVal |= PTHRESHLO_DFIFO512; 
           else if (pLinkCfg->pauseRxDALO < 1024) 
                   pcrVal |= PTHRESHLO_DFIFO1024; 
                else 
                   pcrVal |= PTHRESHLO_DFIFO1536; 
      
      // Data FIFO - Higher Threshold
      if (pLinkCfg->pauseRxDAHI < pLinkCfg->pauseRxDALO) 
         pLinkCfg->pauseRxDAHI = pLinkCfg->pauseRxDALO;

      if (pLinkCfg->pauseRxDAHI == 0x0) 
         pcrVal |= PTHRESHHI_DFIFO_DIS; 
      else if (pLinkCfg->pauseRxDAHI >= 1024) 
              pcrVal |= PTHRESHHI_DFIFO1536; 
           else if (pLinkCfg->pauseRxDAHI >= 512) 
                   pcrVal |= PTHRESHHI_DFIFO1024; 
                else 
                   pcrVal |= PTHRESHHI_DFIFO512; 

      // Set pause counter
      pcrVal |= pLinkCfg->pauseCtr; 
   }

   MPL_WRITE32(pMplCtx, PCR, pcrVal);
   EXIT(setPause);
   return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -