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

📄 nicmemory.c

📁 3com 3c905网卡驱动硬件部分源码
💻 C
字号:
/*******************************************************************************
*** Note: Copy rights resevered to Beijing Pacific Linkair Communications Co. 
***
*** File Name: NICMemory.c
*** Purpose  : Shared Memory Cases Handlers
***
*** Author   : Guangzhao Tian
*** Modified : By Guangzhao Tian at 2000/10/19
***
**/

#include "NICMacro.h"
#include "NICWinReg.h"
#include "NICCommand.h"
#include "NICEeprom.h"
#include "NICMemory.h"
#include "NICData.h"
#include "NICHelper.h"
#include "NICExport.h"

/*************************************************************************** 
*** Allocating Memory Needed in Host System Memory Space
***  The memory needed by this model includs:
***  1. DPD lists, include the memory used by the lists, the Memory that used
***    to hold the packet data are allocated by protocol  when transimitting;
***	 2. UPD lists, include memory used by the lists, and the memory 
***	     buffers  to receive the uploaded data packets.
*/
NIC_STATUS Drv_MemSharedAlloc(IN NIC_INFORMATION * pAdapter)
{
	DWORD nCacheLineSize;

  /*  int x; 
    pAdapter = &gNic_Information; */

	DebugMsg("Allocate Shared Memory Now ... \n");
    pAdapter->Hardware.CacheLineSize = NIC_DEFAULT_CACHELINESIZE;
    pAdapter->Resources.nUPDNodeCount= NIC_DEFAULT_RECEIVE_COUNT;
    pAdapter->Resources.nDPDNodeCount= NIC_DEFAULT_SEND_COUNT;
    pAdapter->Resources.dwHostResourcesReserved =0;

	nCacheLineSize = pAdapter->Hardware.CacheLineSize;

    /* UPD structure memory requirement.*/
	pAdapter->Resources.lUPDMemOneSize = sizeof(UPD_LIST_ENTRY) + nCacheLineSize;
	pAdapter->Resources.lUPDMemTotalSize = pAdapter->Resources.nUPDNodeCount   *
                                           pAdapter->Resources.lUPDMemOneSize ;

    /* Receive buffer requirement.*/
	pAdapter->Resources.lRxDataBufferOneSize = ETHERNET_MAXIMUM_FRAME_SIZE + nCacheLineSize;

   /* DPD structure memory requirement.	*/
	pAdapter->Resources.lDPDMemOneSize = sizeof(DPD_LIST_ENTRY) + nCacheLineSize;
	pAdapter->Resources.lDPDMemTotalSize = pAdapter->Resources.nDPDNodeCount     * 
                                           pAdapter->Resources.lDPDMemOneSize ;

   /* Total memory requied for the UPD and DPD List Structure */
	pAdapter->Resources.lSharedMemorySize = pAdapter->Resources.lUPDMemTotalSize +
                                            pAdapter->Resources.lDPDMemTotalSize ;

	DebugMsg(" Now allocat memory from host ...");
   /*   Allocate the memory for UPD and DPD Lists */
	pAdapter->Resources.lSharedMemoryBase = NIC_MEM_Alloc(pAdapter->Resources.lSharedMemorySize);
     if(NULL == pAdapter->Resources.lSharedMemoryBase )
     {
        DebugMsg(" \nShared Memory Allocation Failure ! \n");
        return NIC_STATUS_FAILURE;
     } 

	pAdapter->Resources.dwHostResourcesReserved |= NIC_SHARED_MEMORY_ALLOCATED; 

	DebugMsg(" Done !\n");

    /* Zero out the memory.*/
   	 DebugMsg(" Zero out the allocated Memory ...");
    	NIC_MEM_ZeroOut(pAdapter->Resources.lSharedMemoryBase, pAdapter->Resources.lSharedMemorySize);
     DebugMsg("  Done !\n");

    /*************** --------- Carve out the regions ------ ******************/
  	  DebugMsg(" Now Carve out the regions in allocated Memory ...");

	/*  Base addresses of the UPD and DPD regions.  */
     pAdapter->Resources.lSharedMemUPDBase = pAdapter->Resources.lSharedMemoryBase;
     pAdapter->Resources.lSharedMemDPDBase = pAdapter->Resources.lSharedMemoryBase +
                                             pAdapter->Resources.lUPDMemTotalSize  ;

    /* PCI address of those Memory Region Base */
     pAdapter->Resources.pSharedMemoryBasePCI = Virt_to_Bus(pAdapter->Resources.lSharedMemoryBase); 

     pAdapter->Resources.pSharedMemUPDBasePCI = Virt_to_Bus(pAdapter->Resources.lSharedMemUPDBase);
     pAdapter->Resources.pSharedMemDPDBasePCI = Virt_to_Bus(pAdapter->Resources.lSharedMemDPDBase);
      DebugMsg(" Done ! \n");

      DebugMsg(" Now make up the UPD List and Data buffers ... ");
    if( NIC_STATUS_SUCCESS != Drv_MemMakeUPDList(pAdapter) )
    {
       DebugMsg(" \nFailed Building up the UPD List and the Rx Buffers ! \n");
       return NIC_STATUS_FAILURE;

    };
     DebugMsg(" Done ! \n");
 
      DebugMsg(" Now make up the DPD List ... ");
    if( NIC_STATUS_SUCCESS != Drv_MemMakeDPDList(pAdapter) )
    {
       DebugMsg(" \nFailed Building up the DPD List ! \n");
       return NIC_STATUS_FAILURE;

    };
     DebugMsg(" Done ! \n");

    DebugMsg("Allocate Shared Memory: Done ! \n");

/*   DebugMsg("\n\nHit a number to exit ! \n ");
      scanf("%d",&x);
     Drv_MemSharedFree(pAdapter);  */

	return NIC_STATUS_SUCCESS;
}

