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

📄 support.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
               }

               //
               //  If this buffer is not the last one in the queue,
               //  set pBufferQ->BufListTail->Next to NULL.
               //
               if (NULL != pBufferQ->BufListTail)
               {
                   // 
                   // This buffer is at the end of queue.
                   // 
                   pBufferQ->BufListTail->Next = NULL;
               }
		    }
           else
           {
               //
               //  The receive is at the Beginning of the list. 
               //  Update the BufListHead
               //
			    pBufferQ->BufListHead = ptmpRecvHeader->Next;
			    pBufferQ->BufListHead->Prev = NULL;
           }
           ptmpRecvHeader->Next = NULL;
           ptmpRecvHeader->Prev = NULL;
           pBufferQ->BufferCount--;
           BufferIsFound = TRUE;

           break;  
   	}
   }

   if (BufferIsFound == TRUE)
   {
       *pRecvHeader = ptmpRecvHeader;
   }
   else
   {
       *pRecvHeader = NULL;
   }

   NdisDprReleaseSpinLock(&pBufferQ->lock);

}



VOID
tbAtm155MergeRecvBuffers2FreeBufferQueue(
   IN PADAPTER_BLOCK      pAdapter,
   IN PRECV_BUFFER_QUEUE  pFreeBufferQ,
   IN PRECV_BUFFER_QUEUE  pReturnBufferQ
   )
/*++

Routine Description:

   This routine will merge pRetrunBufferQ into pFreeBufferQ and
   put the buffers back to their pools if the pools are being
   freed.

Arguments:

Return Value:

--*/
{

   NdisAcquireSpinLock(&pFreeBufferQ->lock);

   if (NULL != pReturnBufferQ->BufListHead)
   {
       if (NULL == pFreeBufferQ->BufListHead)
       {
           pFreeBufferQ->BufListHead = pReturnBufferQ->BufListHead;
           pFreeBufferQ->BufListTail = pReturnBufferQ->BufListTail;
       }
       else
       {
           //
           //	Chain the first buffer in the returned queue with the
           //	current tail of the free buffer list.
           //
           pReturnBufferQ->BufListTail->Prev = pFreeBufferQ->BufListTail;
           pFreeBufferQ->BufListTail->Next = pReturnBufferQ->BufListHead;
	
           //
           //	Setup the new tail of the free buffer list.
           //
           pFreeBufferQ->BufListTail = pReturnBufferQ->BufListTail;
           pFreeBufferQ->BufListTail->Next = NULL;
       }

       //
       //	Increment the receive information's free buffer count.
       //	This is the total number of returned headers minus the
       //	ones that were freed back to their pools.
       //
       pFreeBufferQ->BufferCount += pReturnBufferQ->BufferCount;

	    DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_INFO,
		    ("tbAtm155MergeRecvBuffers2FreeBufferQueue: %lu\n", pFreeBufferQ->BufferCount));
       
	    DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_INFO,
		    ("AllocatedBigRecvBuffers: %lu\n", pAdapter->HardwareInfo->SarInfo->AllocatedBigRecvBuffers));
       
	    DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_INFO,
		    ("AllocatedSmallRecvBuffers: %lu\n", pAdapter->HardwareInfo->SarInfo->AllocatedSmallRecvBuffers));
       

       // initialize the pReturnBufferQ for re-use.
       pReturnBufferQ->BufListHead = NULL;
       pReturnBufferQ->BufListTail = NULL;
       pReturnBufferQ->BufferCount = 0;
   }

   NdisReleaseSpinLock(&pFreeBufferQ->lock);

}


VOID
tbAtm155HashVc(
   IN  PADAPTER_BLOCK  pAdapter,
   IN  PVC_BLOCK       pVc
   )
/*++

Routine Description:

   This routine will save the VC pointer in a hash table.
   This table is used to find the VC in a quick manner given only
   it's VC number.

Arguments:

   pAdapter    -   Adapter block to hash the VC to.
   pVc         -   Pointer to the VC to hash.

Return Value:

   None.

--*/
{
   ULONG	HashIndex;

   //
   //	Get the bucket in the hash table where this VC will be placed.
   //
   HashIndex = pVc->VpiVci.Vci % pAdapter->RegistryParameters[TbAtm155VcHashTableSize].Value;

   //
   //	Just store this vc at the head.
   //
   NdisAcquireSpinLock(&pAdapter->VcHashLock);
   pVc->NextVcHash = pAdapter->VcHashList[HashIndex];
   pAdapter->VcHashList[HashIndex] = pVc;
   NdisReleaseSpinLock(&pAdapter->VcHashLock);
}

