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

📄 mplreceive.c

📁 NATIONAL公司DP83816芯片Linux下驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
      // FM: Assert Make sure that this Rxd is empty

      // Set up the Rxd
      currRxd->cmdSts = MPL_HTOL32(currFrag->fragSize);
      currRxd->bufptrPA = MPL_ADDR_HTOL(currFrag->physAddr);
      currRxd->mplPriv  = currFrag; // Note the Frag Ptr

      // Get the next fragment
      currFrag = currFrag->pNextFrag;
   }

   // If we managed to replenish some buffers then re-enable the Rx engine
   if ((pMplCtx->rxQueue.curr - pMplCtx->rxQueue.dirty) <
                       pMplCtx->rxQueue.descCnt)
   {
      MPL_WRITE32(pMplCtx, CR, RX_EN);
   }

   // If we have some fragments left over, then return it back to NSM
   if (bufFragCount)
   {
      *pFragList = currFrag;
   }

   EXIT(MplReceiveReplenish);
   return NS_STATUS_SUCCESS;
}


//*****************************************************************************
//   MplQueryPacketLength
//      Returns the size (in bytes) of the data frame within a MPL_PKT structure
//
//   Parameters
//      pPacket
//         Pointer to the MPL_PKT structure who data frame length is being 
//          queried.
//
//   Return Value
//      The total size of the data frame in bytes (could be 0x0 also).
//
//*****************************************************************************
NS_UINT
   MplQueryPacketLength (
      IN MPL_PKT   *pPacket
      )
{
   ENTER(MplQueryPacketLength);

   EXIT(MplQueryPacketLength);

   // Return the packet size
   return pPacket->packetSize;
}

//*****************************************************************************
//   MplReceiveReset
//      Resets the receive engine on the device and associated software 
//       resources. 
//
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize
//
//   Return Value
//      NS_STATUS_SUCCESS
//         The receive engine was successfully reset.
//      NS_STATUS_HARDWARE_FAILURE
//         Unexpected hardware error - No reset done notification from Hw
//
//*****************************************************************************
MPL_STATUS
   MplReceiveReset (
      IN NS_VOID       *pMplHandle
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
   NS_UINT entry, pendRxds;
   MPL_PKT_FRAG *currFrag;
   MPL_DESC *currRxd;
   
   ENTER(MplReceiveReset);

   // Make sure we were initialized to begin with
   if (pMplCtx->rxQueue.pRgnHndl == NULL)
   {
      EXIT(MplReceiveReset);
      return NS_STATUS_SUCCESS;
   }

   // Tell the hardware to reset its Rx engine 
   MPL_WRITE32(pMplCtx, CR, RXRESET);

   // Total 4msec - Not waiting for notification
   OaiSleep(4 * RESETINTERVAL_MAC);

   // Get the starting Rxd and number of Rxds to process
   entry = pMplCtx->rxQueue.curr % pMplCtx->rxQueue.descCnt;
   currRxd = &pMplCtx->rxQueue.pRing[entry];
   pendRxds = pMplCtx->rxQueue.dirty + pMplCtx->rxQueue.descCnt 
                       - pMplCtx->rxQueue.curr;

   // Process the Rxd ring - Collect all data buffers in all pending
   //  Rxds and report them in one big blob
   while (pendRxds)
   {
      // Software OWNs them all
      currRxd->cmdSts = CS_OWN_ES;

      // Get the frag ptr
      currFrag = (MPL_PKT_FRAG *)currRxd->mplPriv;
      currRxd->mplPriv = NULL;

      // We link all the buffers together
      if (pMplCtx->rxQueue.pFragHead == NULL)
         pMplCtx->rxQueue.pFragHead = currFrag; // Head frag 
      else
         pMplCtx->rxQueue.pFragTail->pNextFrag = currFrag; // Tail Frag

      pMplCtx->rxQueue.fragCnt++;

      // Accumulate the frag sizes
      pMplCtx->rxQueue.packetSize += 
                    (MPL_LTOH32(currRxd->cmdSts) & CS_LEN_MASK);

      // Add to the tail of pending list
      pMplCtx->rxQueue.pFragTail = currFrag;

      // Get the next Rxd and Read its cmdSts
      entry = (++pMplCtx->rxQueue.curr) % pMplCtx->rxQueue.descCnt;
      currRxd = &pMplCtx->rxQueue.pRing[entry];
      pendRxds--;
   }

   // If we managed to salvage any buffer fragments, report it in one blob
   if (pMplCtx->rxQueue.fragCnt)
   {
      // We have all Rxd frags for this abort pkt - Prepare a indication
      pMplCtx->rxDone[0x0].fragCount = pMplCtx->rxQueue.fragCnt;
      pMplCtx->rxDone[0x0].pFragHead = pMplCtx->rxQueue.pFragHead;
      pMplCtx->rxDone[0x0].rxOOB.cmdSts = 0x0;
      pMplCtx->rxDone[0x0].packetSize = pMplCtx->rxQueue.packetSize;
      pMplCtx->rxDone[0x0].packetStatus = NS_STATUS_ABORTED;
     
      NsmReceive(pMplCtx->pClientHandle, 0x1, pMplCtx->rxDone);
   }

   // Clean up partial tracker
   pMplCtx->rxQueue.pFragHead = pMplCtx->rxQueue.pFragTail = NULL;
   pMplCtx->rxQueue.fragCnt = pMplCtx->rxQueue.packetSize = 0x0 ;

   // Reset pointers
   pMplCtx->rxQueue.dirty = 0x0;
   pMplCtx->rxQueue.curr = pMplCtx->rxQueue.descCnt;
   pMplCtx->rxQueue.ringPA = pMplCtx->rxQueue.pRgnHndl->phyAddr;
   pMplCtx->rxQueue.pRing  = (MPL_DESC *)pMplCtx->rxQueue.pRgnHndl->pAddr;

   // Notify the device about the head node on the ring
   MPL_WRITE32(pMplCtx, RXDP,  pMplCtx->rxQueue.ringPA);

   EXIT(MplReceiveReset);
   return NS_STATUS_SUCCESS;
}

