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

📄 nsmdiag.c

📁 NATIONAL公司DP83816芯片Linux下驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
//
//   Return Value
//      NS_STATUS_SUCCESS
//         The packet was successfully sent
//      NS_STATUS_INVALID_PARM
//         The specified packet handle was not found 
//         Note: This could happen when the status queue was oveflowed too
//      NS_STATUS_FAILURE
//         The packet completed with a failure
//      NS_STATUS_RESOURCES
//         The pkt could not be copied since the buffer is of smaller size
//*****************************************************************************
static NS_UINT
   pktStatus(
      NSM_CONTEXT     *adapter,
      MPL_LIST        *pList,
      MPL_PKT_FRAG   **ppTailFrag,
      spinlock_t      *pLock,
      NS_APP_XFER_CMD *pCmd,
      NS_UINT8        *pData)
{
   DIAG_PKT *dPkt;
   MPL_PKT_FRAG *pFrag, *pTail, *pHead = NULL;
   MPL_LIST_NODE *node;
   NS_UINT status = NS_STATUS_INVALID_PARM, dst, fragCnt;

   NI(pktStatus);   

   // Take lock and search for the pkt in the done list
   spin_lock_irq(pLock);
   for (node = MPL_LIST_GET_HEAD(pList); 
           MPL_LIST_CHK_END(pList, node) == NS_FALSE; 
               node = MPL_LIST_GET_NEXT(node))
   {
      dPkt = MPL_LIST_GET_ENTRY(node, DIAG_PKT, link);

      // Match the app pkt handle with what we have
      if (dPkt->appPktHandle == pCmd->pktHandle)
      {
         // Found the requested pkt

         // Prep response
         pCmd->numDesc = dPkt->numDesc;
         pCmd->cmdSts = dPkt->cmdSts;
         pCmd->packetSize = dPkt->pktSize;
         status = dPkt->pktStatus;

         // Note head frag pointer and detach from packet
         pHead = dPkt->pFrag;
         dPkt->pFrag = NULL;

         // Move the Diag pkt node from Rx done to free list
         MplListDel(pList, &dPkt->link);
         MplListAddTail(&adapter->diagFreeList, &dPkt->link);

         // Return count of completed pkts waiting for app
         pCmd->morePkts = MPL_LIST_GET_SIZE(pList);
         break;
      }
   }
   spin_unlock_irq(pLock);

   // If we managed to find the req node then free the frags
   //  since we are done with this packet
   if (pHead)
   {
      pTail = pFrag = pHead;
      dst = fragCnt = 0x0;

      // Do the copy of the data etc.. This is done outside of the locks
      while (pFrag)
      {
         if (pCmd->flags & NSM_APP_XFER_COPY)
         {
            // Check for overflow
            if (dst > pCmd->bufSize)
            {
               status = NS_STATUS_RESOURCES;
            }
            else
            {
               // Copy data back
               if (copy_to_user(&pData[dst], pFrag->pAddr, pFrag->fragSize))
               {
                  status = NS_STATUS_FAILURE;
               }
               dst += pFrag->fragSize;
            }
         }

         // Copy physical address used for this transfer
         if (fragCnt < NS_APP_MAX_FRAG_INFO) 
         {
            pCmd->descPhyAddr[fragCnt] = (NS_ADDR)pFrag->pMplPrivate;
            pCmd->bufPhyAddr[fragCnt++]  = pFrag->physAddr;
         }

         // Get next frag
         pTail = pFrag;
         pFrag = pFrag->pNextFrag;
      }

      // Add the frags back to the free list
      spin_lock_irq(pLock);
      (*ppTailFrag)->pNextFrag = pHead;
      *ppTailFrag = pTail;
      spin_unlock_irq(pLock);
   }

   NO(pktStatus);   
   return status;
}

//*****************************************************************************
//   pktValidate
//     Do some basic validation on the pkt, and update stats
//
//   Parameters
//      adapter
//         NSM Context
//      pHeadFrag
//         Pointer to the head fragment in the pkt
//   Return Value
//      None
//*****************************************************************************
static NS_VOID
pktValidate(
      NSM_CONTEXT *adapter,
      MPL_PKT_FRAG *pHeadFrag)
{
   NI(pktValidate);   
   NO(pktValidate);   
   return;
}