/****************************************************************************
*** ------- Make the UPD Link List Structures to form a RingBuffer --------- *** 
***/
NIC_STATUS Drv_MemMakeUPDList(IN PNIC_INFORMATION pAdapter)
{
    DWORD nCount,nAlignment=0,nCacheLineSize=0, nTempAddr;
    int a, b;

    PUPD_LIST_ENTRY pThisUPD     = NULL;
	PUPD_LIST_ENTRY pFirstUPD    = NULL;
	PUPD_LIST_ENTRY pPreviousUPD = NULL;

	DWORD    lUPDMemRegionBase;
	PPCIADDR pUPDMemRegionBasePCI;

    DWORD lThisUPDAddr, lPreviousUPDAddr;
	DWORD lFirstUPDAddr = 0;

    PPCIADDR pThisUPDAddrPCI, pPreviousUPDAddrPCI;
	PPCIADDR pFirstUPDAddrPCI = 0;

    DWORD lUPDMemOneSize;

/*    a=205; b=16; ;
    DebugMsg("a= %d, b= %d, c= a mod b: %d \n", a, b, a % b);*/

    lUPDMemRegionBase    = pAdapter->Resources.lSharedMemUPDBase ;
    pUPDMemRegionBasePCI = pAdapter->Resources.pSharedMemUPDBasePCI;
   	nCacheLineSize		 = pAdapter->Hardware.CacheLineSize;
    lUPDMemOneSize 		 = pAdapter->Resources.lUPDMemOneSize;

	for (nCount = 0; nCount < pAdapter->Resources.nUPDNodeCount; nCount++) 
	{
         nTempAddr =(ULONG) pUPDMemRegionBasePCI + nCount * lUPDMemOneSize;
         nAlignment = nCacheLineSize - (nTempAddr % nCacheLineSize ); 
    /*           DebugMsg("%d \n", (nTempAddr % nCacheLineSize ) );*/
		
          lThisUPDAddr = lUPDMemRegionBase + nAlignment + nCount * lUPDMemOneSize ;
          pThisUPD     = (PUPD_LIST_ENTRY) lThisUPDAddr ;

           pThisUPDAddrPCI =Virt_to_Bus(lThisUPDAddr);

       /*  Store the physical address of this UPD in the UPD itself. */
		  pThisUPD->ThisUPDAddrPCI = pThisUPDAddrPCI;

       	if (0 == nCount)
		{
			/* Store the virtual and physical address of the first UPD. */
              pFirstUPD  = pThisUPD;
		}
		else 
		{
			/*  Put the links in the UPDs. */
			pPreviousUPD->pNext          = pThisUPD;
			pPreviousUPD->UpNextPointerPCI  = pThisUPD->ThisUPDAddrPCI; /*must be PCI Mem Address*/
			pThisUPD->pPrevious          = pPreviousUPD;
		} 
		
	    /* Allocate the Data Buffer per UPD, and align it on 16 Bytes Boundry */
	    pThisUPD->pThisUPDRxBuffer= NIC_MEM_AlignAlloc(16,ETHERNET_MAXIMUM_FRAME_SIZE +2); 
        
		if (pThisUPD->pThisUPDRxBuffer == NULL) 
		{
			DebugMsg("	UPD Mem allocating failure ! \n");
			return NIC_STATUS_FAILURE;
		}
		 
		pThisUPD->UPDFragNode[0].nFragAddrPCI = Virt_to_Bus(pThisUPD->pThisUPDRxBuffer); /*Must be PCI Mem Address*/
		pThisUPD->UPDFragNode[0].nFragLength  = ETHERNET_MAXIMUM_FRAME_SIZE | 0x80000000;

	/* Make the current UPD as the previous one.
		previousUPDPhysical =(PUPD_LIST_ENTRY) currentUPDPhysical; */	
		pPreviousUPD =  pThisUPD;
	}

	/* Link the first and last UPDs to form a ring buffer */
	pThisUPD->pNext = pFirstUPD;
	pThisUPD->UpNextPointerPCI = pFirstUPD->ThisUPDAddrPCI; /*Must be PCI Mem Address*/
	pFirstUPD->pPrevious = pThisUPD;
	
	/* Save the address of the first UPD in the adapter structure. */
	pAdapter->Resources.pHeadUPD = pFirstUPD;

	return NIC_STATUS_SUCCESS;
}