//*****************************************************************************
//   MplReceiveGetEmptyDesc
//      Returns the count of the Rxds that are empty i.e. no attached buffers
//
//   Parameters
//      pMplHandle
//         MPL device handle returned following a call to MplInitialize
//      pQueue
//         Queue (1,2...max tx queues) from which the empty count is desired
//      pRxdCnt
//         Pointer to a caller allocated fields in which the count of empty
//          receive descriptors is returned
//
//   Return Value
//      NS_STATUS_SUCCESS
//         The count was successfully returned.
//      NS_STATUS_INVALID_PARM
//         The priority queue count is invalid
//
//*****************************************************************************
MPL_STATUS
   MplReceiveGetEmptyDesc (
      IN NS_VOID    *pMplHandle,
      IN NS_UINT8    pQueue,
      OUT NS_UINT   *pRxdCnt
      )
{
   MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;

   ENTER(MplReceiveGetEmptyDesc);

   // Get the empty Rxd count
   *pRxdCnt = pMplCtx->rxQueue.curr - pMplCtx->rxQueue.dirty;

   EXIT(MplReceiveGetEmptyDesc);
   return NS_STATUS_SUCCESS;
}

//+++++ Local Functions
//#####################

//*****************************************************************************
//   setRxCfg
//      Set the FIFO and DMA burst related configurations on the device
//
//   Parameters
//      pMplCtx
//         Pointer to MPL Context
//      pCfgReceive
//         Pointer to a caller allocated MPL_RECEIVE_CFG structure with 
//          configuration values for the receive engine
//
//   Return Value
//      None
//
//*****************************************************************************
static
NS_VOID
   setRxCfg(
      IN MPL_CONTEXT       *pMplCtx,
      IN MPL_RECEIVE_CFG   *pCfgReceive
      )
{
   NS_UINT32 rxDma, rxCfg, drain;

   ENTER(setRxCfg);

   // Get the Rx DMA size
   rxDma = 0x0;
   if (pCfgReceive->maxDmaBurst < 8) 
      rxDma = MXDMA4; //Min
   else if (pCfgReceive->maxDmaBurst < 16) 
           rxDma = MXDMA8;
        else
           if (pCfgReceive->maxDmaBurst < 32) 
                rxDma = MXDMA16;
           else if (pCfgReceive->maxDmaBurst < 64) 
                     rxDma = MXDMA32;
                else if (pCfgReceive->maxDmaBurst < 128) 
                          rxDma = MXDMA64;
                     else if (pCfgReceive->maxDmaBurst < 256) 
                               rxDma = MXDMA128;
                          else if (pCfgReceive->maxDmaBurst < 512) 
                                    rxDma = MXDMA256;
                               else if (pCfgReceive->maxDmaBurst < 1024) 
                                       rxDma = MXDMA512;
                                     else if (pCfgReceive->maxDmaBurst < 2048) 
                                             rxDma = (MXDMA256 | RXDMA4);
                                          else
                                             rxDma = (MXDMA512 | RXDMA4); //Max


   // Read the Rxcfg contents
   rxCfg = MPL_READ32(pMplCtx, RXCFG);
    
   // Mask the rx settable values
   rxCfg &= ~RXSET_MASK;

   // Generate the RXCFG contents - The drain threshold is specified in
   //  8 byte units
   drain = ((pCfgReceive->drainThreshold / 8) & 0x1F) << RXDRAIN_SHIFT;
   rxCfg |= rxDma | drain;

   // Write RXCFG
   MPL_WRITE32(pMplCtx, RXCFG, rxCfg);

   EXIT(setRxCfg);
   return;
}

