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

📄 vc.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c) 2000 Microsoft Corporation. All rights reserved.

   File:       vc.c
 
               Developed for Toshiba by Elisa Research Inc., CA
               http://www.elisaresearch.com
               (510) 770-4920



Abstract:

	This module contains the routines that allow for the creation, deletion,
	activation and deactivation of virtual circuits.

Author:

	A. Wang

Environment:

	Kernel mode

Revision History:

	09/23/96		kyleb		Cleanup.
								Added support for NdisAllocateMemoryWithTag
								Fixed/cleanup transmit segment allocation code.
								Insert the VC_BLOCK in the hash table before
									the receiver is activated for the VC.
	10/01/96		kyleb		Added async VC completion and async receive
								buffer allocation.
	01/07/97		awang		Initial of Toshiba ATM 155 Device Driver.
   02/16/99        hhan        Use synchronize mode to allocate xmit buffer.
   03/04/99        hhan        Added support for MAX_AAL5_

--*/

#include "precomp.h"
#pragma hdrstop

#define MODULE_NUMBER	MODULE_VC

NDIS_STATUS
TbAtm155CreateVc(
   IN  NDIS_HANDLE         MiniportAdapterContext,
   IN  NDIS_HANDLE         NdisVcHandle,
   OUT PNDIS_HANDLE        MiniportVcContext
   )
/*++

Routine Description:

   This is the NDIS 4.1 handler to create a VC.  This will allocate necessary
   system resources for the VC.

Arguments:

   MiniportAdapterContext  -   Pointer to our ADAPTER_BLOCK.
   NdisVcHandle            -   Handle that NDIS uses to identify the VC that
                               is about to be created.
   MiniportVcContext       -   Storage to hold context information about
                               the newly created VC.

Return Value:

   NDIS_STATUS_SUCCESS     if we successfully create the new VC.
	NDIS_STATUS_RESOURCES   if we are unable to allocate system memory for
                           driver use.

--*/
{
   PADAPTER_BLOCK      pAdapter = (PADAPTER_BLOCK)MiniportAdapterContext;
   PVC_BLOCK           pVc;
   NDIS_STATUS         Status;

   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
       ("==>TbAtm155CreateVc\n"));

   //
   //	I'm paranoid.
   //
   *MiniportVcContext = NULL;

   //
   //	Allocate memory for the VC.
   //
   ALLOCATE_MEMORY(&Status, &pVc, sizeof(VC_BLOCK), '90DA');
   if (NDIS_STATUS_SUCCESS != Status)
   {
       return(NDIS_STATUS_RESOURCES);
   }

   //
   //	Initialize memory.
   //
   ZERO_MEMORY(pVc, sizeof(VC_BLOCK));

   //
   //	Attempt to allocate storage for the debug logs.
   //
   dbgInitializeDebugInformation(&pVc->DebugInfo);

   //
   //	Save a pointer to the adapter block with the vc.
   //
   pVc->Adapter = pAdapter;
   pVc->HwInfo = pAdapter->HardwareInfo;
   pVc->NdisVcHandle = NdisVcHandle;
   pVc->Sar = pAdapter->HardwareInfo->SarInfo;
   pVc->XmitDmaQ = &pAdapter->HardwareInfo->SarInfo->XmitDmaQ;
   pVc->RecvDmaQ = &pAdapter->HardwareInfo->SarInfo->RecvDmaQ;
   pVc->References = 1;

   NdisAllocateSpinLock(&pVc->lock);

   NdisAcquireSpinLock(&pAdapter->lock);

   //
   //	Add the VC to the adapter's inactive list.
   //
   InsertHeadList(&pAdapter->InactiveVcList, &pVc->Link);

   //
   //	This adapter has another reference...
   //
   tbAtm155ReferenceAdapter(pAdapter);

   NdisReleaseSpinLock(&pAdapter->lock);

   //
   //	Return the pointer to the new VC as the context.
   //
   *MiniportVcContext = (PNDIS_HANDLE)pVc;

   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
       ("<==TbAtm155CreateVc (Status: 0x%lx)\n", Status));

   return(Status);
}

NDIS_STATUS
TbAtm155DeleteVc(
   IN  NDIS_HANDLE MiniportVcContext
   )