/****************************************************************************
*** ------- Make the DPD Link List Structure, but not form a ringbuffer --------- *** 
***/
NIC_STATUS Drv_MemMakeDPDList(IN PNIC_INFORMATION pAdapter)
{
	
    DWORD nCount,nAlignment=0,nCacheLineSize=0, nTempAddr;

    PDPD_LIST_ENTRY pThisDPD     = NULL;
	PDPD_LIST_ENTRY pFirstDPD    = NULL;
	PDPD_LIST_ENTRY pPreviousDPD = NULL;

	DWORD    lDPDMemRegionBase;
	PPCIADDR pDPDMemRegionBasePCI;

    DWORD lThisDPDAddr, lPreviousDPDAddr;
	DWORD lFirstDPDAddr = 0;

    PPCIADDR pThisDPDAddrPCI, pPreviousDPDAddrPCI;
	PPCIADDR pFirstDPDAddrPCI = 0;

    DWORD lDPDMemOneSize;

    lDPDMemRegionBase    = pAdapter->Resources.lSharedMemDPDBase ;
    pDPDMemRegionBasePCI = pAdapter->Resources.pSharedMemDPDBasePCI;
   	nCacheLineSize		 = pAdapter->Hardware.CacheLineSize;
    lDPDMemOneSize		 = pAdapter->Resources.lDPDMemOneSize;

	for (nCount = 0; nCount < pAdapter->Resources.nDPDNodeCount; nCount++) 
	{
         nTempAddr =(ULONG) pDPDMemRegionBasePCI + nCount * lDPDMemOneSize;
         nAlignment = nCacheLineSize - ( nTempAddr % nCacheLineSize ); 
		
         lThisDPDAddr = lDPDMemRegionBase + nAlignment + nCount * lDPDMemOneSize ;
         pThisDPD     = (PDPD_LIST_ENTRY) lThisDPDAddr ;

	     pThisDPDAddrPCI = Virt_to_Bus(lThisDPDAddr);

       /*  Store the physical address of this DPD in the DPD itself. */
		  pThisDPD->ThisDPDAddrPCI = pThisDPDAddrPCI;

       	if (0 == nCount)
		{
			/* Store the virtual and physical address of the first DPD. */
              pFirstDPD  = pThisDPD;
		}
		else 
		{
			/*  Put the links in the DPDs. */
			pPreviousDPD->pNext               = pThisDPD;
			pPreviousDPD->DownNextPointerPCI  = pThisDPD->ThisDPDAddrPCI; /*must be PCI Mem Address*/
			pThisDPD->pPrevious               = pPreviousDPD;
		} 
		

	/* Make the current DPD as the previous one.
		previousDPDPhysical =(PDPD_LIST_ENTRY) currentDPDPhysical; */	
		pPreviousDPD =  pThisDPD;
	}

	/* Link the first and last DPDs, but not to form a ring buffer */
	pThisDPD->pNext = pFirstDPD;
	pFirstDPD->pPrevious = pThisDPD;
	
	/* Save the address of the first DPD in the adapter structure. */
	pAdapter->Resources.pHeadDPD = pFirstDPD; /*this is the first DPD*/
	pAdapter->Resources.pTailDPD = pFirstDPD; /*when the DPD is all free, the pTailDPD == pFirstDPD, when
                                                data packetd into DPD List, then pTailDPD moves on  */

	return NIC_STATUS_SUCCESS;
}

