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

📄 mplintr.c

📁 NATIONAL公司DP83816芯片Linux下驱动
💻 C
字号:

//******************************************************************************
//
//  MPLINTR.C
//
//  Copyright (c) 2004 National Semiconductor Corporation.
//  All Rights Reserved
//
//  MPL Interrupt Processing.
//
//  This file contains the API implementations for
//     o MPL interrupt configuration
//     o Enabling and Disabling interrupts
//     o Processing interrupts
//
//******************************************************************************

#include <mplinternal.h>

//*****************************************************************************
//   MplInterruptCfg
//      Configure the interrupt hold-off delay (for interrupt coalescing).
//
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize
//      delayMSec
//         Interrupt hold off delay in microseconds
//      transmitHold
//         Interrupts hold off based on number of Tx pkts sent
//      receiveHold
//         Interrupts hold off based on number of Rx pkts sent
//
//   Return Value
//      NS_STATUS_SUCCESS
//         Interrupts were successfully configured
//
//*****************************************************************************
MPL_STATUS
   MplInterruptCfg (
      IN NS_VOID   *pMplHandle,
      IN NS_UINT    delayMSec,
      IN NS_UINT    transmitHold,
      IN NS_UINT    receiveHold
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
   NS_UINT32 ihrVal = 0x0;

   MPL_CENTER(DZONE_MPL_INTR, MplInterruptCfg);

   // Force values to max supported
   if (delayMSec > pMplCtx->caps.intrCaps.maxTimerHold)
   {
      delayMSec = pMplCtx->caps.intrCaps.maxTimerHold;
   }

   if (transmitHold > pMplCtx->caps.intrCaps.maxTransmitHold)
   {
      transmitHold = pMplCtx->caps.intrCaps.maxTransmitHold;
   }

   if (receiveHold  > pMplCtx->caps.intrCaps.maxReceiveHold)
   {
      receiveHold = pMplCtx->caps.intrCaps.maxReceiveHold;
   }

   // Decide if we need to use the lower resolution clock
   if (delayMSec >= 100)
   {
      // Compute clocks
      delayMSec = delayMSec / 100;
   }
   else
   {
      ihrVal |= INTHLDTMR_4US;

      // Compute clocks
      delayMSec = delayMSec / 4;
   }

   // Write on the device
   MPL_WRITE32(pMplCtx, IHR, ihrVal | delayMSec | 
                  (transmitHold << INTHLDCNCL_TXPKTS_SHIFT) |
                  (receiveHold  << INTHLDCNCL_RXPKTS_SHIFT));

   MPL_CEXIT(DZONE_MPL_INTR, MplInterruptCfg);
   return NS_STATUS_SUCCESS;
}

//*****************************************************************************
//   MplInterruptEnable
//      Enable the interrupt line on the network device.
//
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize
//
//   Return Value
//      NS_STATUS_SUCCESS
//         Interrupts were successfully enabled
//
//*****************************************************************************
MPL_STATUS
   MplInterruptEnable (
      IN NS_VOID   *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;

   // Enable Interrupts
   MPL_WRITE32(pMplCtx, IER, INT_EN);

   return NS_STATUS_SUCCESS;
}

//*****************************************************************************
//   MplInterruptDisable
//      Disable the interrupt line on the network device.
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize
//   Return Value
//      NS_STATUS_SUCCESS
//         Interrupts were successfully disabled
//
//*****************************************************************************
MPL_STATUS
   MplInterruptDisable (
      IN NS_VOID   *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;

   // Disable Interrupts
   MPL_WRITE32(pMplCtx, IER, 0x0);

   return NS_STATUS_SUCCESS;
}

//*****************************************************************************
//   MplInterruptCheck
//      Checks for and clears pending interrupt conditions on the device.
//
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize.
//      pIrqsPresent
//         A caller supplied variable in which the current interrupting 
//          conditions are noted.
//
//   Return Value
//      NS_STATUS_SUCCESS
//         The current interrupting conditions were successfully read from the 
//          device and pending events do exist.
//      NS_STATUS_FAILURE
//         Interrupts are currently disabled, so no interrupt conditions exist.
//          or the mask bits and status bits don't match
//
//*****************************************************************************
MPL_STATUS
   MplInterruptCheck (
      IN NS_VOID    *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;

   // Make sure interrupts are currently enabled i.e. this is not a
   //  spurious interrupt
   if (MPL_READ32(pMplCtx, IER) & INT_EN)
   {
      //Disable Interrupts FM: Make this version specific
      MPL_WRITE32(pMplCtx, IER, 0x0);

      // Read ISR
      pMplCtx->isrReg = MPL_READ32(pMplCtx, ISR);

      // Rev A3 (AspenPhy) don't seem to clear int on mere read of ISR
      MPL_READ32(pMplCtx, MISR);

      // Make sure this interrupt reason is not masked
      if (pMplCtx->isrReg & pMplCtx->imrReg)
      {
          return NS_STATUS_SUCCESS;
      }
      else
      {
         // Interrupts will be disabled after reading the ISR
         //  so reenable it
         MPL_WRITE32(pMplCtx, IER, INT_EN);
      }
   }

   return NS_STATUS_FAILURE;
}