/*++

Routine Description:

   This is the NDIS 4.1 handler to delete a given VC. This routine will
   free any resources that are associated with the VC.  For the VC to
   be deleted it MUST be deactivated first.

Arguments:

   MiniportVcContext   -   Pointer to the VC_BLOCK describing the VC that
                           is to be deleted.

Return Value:

   NDIS_STATUS_SUCCESS     if the VC is successfully deleted.

--*/
{
   PVC_BLOCK       pVc = (PVC_BLOCK)MiniportVcContext;
   PADAPTER_BLOCK  pAdapter = pVc->Adapter;

   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
       ("==>TbAtm155DeleteVc, Vc=(%lx)\n", pVc->VpiVci.Vci));

   NdisAcquireSpinLock(&pAdapter->lock);

   NdisDprAcquireSpinLock(&pVc->lock);

   //
   //	Verify that this VC is inactive.
   //
   if (VC_TEST_FLAG(pVc, fVC_ACTIVE) || VC_TEST_FLAG(pVc, fVC_DEACTIVATING))
   {
		DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
			("DeleteVc: Vc is either active [%u] or is deactivating [%u]\n", 
             VC_TEST_FLAG(pVc, fVC_ACTIVE), VC_TEST_FLAG(pVc, fVC_DEACTIVATING)));

       //	Cannot delete a VC that is still active.
       //
       NdisDprReleaseSpinLock(&pVc->lock);
       NdisReleaseSpinLock(&pAdapter->lock);


       DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
           ("<==TbAtm155DeleteVc (NDIS_STATUS_FAILURE)\n"));

       return(NDIS_STATUS_FAILURE);
   }

   //
   //	If a VC is deactive then it had better have only the creation
   //	reference count on it!
   //
   ASSERT(1 == pVc->References);

   //
   //	Remove the VC from the inactive list.
   //
   RemoveEntryList(&pVc->Link);

   NdisDprReleaseSpinLock(&pVc->lock);

   //
   //	Dereference the adapter.
   //
   tbAtm155DereferenceAdapter(pAdapter);

   NdisReleaseSpinLock(&pAdapter->lock);

   //
   //	Free any logs that were allocated.
   //
   dbgFreeDebugInformation(pVc->DebugInfo);

   //
   //	Clean up the resources that were allocated on behalf of the
   //	VC_BLOCK.
   //
   NdisFreeSpinLock(&pVc->lock);

#if DBG
   if (VC_TEST_FLAG(pVc, fVC_ALLOCATING_TXBUF))
   {
       DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR, 
               ("FREE_MEMORY: pVc(%lx) of VC(0x%lx) Flags(0x%lx)\n", 
               pVc, pVc->VpiVci.Vci, pVc->Flags));

       DBGBREAK(DBG_COMP_VC, DBG_LEVEL_ERR);
   }           
#endif // end of DBG           

   //
   //	Free the memory that was taken by the vc.
   //
   FREE_MEMORY(pVc, sizeof(VC_BLOCK));

   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
       ("<==TbAtm155DeleteVc (NDIS_STATUS_SUCCESS)\n"));

   return(NDIS_STATUS_SUCCESS);
}


ULONG
tbAtm155NextPowerOf2(
   ULONG RequestedSize
	)
/*++

Routine Description:

   If the RequestedSize is not a power of 2 then this routine will find the
   next highest...

Arguments:

   RequestedSize   -   Value to find the power of 2 for.

Return Value:

--*/
{
   ULONG	Value;

   if ((RequestedSize > 0) && (RequestedSize <= BLOCK_1K))
   {
       Value = BLOCK_1K;
   }
   else if ((RequestedSize > BLOCK_1K) && (RequestedSize <= BLOCK_2K))
   {
       Value = BLOCK_2K;
   }
   else if ((RequestedSize > BLOCK_2K) && (RequestedSize <= BLOCK_4K))
   {
       Value = BLOCK_4K;
   }
   else if ((RequestedSize > BLOCK_4K) && (RequestedSize <= BLOCK_8K))
   {
       Value = BLOCK_8K;
   }
   else if ((RequestedSize > BLOCK_8K) && (RequestedSize <= BLOCK_10K))
   {
       Value = BLOCK_10K;
   }
   else
   {
       Value = BLOCK_16K;
   }

   return(Value);

}