/****************************************************************************
*** Memroy Shared Free Routines 
***/
void Drv_MemSharedFree(IN PNIC_INFORMATION pAdapter	)
{
    DWORD nCount;

    PUPD_LIST_ENTRY pThisUPD     = NULL;
	PUPD_LIST_ENTRY pFirstUPD    = NULL;

   DebugMsg(" Now free all the Host Resources ! \n");
/*  if (pAdapter->dwHostResourcesReserved & NIC_INTERRUPT_REGISTERED) 
    {
		DebugMsg(" Now UnHook the Interruptor assigned ! \n"));
		free_irq(device->irq, device);
		pAdapter->dwHostResourcesReserved &= ~NIC_INTERRUPT_REGISTERED;
	}
*/
    DebugMsg("  Now free the shared memory allocated in host system ... \n ");
	if (pAdapter->Resources.dwHostResourcesReserved & NIC_SHARED_MEMORY_ALLOCATED)
    {
        if(NULL != pAdapter->Resources.lSharedMemoryBase )
        {
           DebugMsg(" First, Free the Rx Data Buffer of each UPD: "); 
            pFirstUPD=pAdapter->Resources.pHeadUPD;
            pThisUPD=pFirstUPD;

  	        while(1) 
     	    {
          	    if(NULL != pThisUPD->pThisUPDRxBuffer )
                {
                   NIC_MEM_Free(pThisUPD->pThisUPDRxBuffer);
                   pThisUPD->pThisUPDRxBuffer=NULL;
                   DebugMsg(".");
                }

              if(pThisUPD->pNext == pFirstUPD) break;

              pThisUPD= pThisUPD->pNext;
		    }
            
            DebugMsg(" Done ! \n");
          
          NIC_MEM_Free(pAdapter->Resources.lSharedMemoryBase);
        
          pAdapter->Resources.lSharedMemoryBase=NULL;
		  pAdapter->Resources.dwHostResourcesReserved &= ~NIC_SHARED_MEMORY_ALLOCATED;
        }
	}

    DebugMsg(" Done ! \n");

   DebugMsg(" Host Resources All Freed -- Done ! \n");
}

/***  Above are routines about Shared Memory Handlers
***    End of NICMemory.c
************************************************************************************/

⌨️ 快捷键说明

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