//*****************************************************************************
//   MplInterruptCheckTransmit
//      Checks for the presence of transmit engine related interrupt events.
//
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize.
//
//   Return Value
//      NS_STATUS_SUCCESS
//         Pending transmit related events exist on the device
//      NS_STATUS_FAILURE
//         No transmit related events detected.
//
//*****************************************************************************
MPL_STATUS
   MplInterruptCheckTransmit (
      IN NS_VOID   *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;

   // Check if any Tx events are triggered
   if (pMplCtx->isrReg & (TXOK | TXDESC | TXERR | TXIDLE | TXUNDERRUN))
   {
       return NS_STATUS_SUCCESS;
   }
   else
   {
       return NS_STATUS_FAILURE;
   }
}


//*****************************************************************************
//   MplInterruptCheckReceive
//      Checks for the presence of receive engine related interrupt events.
//
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize.
//
//   Return Value
//      NS_STATUS_SUCCESS
//         Pending receive related events exist on the device
//      NS_STATUS_FAILURE
//         No receive related events detected.
//
//*****************************************************************************
MPL_STATUS
   MplInterruptCheckReceive (
      IN NS_VOID   *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;

   // Check if any Rx events are triggered
   if (pMplCtx->isrReg & (RXOK | RXDESC | RXERR | RXEARLY | RXOVERUN))
   {
       return NS_STATUS_SUCCESS;
   }
   else
   {
       return NS_STATUS_FAILURE;
   }
}


//*****************************************************************************
//   MplInterruptCheckInternal
//      Checks for the presence of MAC/PHY internal (non data transfer related)
//       interrupt events.
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize.
//   Return Value
//      NS_STATUS_SUCCESS
//         Pending internal events exist on the device
//      NS_STATUS_FAILURE
//         No internal events detected.
//
//*****************************************************************************
MPL_STATUS
   MplInterruptCheckInternal (
      IN NS_VOID   *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;

   // Check if any Tx events are triggered
   if (pMplCtx->isrReg & (MIBSTATS | SW_INT | WOL_EVENT | PHYSTSCHANGE | RXIDLE|
                            RXSTSFIFO_OVRN | RXRST_COMPLETE | TXRST_COMPLETE))
   {
       return NS_STATUS_SUCCESS;
   }
   else
   {
       return NS_STATUS_FAILURE;
   }
}

//*****************************************************************************
//   MplInterruptDoneInternal
//      Processes device’s internal (non data-type) interrupts.
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize
//      maxEvents
//         The maximum internal events (e.g. link change) that MPL should 
//          process before returning back to the caller.
//   Return Value
//      NS_STATUS_SUCCESS
//         The internal event was successfully handled.
//      NS_STATUS_ABORTED
//         The processing was aborted since the maximum event count specified 
//          was met.
//
//*****************************************************************************
MPL_STATUS
   MplInterruptDoneInternal (
      IN NS_VOID   *pMplHandle,
      IN NS_UINT    maxEvents
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;

   if (pMplCtx->isrReg & RXIDLE) 
   {
       // Rx-Idle - For Perf tuning purposes
   }

   if (pMplCtx->isrReg & MIBSTATS) 
   {
       // Go read MIB statistics
   }

   if (pMplCtx->isrReg & WOL_EVENT) 
   {
       // Power Management Event, i.e. Wake-On-LAN
   }

   if (pMplCtx->isrReg & PHYSTSCHANGE) 
   {
       // PHY status change: link is up or down
       MplLinkInterrupt(pMplCtx);
   }

   if (pMplCtx->isrReg & SW_INT) 
   {
       // Software Interrupt, set when SWI bit is set in CR
   }

   if (pMplCtx->isrReg & HIORDER_INT) 
   {
       if (pMplCtx->isrReg & RXSTSFIFO_OVRN) 
       {
          //  Rx FIFO overrun (RXOVR)
       }
   }

   if (pMplCtx->isrReg & RXRST_COMPLETE) 
   {
       // recv reset complete
   }

   if (pMplCtx->isrReg & TXRST_COMPLETE) 
   {
       // xmit reset complete
   }

   return NS_STATUS_SUCCESS;
}

⌨️ 快捷键说明

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