NDIS_STATUS
tbAtm155WriteEntryOfTheSramTbl(
   IN  PADAPTER_BLOCK  pAdapter,
   IN  ULONG           Dest,
   IN  PUSHORT         pPhData,
   IN	USHORT          LengthOfEntry
	)
/*++

Routine Description:

   This routine will write data to the entry to the specified table
   on on-board SRAM.

Arguments:

   pAdapter            -   Pointer to the adapter to program.
   Dest                -   Point to the entry of the table on SRAM
   pPhData             -   Point to the starting address of data array
                           to be written onto SRAM.
   LengthOfEntry       -   Number of words to be written to the table.

Return Value:

   NDIS_STATUS_SUCCESS     if the entry of VC state table is opened
                           successfully.

--*/
{
   NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;

//
//   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
//       ("==>tbAtm155WriteEntryOfTheSramTbl\n"));
//
//
//   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
//            ("Dest=0x%lx, pPhData=0x%lx, LengthOfEntry=%d\n",
//              Dest, pPhData, LengthOfEntry));
//

   for (
       ;
       (LengthOfEntry > 0) && (NDIS_STATUS_SUCCESS == Status);
       LengthOfEntry--, Dest++, pPhData++)
   {

       TBATM155_PH_WRITE_SRAM(pAdapter, Dest, *pPhData, &Status);

       if (NDIS_STATUS_SUCCESS != Status)
       {
	        DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
		        ("Failed to open the entry of the Vc state table.\n") );

           break;
       }
   }

//
//   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
//       ("<==tbAtm155WriteEntryOfTheSramTbl.\n"));
//

   return (Status);

}



NDIS_STATUS
tbAtm155AdjustTrafficParameters(
   IN  PADAPTER_BLOCK          pAdapter,
   IN  PATM_FLOW_PARAMETERS    pFlow,
   IN  BOOLEAN                 fRoundFlowUp,
   OUT PULONG                  pPreScaleVal,
   OUT PULONG                  pNumOfEntries
   )
/*++

Routine Description:

Arguments:

Return Value:

   NDIS_STATUS_SUCCESS     if we successfully allocate the bandwidth.
	NDIS_STATUS_FAILURE     if we are unable to allocate bandwidth for 
                           the flow parameters.

--*/
{
   PHARDWARE_INFO  pHwInfo = pAdapter->HardwareInfo;
   ULONG           PreScale_Val;
   ULONG           NumOfEntriesNeeded;
   ULONG           ActualPeakCellRate;
   BOOLEAN         fDone;
   ULONG           c;
   NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;


   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
       ("==>tbAtm155AdjustTrafficParameters\n"));

   do
   {

#if    AW_QOS
       //
       //	The Number of available CBR VCs
       //  9/17/97     - Please read the note where declares this
       //                variable (in SW.H).
       //	
       if (pAdapter->NumOfAvailableCbrVc == 0)
       {
           DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
               ("There is not enough remaining bandwidth to support even the minimum required bandwidth\n"));

           Status = NDIS_STATUS_FAILURE;
           break;
       }

#endif // end of AW_QOS

       //
       //	Verify the low end of the bandwidth
       //
       if (pAdapter->RemainingTransmitBandwidth < pAdapter->MinimumCbrBandwidth)
       {
           DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
               ("There is not enough remaining bandwidth to support even the minimum required bandwidth\n"));

           Status = NDIS_STATUS_FAILURE;
           break;
       }

       //
       //	Make sure we can satisfy the peak cell rate.
       //
       if (pFlow->PeakCellRate < pAdapter->MinimumCbrBandwidth)
           pFlow->PeakCellRate = pAdapter->MinimumCbrBandwidth;

       if ((pFlow->PeakCellRate > pAdapter->RemainingTransmitBandwidth) ||
           (pFlow->PeakCellRate < pAdapter->MinimumCbrBandwidth))
       {
           DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
               ("PeakCellRate is not within remaining and minimum\n"));

           DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
               ("PeakCellRate %u, RemainingBW %u\n", pFlow->PeakCellRate, pAdapter->RemainingTransmitBandwidth));

           Status = NDIS_STATUS_FAILURE;
           break;
       }

⌨️ 快捷键说明

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