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

📄 nsmdiag.c

📁 NATIONAL公司DP83816芯片Linux下驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
         case NSM_STATS:
                         if (copy_from_user(&statCmd, useraddr, 
                                                        sizeof(statCmd)))
                         {
                            ret = NS_STATUS_FAILURE;
                         }
                         else
                         {
                            getDiagStats(adapter, &statCmd);
                            if (copy_to_user(useraddr, &statCmd, 
                                                      sizeof(statCmd)))
                            {
                               ret = NS_STATUS_FAILURE;
                            }
                         }
                         break;

         default :         
                          ret = NS_STATUS_NOT_SUPPORTED;
      }
   }

   NO(NsmDiagIoctl);
   return ret;
}


//*****************************************************************************
//   NsmDiagTransmitDone
//     Transmit Done Notification  (Diag Mode)
//
//   Parameters
//      pClientDevHndl
//         NSM device handle registered with MPL (during MplInitialize)
//      packetCnt
//         Count of packets whose completion is being reported.
//      pTxDone
//         MPL allocated MPL_TRANSMIT_DONE structure array in which the 
//          NSM packet handles and statuses are returned.
//
//   Return Value
//      None
//*****************************************************************************
NS_VOID
NsmDiagTransmitDone(
    NS_VOID *pClientDevHndl,
    NS_UINT  packetCnt,
    MPL_TRANSMIT_DONE *pTxDone
    )
{
   NSM_CONTEXT *adapter = pClientDevHndl;
   NS_UINT i, pktSize, fragCnt;
   DIAG_PKT *dPkt;
   MPL_LIST_NODE *node;
   MPL_PKT_FRAG *pFrag, *pHeadFrag, *pTailFrag;

   NI(NsmDiagTransmitDone);   

   // Unmap and Free done skbs
   for(i = 0x0; i < packetCnt; i++)
   {
      // Get the head frag which was noted as NSM private
      pHeadFrag = pTxDone[i].pNsmPrivate;

      // Unmap Buffers
      pFrag = pHeadFrag; pTailFrag = NULL;
      pktSize = 0x0; fragCnt = 0x0;
      while (pFrag)
      {
         pci_unmap_single(adapter->pdev, pFrag->physAddr, pFrag->fragSize,
                            PCI_DMA_TODEVICE);
    
         pktSize += pFrag->fragSize;
         fragCnt++;

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

      // Update stats
      if (pTxDone[i].packetStatus == NS_STATUS_SUCCESS)
      {
         // Update counters
         adapter->diagStats.txPackets++;
         adapter->diagStats.txBytes += pktSize;
      }
      else
      {

         // Update counters
         adapter->diagStats.txErrors++;

         // Detailed Error analysis 
         if (pTxDone[i].cmdSts & CS_ERR_TXA)
         {
            adapter->diagStats.txAbortedErrors++;
         }

         if (pTxDone[i].cmdSts & CS_ERR_TX_EC)
         {
            adapter->diagStats.txCollErrors++;
         }

         if (pTxDone[i].cmdSts & CS_ERR_TFU)
         {
            adapter->diagStats.txFifoErrors++;
         }
         
         if (pTxDone[i].cmdSts & CS_ERR_TX_CRS)
         {
            adapter->diagStats.txCarrierErrors++;
         }

         if (pTxDone[i].cmdSts & CS_ERR_TX_OWC)
         {
            adapter->diagStats.txWindowErrors++;
         }
      }

      if (pTxDone[i].packetStatus != NS_STATUS_ABORTED)
      {
         // If we are are out of free pkt nodes to note this completion
         //  then force a stale one out of the completed list
         if (MPL_LIST_GET_SIZE(&adapter->diagFreeList) == 0x0)
         {
            // Ask ProcessDone function to do a basic validation before freeing
            NsmDiagProcessDoneList(adapter, 0x1, NS_TRUE,
                          &adapter->diagTxDoneList, &adapter->txFragsTail);
            adapter->diagStats.txDropped++;
         }

         // Get a free diag pkt node from the head of the free list
         node = MPL_LIST_GET_HEAD(&adapter->diagFreeList); 

         // Get the Diag Pkt linked to the curr node
         dPkt = MPL_LIST_GET_ENTRY(node, DIAG_PKT, link);

         // Note pkt details
         dPkt->pktStatus = pTxDone[i].packetStatus;
         dPkt->cmdSts = pTxDone[i].cmdSts;
         dPkt->pktSize = pktSize;
         dPkt->appPktHandle = (NS_UINT)pHeadFrag->pPacketHndl;
         dPkt->numDesc = fragCnt;

         // NSM Diag related
         dPkt->pFrag = pHeadFrag;

         // Move this packet from the free list to the done list
         MplListDel(&adapter->diagFreeList, &dPkt->link);
         MplListAddTail(&adapter->diagTxDoneList, &dPkt->link);
      }
      else
      {
         // Add the frags back to the free list
         adapter->txFragsTail->pNextFrag = pHeadFrag;
         adapter->txFragsTail = pTailFrag;
      }
   }

   NO(NsmDiagTransmitDone);
   return;
}


//*****************************************************************************
//   NsmDiagReceive
//     Diag mode Receive Done Notification
//
//   Parameters
//      pClientDevHndl
//         NSM device handle registered with MPL (during MplInitialize)
//      packetCnt
//         Count of packets whose reception is being reported.
//      pPkt
//         MPL allocated MPL_PKT structure array in which 
//         a list of the newly received packets are reported
//
//   Return Value
//      None
//*****************************************************************************
NS_VOID
NsmDiagReceive(
    NS_VOID *pClientDevHndl,
    NS_UINT  packetCnt,
    MPL_PKT *pPkt
    )
{
   NSM_CONTEXT *adapter = pClientDevHndl;
   MPL_PKT_FRAG *pTailFrag, *pHeadFrag;
   DIAG_PKT *dPkt;
   MPL_LIST_NODE *node;
   NS_UINT i, j;

   NI(NsmDiagReceive);

   // Process the receive list
   for(i = 0x0; i < packetCnt; i++)
   {
      // Get the head frag ptr
      pHeadFrag = pPkt[i].pFragHead;

      if (pPkt[i].packetStatus == NS_STATUS_SUCCESS)
      {
         // Update counters
         adapter->diagStats.rxPackets++;
         adapter->diagStats.rxBytes += pPkt[i].packetSize;
      }
      else
      {
         // Update counters
         adapter->diagStats.rxErrors++;

         // Detailed Error analysis
         if (pPkt[i].rxOOB.cmdSts & (CS_RXA | CS_ERR_RXO))
         {
            adapter->diagStats.rxOverErrors++;
         }

         if (pPkt[i].rxOOB.cmdSts & CS_ERR_RX_CRCE)
         {
            adapter->diagStats.rxCrcErrors++;
         }

         if (pPkt[i].rxOOB.cmdSts & (CS_ERR_RX_LONG | CS_ERR_RX_RUNT))
         {
            adapter->diagStats.rxLengthErrors++;
         }

         if (pPkt[i].rxOOB.cmdSts & (CS_ERR_RX_ISE | CS_ERR_RX_FAE))
         {
            adapter->diagStats.rxFrameErrors++;
         }
      }

      if (pPkt[i].packetStatus != NS_STATUS_ABORTED)
      {
         // If we are are out of free pkt nodes to note this completion
         //  then force a stale one out of the completed list
         if (MPL_LIST_GET_SIZE(&adapter->diagFreeList) == 0x0)
         {
            // Ask ProcessDone function to do a basic validation before freeing
            NsmDiagProcessDoneList(adapter, 0x1, NS_TRUE, 
                              &adapter->diagRxDoneList, &adapter->rxFragsTail);
            adapter->diagStats.rxDropped++;
         }

         // Get a free diag pkt node from the head of the free list
         node = MPL_LIST_GET_HEAD(&adapter->diagFreeList); 

         // Get the Diag Pkt linked to the curr node
         dPkt = MPL_LIST_GET_ENTRY(node, DIAG_PKT, link);

         // Note pkt details
         dPkt->pktStatus = pPkt[i].packetStatus;
         dPkt->cmdSts = pPkt[i].rxOOB.cmdSts;
         dPkt->pktSize = pPkt[i].packetSize;
         dPkt->appPktHandle = 0x0; // Reference handle for Rx pkts
         dPkt->numDesc = pPkt[i].fragCount;

         // NSM Diag related
         dPkt->pFrag = pHeadFrag;

         // Move this packet from the free list to the done list
         MplListDel(&adapter->diagFreeList, &dPkt->link);
         MplListAddTail(&adapter->diagRxDoneList, &dPkt->link);
      }
      else
      {
         pTailFrag = pHeadFrag;
         for (j = 0x0; j < (pPkt[i].fragCount - 1); j++)
         {
            pTailFrag = pTailFrag->pNextFrag;
         }

         // Add the frags back to the free list
         adapter->rxFragsTail->pNextFrag = pHeadFrag;
         pTailFrag->pNextFrag = NULL;
         adapter->rxFragsTail = pTailFrag;
      }
   }

   NO(NsmDiagReceive);
   return;
}

//*****************************************************************************
//   NsmDiagProcessDoneList
//     Process one or more packets in the Tx/Rx Done queue
//
//   Parameters
//      adapter
//         NSM Context
//      pktCnt
//         Number of packets to process.
//         Set this to 0x0 to process all packets in the completion queue
//      validate
//         NS_TRUE : Do a basic validation on the packet before releasing it
//         NS_FALSE : Just release it
//       pList
//         Done List (Tx/Rx) to process
//       ppTailFrag
//         Pointer to a frag pointer at which to append the freed frags
//   Return Value
//      None
//*****************************************************************************
NS_VOID
NsmDiagProcessDoneList(
      NSM_CONTEXT   *adapter, 
      NS_UINT        pktCnt, 
      NS_BOOLEAN     validate,
      MPL_LIST      *pList,
      MPL_PKT_FRAG **ppTailFrag)
{
   DIAG_PKT *dPkt;
   MPL_LIST_NODE *node;
   NS_UINT i;
   MPL_PKT_FRAG *pTail;

   NI(NsmDiagProcessDoneList);   

   // Check if we need to process all pkts
   if (pktCnt == 0x0)
   {
      pktCnt = MPL_LIST_GET_SIZE(pList);
   }

   // Process done list
   node = MPL_LIST_GET_HEAD(pList); 
   for (i = 0x0; i < pktCnt; i++)
   {
      if (MPL_LIST_GET_SIZE(pList) == 0x0)
      {
         break; //premature?
      }

      // Get the Diag Pkt linked to the curr node
      dPkt = MPL_LIST_GET_ENTRY(node, DIAG_PKT, link);

      // Get the next node
      node  = MPL_LIST_GET_NEXT(node);

      if (dPkt->pFrag)
      {
         // Check if we need to validate this packet before removing
         if (validate == NS_TRUE)
         {
            pktValidate(adapter, dPkt->pFrag);
         }

         // Put the frags back on the free frag list
         pTail = dPkt->pFrag;
         while (pTail->pNextFrag)
         {
            pTail = pTail->pNextFrag;
         }

         // Add the frags back to the free list
         (*ppTailFrag)->pNextFrag = dPkt->pFrag;
         *ppTailFrag = pTail;
      }

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

   NO(NsmDiagProcessDoneList);   
   return;
}
// Local functions

//*****************************************************************************
//   setupTxFrags
//     Setup the MPL frags for Tx
//
//   Parameters
//      adapter
//         NSM Context
//   Return Value
//      NS_TRUE : Setup was successful
//      NS_FALSE : Setup failed
//*****************************************************************************
static NS_BOOLEAN
setupTxFrags(
      NSM_CONTEXT *adapter)
{
   NS_UINT allocSize, i, nodes;
   MPL_PKT_FRAG *pFrag = NULL, *prevFrag;
   NS_VOID *allocMem;
   NS_BOOLEAN ret = NS_FALSE;
   struct sk_buff *skb;

   NI(setupTxFrags);

   // Allocate memory for the frags = total ring size + sts queue size
   nodes = adapter->txdCnt + adapter->diagStsQueueSize;
            
   allocSize = sizeof(MPL_PKT_FRAG) * nodes;
   allocMem  = kmalloc(allocSize, GFP_KERNEL);

   if (allocMem == NULL)
   {
      NSM_DBG(DBG_ERR,("Failed to Alloc mem to tx frags \n"));
      NO(setupTxFrags);
      return ret;
   }
   else
   {
      // Zero up the memory
      memset((void *)(allocMem), 0x0, allocSize);

      pFrag = (MPL_PKT_FRAG *) allocMem;
      prevFrag = NULL;

      // Create linked list and attach a buffer
      for (i = 0x0; i < nodes; i++)
      {
         // Allocate buffer
         skb = dev_alloc_skb(adapter->txBufferLen);
         if (skb == NULL)

⌨️ 快捷键说明

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