//*****************************************************************************
//   allocRxdRing
//      Alloc all the Rxd rings
//
//   Parameters
//      pMplCtx
//         Pointer to MPL Context
//
//   Return Value
//      NS_STATUS_SUCCESS
//         The rings were correctly setup
//      NS_STATUS_RESOURCES
//         Failed to allocate the resources (receive control blocks)
//
//*****************************************************************************
static
MPL_STATUS
   allocRxdRing(
      IN MPL_CONTEXT       *pMplCtx
      )
{
   MPL_STATUS status = NS_STATUS_SUCCESS;

   ENTER(allocRxdRing);

   // Allocate resources for the Rx done indication packets
   pMplCtx->rxDone = (MPL_PKT *)
                          OaiMalloc(sizeof(MPL_PKT) * pMplCtx->maxRxDones);
   if (pMplCtx->rxDone == NULL)
   {
      return NS_STATUS_RESOURCES;
   }
   OaiZeroMem(pMplCtx->rxDone, sizeof(MPL_PKT) * pMplCtx->maxRxDones);

   // Allocate memory for the descriptors
   if (OaiAllocDmaRegion(pMplCtx->pClientHandle, 
                         sizeof(MPL_DESC) * pMplCtx->rxQueue.descCnt,
                         4, // Aligned on 32-bits
                         &pMplCtx->rxQueue.pRgnHndl) == NS_FALSE)
   {
      // Allocation failed - Free all prev allocations
      OaiFree(sizeof(MPL_PKT) * pMplCtx->maxRxDones, pMplCtx->rxDone);
      status = NS_STATUS_RESOURCES;
   }
   else
   {
      // Reset mem block
      OaiZeroMem(pMplCtx->rxQueue.pRgnHndl->pAddr, 
                 sizeof(MPL_DESC) * pMplCtx->rxQueue.descCnt);
   }

   EXIT(allocRxdRing);
   return status;
}

//*****************************************************************************
//   freeRxdRing
//      Free the Rxd rings
//
//   Parameters
//      pMplCtx
//         Pointer to MPL Context
//
//   Return Value
//      None
//
//*****************************************************************************
NS_VOID
   freeRxdRing(
      IN MPL_CONTEXT       *pMplCtx
      )
{
   ENTER(freeRxdRing);

   // Free resources for the Rx done indications 
   if (pMplCtx->rxDone != NULL)
   {
      OaiFree(sizeof(MPL_PKT) * pMplCtx->maxRxDones, pMplCtx->rxDone);
      pMplCtx->rxDone = NULL;
   }

   // Free memory for the descriptors
   if (pMplCtx->rxQueue.pRgnHndl != NULL)
   {
      OaiFreeDmaRegion(pMplCtx->pClientHandle, pMplCtx->rxQueue.pRgnHndl);
      pMplCtx->rxQueue.pRgnHndl = NULL;
   }

   EXIT(freeRxdRing);
   return;
}

//*****************************************************************************
//   setupRxdRing     
//      Setup the Rxd Ring
//
//   Parameters
//      pMplCtx
//         Pointer to MPL Context
//
//   Return Value
//      None
//
//*****************************************************************************
static
NS_VOID   
   setupRxdRing(
      IN MPL_CONTEXT       *pMplCtx
      )
{
   NS_UINT j;

   // Dirty % Ring_Size = First empty Rxd (i.e. no buf attached)
   // Curr % Ring_Size  = First full Rxd (i.e. buf attached)
   // If (Curr == Dirty) => All Rxds have data bufs attached
   // If ((Curr - Dirty) == Ring_Size) => None of the Rxds have data bufs 
   //                                      attached
   
   ENTER(setupRxdRing);

   pMplCtx->rxQueue.dirty = 0x0;
   pMplCtx->rxQueue.curr = pMplCtx->rxQueue.descCnt;
   pMplCtx->rxQueue.ringPA = pMplCtx->rxQueue.pRgnHndl->phyAddr;
   pMplCtx->rxQueue.pRing  = (MPL_DESC *)pMplCtx->rxQueue.pRgnHndl->pAddr;

   for (j = 0x0; j < pMplCtx->rxQueue.descCnt; j++)
   {
      // Link up and form a ring
      pMplCtx->rxQueue.pRing[j].linkPA  = 
              MPL_ADDR_HTOL(pMplCtx->rxQueue.ringPA +
                              (sizeof(MPL_DESC) * 
                                ((j+1) % (pMplCtx->rxQueue.descCnt))));

      // We OWN the Rxd (Till it is attached with a buffer)
      pMplCtx->rxQueue.pRing[j].cmdSts = CS_OWN_ES;
      pMplCtx->rxQueue.pRing[j].bufptrPA = 0x0;
   }

   // Link up the Rx Indication packets also
   for (j = 0x0; j < (pMplCtx->maxRxDones - 1); j++)
   {
      pMplCtx->rxDone[j].pNextPacket = &pMplCtx->rxDone[j+1];
   }
   
   EXIT(setupRxdRing);
   return;
}

⌨️ 快捷键说明

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