//*****************************************************************************
//   flushRx
//     Dump all pkts in done list and puts the frags and Diag Pkts back on
//     free lists
//
//   Parameters
//      adapter
//         NSM Context
//   Return Value
//      None
//*****************************************************************************
static NS_VOID
flushRx(
      NSM_CONTEXT *adapter)
{

   NI(flushRx);   

   spin_lock_irq(&adapter->rxLock);

   // Force all frags from the Done list
   NsmDiagProcessDoneList(adapter, 0x0, NS_FALSE,
                          &adapter->diagRxDoneList, &adapter->rxFragsTail);

   // Clear all stats
   adapter->diagStats.rxPackets = 0x0;
   adapter->diagStats.rxBytes = 0x0;
   adapter->diagStats.rxErrors = 0x0;
   adapter->diagStats.rxDropped = 0x0;
   adapter->diagStats.rxLengthErrors = 0x0;
   adapter->diagStats.rxOverErrors = 0x0;
   adapter->diagStats.rxCrcErrors = 0x0;
   adapter->diagStats.rxFrameErrors = 0x0;

   spin_unlock_irq(&adapter->rxLock);

   NO(flushRx);   
   return;
}

//*****************************************************************************
//   flushTx
//     Dump all pkts in done list and puts the frags and Diag Pkts back on
//     free lists
//
//   Parameters
//      adapter
//         NSM Context
//   Return Value
//      None
//*****************************************************************************
static NS_VOID
flushTx(
      NSM_CONTEXT *adapter)
{
   NI(flushTx);   

   spin_lock_irq(&adapter->txLock);

   // Force all frags from the Done list
   NsmDiagProcessDoneList(adapter, 0x0, NS_FALSE,
                          &adapter->diagTxDoneList, &adapter->txFragsTail);

   // Clear all stats
   adapter->diagStats.txPackets = 0x0;
   adapter->diagStats.txBytes = 0x0;
   adapter->diagStats.txErrors = 0x0;
   adapter->diagStats.txDropped = 0x0;
   adapter->diagStats.txCollErrors = 0x0;
   adapter->diagStats.txAbortedErrors = 0x0;
   adapter->diagStats.txCarrierErrors = 0x0;
   adapter->diagStats.txFifoErrors = 0x0;
   adapter->diagStats.txWindowErrors = 0x0;

   spin_unlock_irq(&adapter->txLock);

   NO(flushTx);   
   return;
}

//*****************************************************************************
//   getDiagStats
//     Diag module check status of previous Tx
//
//   Parameters
//     adapter
//         NSM Context
//     pCmd
//         Diag Stats command request
//
//   Return Value
//     None
//*****************************************************************************
static NS_VOID
   getDiagStats(
      NSM_CONTEXT       *adapter,
      NS_APP_STATS_CMD  *pCmd)
{
   NI(getDiagStats);   

   // Basic Tx, Rx
   pCmd->rxPackets = adapter->diagStats.rxPackets;
   pCmd->txPackets = adapter->diagStats.txPackets;
   pCmd->rxBytes = adapter->diagStats.rxBytes;
   pCmd->txBytes = adapter->diagStats.txBytes;
   pCmd->rxErrors = adapter->diagStats.rxErrors;
   pCmd->txErrors = adapter->diagStats.txErrors;
   pCmd->rxDropped = adapter->diagStats.rxDropped;
   pCmd->txDropped = adapter->diagStats.txDropped;

   // detailed rx_errors  - As seen in descriptor cmdsts
   pCmd->rxLengthErrors = adapter->diagStats.rxLengthErrors;
   pCmd->rxOverErrors = adapter->diagStats.rxOverErrors;
   pCmd->rxCrcErrors = adapter->diagStats.rxCrcErrors;
   pCmd->rxFrameErrors = adapter->diagStats.rxFrameErrors;

   // detailed tx_errors  - As seen in descriptor cmdsts
   pCmd->txCollErrors = adapter->diagStats.txCollErrors;
   pCmd->txAbortedErrors = adapter->diagStats.txAbortedErrors;
   pCmd->txCarrierErrors = adapter->diagStats.txCarrierErrors;
   pCmd->txFifoErrors = adapter->diagStats.txFifoErrors;
   pCmd->txWindowErrors = adapter->diagStats.txWindowErrors;

   NO(getDiagStats);   
   return;
}