PVC_BLOCK
tbAtm155UnHashVc(
   IN  PADAPTER_BLOCK  pAdapter,
   IN  ULONG           Vc
   )
/*++

Routine Description:

   This routine will return the pointer to the VC_BLOCK that is
   represented by the VC number.

Arguments:

   pAdapter    -   Pointer to the adapter block that the VC belongs to.
   Vc          -   The number of the VC that we want to retreive.

Return Value:

   PVC_BLOCK if successful.  NULL if the VC has not been created or
   activated on this adapter.

--*/
{
   ULONG		HashIndex;
   PVC_BLOCK	pVc;

   //
   //	Get the hash bucket that the VC is in.	
   //
   HashIndex = Vc % pAdapter->RegistryParameters[TbAtm155VcHashTableSize].Value;

   NdisAcquireSpinLock(&pAdapter->VcHashLock);

   pVc = pAdapter->VcHashList[HashIndex];
   while ((pVc != NULL) && (pVc->VpiVci.Vci != Vc))
   {
       pVc = pVc->NextVcHash;
   }

   NdisReleaseSpinLock(&pAdapter->VcHashLock);

   return(pVc);
}

VOID
tbAtm155RemoveHash(
   IN  PADAPTER_BLOCK      pAdapter,
   IN  PVC_BLOCK           pVc
   )
/*++

Routine Description:

   This routine will remove VC from the hash table.

Arguments:

   pAdapter    -   Pointer to the ADAPTER_BLOCK.
   pVc         -   Pointer to the VC_BLOCK

Return Value:

   None.

--*/
{
   ULONG       HashIndex;
   PVC_BLOCK   ptmpVc;
   PVC_BLOCK   pPrevVc = NULL;

   //
   //	Get the hash table index.
   //
   HashIndex = pVc->VpiVci.Vci % pAdapter->RegistryParameters[TbAtm155VcHashTableSize].Value;

   NdisAcquireSpinLock(&pAdapter->VcHashLock);

   //
   //	Get a temp list pointer to manipulate.
   //
   ptmpVc = pAdapter->VcHashList[HashIndex];

   //
   //	Walk the list looking for the VC that we need to remove.
   //
   while ((NULL != ptmpVc) && (pVc != ptmpVc))
   {
       //
       //	Save the previous hashed VC_BLOCK.
       //
       pPrevVc = ptmpVc;

       //
       //	Get a pointer to the next hashed VC_BLOCK.
       //
       ptmpVc = ptmpVc->NextVcHash;
   }

   //
   //	Make sure that the VC was hashed.
   //	If it wasn't then ignore the call.
   //
   if (NULL != ptmpVc)
   {
       //
       //	Was the VC_BLOCK the head of the hash list?
       //
       if (NULL == pPrevVc)
       {
           pAdapter->VcHashList[HashIndex] = ptmpVc->NextVcHash;
       }
       else
       {
           pPrevVc->NextVcHash = ptmpVc->NextVcHash;
       }
   }
   NdisReleaseSpinLock(&pAdapter->VcHashLock);
}


VOID
tbAtm155InitializePacketQueue(
   IN  OUT PPACKET_QUEUE   PacketQ
   )
/*++

Routine Description:

   This routine will initialize a PACKET_QUEUE structure for use.

Arguments:

   PacketQ -   Pointer to the PACKET_QUEUE to initialize.

Return Value:

   None.

--*/
{
   PacketQ->Head = NULL;
   PacketQ->Tail = NULL;

   NdisAllocateSpinLock(&PacketQ->lock);
}


VOID
tbAtm155FreePacketQueue(
   IN  OUT PPACKET_QUEUE   PacketQ
   )
/*++

Routine Description:

   This routine will free a PACKET_QUEUE structure from use.

Arguments:

   PacketQ -   Pointer to the PACKET_QUEUE to free.

Return Value:

   None.

--*/
{
   ASSERT(NULL == PacketQ->Head);

   NdisFreeSpinLock(&PacketQ->lock);
}


VOID
tbAtm155InitializeReceiveBufferQueue(
   IN  OUT PRECV_BUFFER_QUEUE  RecvBufferQ
   )
/*++

Routine Description:

   This routine will initialize a RECV_BUFFER_QUEUE structure for use.

Arguments:

   RecvBufferQ -   Pointer to the RECV_BUFFER_QUEUE to initialize.

Return Value:

   None.

--*/
{
   RecvBufferQ->BufListHead = NULL;
   RecvBufferQ->BufListTail = NULL;
   RecvBufferQ->BufferCount = 0;

   NdisAllocateSpinLock(&RecvBufferQ->lock);
}



VOID
tbAtm155FreeReceiveBufferQueue(
   IN  PADAPTER_BLOCK          pAdapter,
   IN  OUT PRECV_BUFFER_QUEUE  RecvBufferQ
   )
/*++

Routine Description:

   This routine will free a RECV_BUFFER_QUEUE structure for use.

Arguments:

   RecvBufferQ	-	Pointer to the RECV_BUFFER_QUEUE to free.

Return Value:

   None.

--*/
{
   PRECV_BUFFER_HEADER	    *ppRecvHeaderHead;
   
   for (ppRecvHeaderHead = &RecvBufferQ->BufListHead; 
        NULL != *ppRecvHeaderHead; )
   {
       // 
       //  Free the buffer pool when all of the buffers has been freed
       //  into the pool.
       //
       tbAtm155FreeReceiveBuffer(ppRecvHeaderHead, pAdapter, *ppRecvHeaderHead);
       RecvBufferQ->BufferCount--;
   }

   ASSERT(0 == RecvBufferQ->BufferCount);

   if (NULL == RecvBufferQ->BufListHead)
   {
       //  Reset the Pointer
       RecvBufferQ->BufListTail = NULL;
   }

   ASSERT(NULL == RecvBufferQ->BufListHead);
   ASSERT(NULL == RecvBufferQ->BufListTail);
   ASSERT(0 == RecvBufferQ->BufferCount);

   NdisFreeSpinLock(&RecvBufferQ->lock);
}



ULONG Exp_Tbl[24] = {
         1L,       2L,       4L,       8L,     // exp 0
        16L,      32L,      64L,     128L,     // exp 4
       256L,     512L,    1024L,    2048L,     // exp 8
      4096L,    8192L,   16386L,   32678L,     // exp 12
     65536L,  131072L,  262144L,  524288L,     // exp 16
   1048576L, 2097152L, 4194394L, 8288608L      // exp 20
};

void
tbAtm155ConvertToFP(
   IN OUT  PULONG  pRate,
   OUT     PUSHORT pRateInFP
   )
/*++

Routine Description:

   This routine will convert from rate, PCR, into a binary floating
   point representation. The Equate is

       Rate = [2^e (1 + m/512)] * nz

           reserved bit -> Bit 15

           nz -> Bit 14
                 0 the rate is zero
                 1 the rate is as given by the fields e and m.

           e  -> Bit 13 through 9
                 range from 0 to 31. The exponent is a 5 bit unsigned

           m  -> Bit 9 through 0
                 The mantissa is a 5 bit unsigned


Arguments:

   Rate        -   The rate needs to be converted.
   pRateInFP   -   point to the variable to write 

Return Value:

   None.

--*/
{
   ULONG               i_rate = *pRate;
   ULONG               temp;
   TBATM155_RATE_IN_FP rate_FP;
   
   NDIS_STATUS Status = NDIS_STATUS_FAILURE;

   do {

       //
       // Just initialize
       //
       rate_FP.reg = 0;      // default nz to be 0.
       rate_FP.nz = 1;      // default nz to be 1.

       if (i_rate == 0)
       {
           //
           // Detected input rate is 0, set nz and return ot caller.
           //
           rate_FP.nz = 0;
           break;
       }
       
       for (temp = 0; temp < 24; temp++)
       {
           if (i_rate <= Exp_Tbl[temp])
           {
               if (i_rate != Exp_Tbl[temp])
               {
                   //
                   // i_rate cannot be less than 1 and not equal to 0
                   // 
                   ASSERT(temp > 0);
                   temp--;
               }
               rate_FP.exp = (USHORT)temp;
               temp = Exp_Tbl[temp];
               Status = NDIS_STATUS_SUCCESS;
               break;
           }
       }

       if (Status == NDIS_STATUS_FAILURE)
       {
           // 
           // If there are trouble, give the lowest rate of transfer
           // 
           i_rate = Exp_Tbl[3];
           temp   = i_rate;
           *pRate = i_rate;
       }

       rate_FP.mant = (USHORT)(((i_rate - temp) * 512) / temp);

   } while (FALSE);

   *pRateInFP = rate_FP.reg;
}


⌨️ 快捷键说明

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