//*****************************************************************************
//   xferCfgSet
//     Configure the Tx/Rx engine
//
//   Parameters
//     adapter
//         NSM Context
//     pCmd
//         Diag xfer cfg command request
//
//   Return Value
//      NS_STATUS_SUCCESS
//         The requested configurations were successfully applied
//      NS_STATUS_INVALID_PARM
//         The configuration values are not valid
//      NS_STATUS_FAILURE
//         The requested configuration could not be applied on the device
//      NS_STATUS_RESOURCES
//         Resources required for this configuration could not be allocated
//*****************************************************************************
static NS_UINT
   xferCfgSet(
      NSM_CONTEXT         *adapter,
      NS_APP_XFER_CFG_CMD *pCmd)
{
   MPL_TRANSMIT_CFG txCfg;
   MPL_RECEIVE_CFG rxCfg;
   NS_UINT i;
   NS_UINT status;

   NI(xferCfgSet);

   // Step0: Validate the parameters before doing any work
   if (pCmd->txpQueueCnt > adapter->mplCaps.txCaps.priorityQCnt)
   {
      return NS_STATUS_INVALID_PARM;
   }

   // Step1: Reset current configuration

   // Reset Tx and Rx engines - This gives all buffers frags back to NSM
   spin_lock_irq(&adapter->txLock);
   MplTransmitReset(adapter->mplContext);
   spin_unlock_irq(&adapter->txLock);

   spin_lock_irq(&adapter->rxLock);
   MplReceiveReset(adapter->mplContext);
   spin_unlock_irq(&adapter->rxLock);

   // Free the Diag pkts - This flushes the pkts in the done list too
   pktFree(adapter);

   // Free the fragments, tx and rx
   freeTxFrags(adapter);
   freeRxFrags(adapter);

   // Step2: Set the new values
   adapter->rxdCnt = pCmd->rxDescCnt;
   adapter->txdCnt = pCmd->txDescCnt;
   adapter->diagStsQueueSize = pCmd->stsQueueSize;
   adapter->rxBufferLen = pCmd->rxBufferLen; 
   adapter->txBufferLen = pCmd->txBufferLen; 
   adapter->txQCnt = pCmd->txpQueueCnt;
   adapter->rxQCnt = NSM_DEFAULT_RX_Q_CNT; //Force it to one

   // Step3: Apply the new values
   txCfg.cfgFlags = MPL_TRANSMIT_CFG_QUEUES;
   txCfg.maxIndications  = NSM_DEFAULT_TX_MAX_INDY;
   txCfg.priorityQueueCnt = adapter->txQCnt;
   for (i = 0x0; i < adapter->txQCnt; i++)
   {
      txCfg.descCnt[i] = adapter->txdCnt;
   }

   // Tell MPL about the new Tx configurations
   status = MplTransmitCfg(adapter->mplContext, &txCfg);
   if (status == NS_STATUS_SUCCESS)
   {
      rxCfg.cfgFlags = MPL_RECEIVE_CFG_QUEUES;
      rxCfg.maxIndications  = NSM_DEFAULT_RX_MAX_INDY;

      rxCfg.priorityQueueCnt = adapter->rxQCnt;
      for (i = 0x0; i < adapter->rxQCnt; i++)
      {
         rxCfg.descCnt[i] = adapter->rxdCnt;
      }

      // Tell MPL about the new Rx configurations
      status = MplReceiveCfg(adapter->mplContext, &rxCfg);
   }

   // Diag related setup
   if (status == NS_STATUS_SUCCESS)
   {
      // Setup new frags based on the new settings
      if ((setupTxFrags(adapter) == NS_TRUE) &&
            (setupRxFrags(adapter) == NS_TRUE))
      {
         // Set up status queue Diag packets based on new status Queue size
         if (pktSetup(adapter) == NS_TRUE)
         {
            // Replenish the device's receive engine with new buffers
            replenishTask((unsigned long)adapter);
         }
         else
         {
            freeRxFrags(adapter);
            freeTxFrags(adapter);
            status = NS_STATUS_RESOURCES;
         }
      }
      else
      {
         freeRxFrags(adapter);
         freeTxFrags(adapter);
         status = NS_STATUS_RESOURCES;
      }
   }

   NO(xferCfgSet);
   return status;
}

//*****************************************************************************
//   xferCfgGet
//     Get the Tx/Rx engine configurations
//
//   Parameters
//     adapter
//         NSM Context
//     pCmd
//         Diag xfer cfg command request
//
//   Return Value
//      NS_STATUS_SUCCESS
//         The requested configurations were successfully applied
//*****************************************************************************
static NS_UINT
   xferCfgGet(
      NSM_CONTEXT         *adapter,
      NS_APP_XFER_CFG_CMD *pCmd)
{
   NI(xferCfgGet);

   pCmd->rxDescCnt = adapter->rxdCnt;
   pCmd->txDescCnt = adapter->txdCnt;
   pCmd->stsQueueSize = adapter->diagStsQueueSize;
   pCmd->rxBufferLen = adapter->rxBufferLen; 
   pCmd->txBufferLen = adapter->txBufferLen; 
   pCmd->txpQueueCnt = adapter->txQCnt;

   NO(xferCfgGet);
   return NS_STATUS_SUCCESS;
}

#endif //NSM_DIAG_MODE

⌨️ 快捷键说明

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