📄 ndisdevice.c
字号:
pHardware->m_bSpeed = 10;
pHardware->m_bDuplex = 1;
#endif
pHardware->m_RxDescInfo.cnAlloc = NUM_OF_RX_DESC;
pHardware->m_TxDescInfo.cnAlloc = NUM_OF_TX_DESC;
pHardware->m_pPciCfg = pAdapter;
pHardware->m_pDevice = pAdapter;
if ( ( nsStatus = GetResources( pAdapter, hConfiguration, hRegistry )) !=
NDIS_STATUS_SUCCESS )
{
goto ReadConfigurationDone;
}
ReadConfigurationDone:
NdisCloseConfiguration( hRegistry );
return( nsStatus );
} // ReadConfiguration
/*
DeRegisterAdapter
Description:
This routine de-registers the adapter from the operating system. It
releases the I/O address range used by the adapter.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
Return (None):
*/
VOID DeRegisterAdapter (
PNDIS_ADAPTER pAdapter )
{
PHARDWARE pHardware = &pAdapter->m_Hardware;
#ifdef DBG
DbgPrint( "DeRegister"NEWLINE );
#endif
if ( pHardware->m_pVirtualMemory )
{
#ifdef UNDER_CE
VirtualFree( pHardware->m_pVirtualMemory, 0, MEM_RELEASE );
pHardware->m_ulVIoAddr = 0;
#else
NdisMUnmapIoSpace( pAdapter->m_hAdapter,
pHardware->m_pVirtualMemory,
pAdapter->m_ulMemorySize );
#endif
pHardware->m_pVirtualMemory = NULL;
}
if ( pHardware->m_ulVIoAddr )
{
NdisMDeregisterIoPortRange( pAdapter->m_hAdapter,
pAdapter->m_ulIOBaseAddress, pAdapter->m_ulIOLength,
( PVOID ) pHardware->m_ulVIoAddr );
pHardware->m_ulVIoAddr = 0;
}
} // DeRegisterAdapter
/*
RegisterAdapter
Description:
This function registers the adapter to the NDIS wrapper. It acquires
the I/O address range to run the adapter.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
Return (NDIS_STATUS):
NDIS_STATUS_SUCCESS if successful; otherwise an error code indicating
failure.
*/
NDIS_STATUS RegisterAdapter (
PNDIS_ADAPTER pAdapter )
{
NDIS_PHYSICAL_ADDRESS PhysicalAddress;
NDIS_STATUS nsStatus = NDIS_STATUS_SUCCESS;
PHARDWARE pHardware = &pAdapter->m_Hardware;
#ifdef UNDER_CE
BOOL bResult;
#endif
#ifdef DBG
DbgPrint( "Register"NEWLINE );
#endif
if ( pAdapter->m_ulMemorySize )
{
NdisSetPhysicalAddressLow( PhysicalAddress,
pAdapter->m_ulMemoryAddress );
NdisSetPhysicalAddressHigh( PhysicalAddress, 0 );
nsStatus = NdisMMapIoSpace(( PVOID* ) &pHardware->m_pVirtualMemory,
pAdapter->m_hAdapter, PhysicalAddress,
pAdapter->m_ulMemorySize );
if ( nsStatus != NDIS_STATUS_SUCCESS )
{
goto RegisterAdapterError;
}
}
if ( pAdapter->m_ulIOLength )
{
#ifdef UNDER_CE
pHardware->m_pVirtualMemory = VirtualAlloc( 0, PAGE_SIZE, MEM_RESERVE,
PAGE_NOACCESS );
DEBUGMSG( ZONE_INIT, ( TEXT( "KS884X: VirtualAlloc at 0x%x.\r\n" ),
pHardware->m_pVirtualMemory ));
if ( !pHardware->m_pVirtualMemory )
goto RegisterAdapterError;
bResult = VirtualCopy( pHardware->m_pVirtualMemory,
( PVOID )( pAdapter->m_ulIOBaseAddress & ( ~( PAGE_SIZE - 1 ))),
PAGE_SIZE, PAGE_READWRITE | PAGE_NOCACHE );
pHardware->m_ulVIoAddr = ( ULONG ) pHardware->m_pVirtualMemory +
( pAdapter->m_ulIOBaseAddress & ( PAGE_SIZE - 1 ));
DEBUGMSG( ZONE_INIT, ( TEXT( "KS884X: VirtualCopy at 0x%x.\r\n" ),
pHardware->m_ulVIoAddr ));
#else
nsStatus = NdisMRegisterIoPortRange(( PVOID* ) &pHardware->m_ulVIoAddr,
pAdapter->m_hAdapter, pAdapter->m_ulIOBaseAddress,
pAdapter->m_ulIOLength );
#endif
if ( nsStatus != NDIS_STATUS_SUCCESS )
{
#ifndef UNDER_CE
NdisWriteErrorLogEntry( pAdapter->m_hAdapter,
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, 3, 0x10560010, 0x1,
pAdapter->m_ulIOBaseAddress );
#endif
goto RegisterAdapterError;
}
}
return( nsStatus );
RegisterAdapterError:
DeRegisterAdapter( pAdapter );
return( nsStatus );
} // RegisterAdapter
/* -------------------------------------------------------------------------- */
/*
InitMapRegisters
Description:
This local routine initializes the map register information structure.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
Return (None):
*/
static void InitMapRegisters (
PNDIS_ADAPTER pAdapter )
{
int i;
for ( i = 0; i < pAdapter->m_cnMapRegAlloc; i++ )
{
pAdapter->m_MapReg[ i ].uiRegister = i;
pAdapter->m_MapReg[ i ].pNdisBuffer = NULL;
pAdapter->m_MapReg[ i ].pNext = &pAdapter->m_MapReg[ i + 1 ];
}
pAdapter->m_MapReg[ i - 1 ].pNext = NULL;
pAdapter->m_pMapRegTop = pAdapter->m_MapReg;
pAdapter->m_cnMapRegAvail = pAdapter->m_cnMapRegAlloc;
} // InitMapRegisters
/*
AllocateMapRegisters
Description:
This local function allocates the mapping registers for use in
transmission.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
Return (NDIS_STATUS):
NDIS_STATUS_SUCCESS if successful; otherwise an error code indicating
failure.
*/
static NDIS_STATUS AllocateMapRegisters (
PNDIS_ADAPTER pAdapter )
{
PHARDWARE pHardware = &pAdapter->m_Hardware;
NDIS_STATUS NdisStatus;
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
NDIS_PHYSICAL_ADDRESS_CONST( -1, -1 );
#if defined(NDIS4_COMPATIBLE)
if ( NdisQueryMapRegisterCount( pAdapter->AdapterType,
&nMapRegisterCount ) == NDIS_STATUS_SUCCESS )
{
pAdapter->m_cnMapRegAlloc = nMapRegisterCount / 2;
}
else
{
pAdapter->m_cnMapRegAlloc = pHardware->m_TxDescInfo.cnAlloc;
}
#else
pAdapter->m_cnMapRegAlloc = pHardware->m_TxDescInfo.cnAlloc;
#endif
/* Need to call NdisMAllocateMapRegisters before NdisMAllocateSharedMemory
is used.
*/
NdisStatus = NdisMAllocateMapRegisters(
pAdapter->m_hAdapter,
0,
TRUE,
pAdapter->m_cnMapRegAlloc,
NDIS_BUFFER_SIZE );
if ( NdisStatus != NDIS_STATUS_SUCCESS )
{
pAdapter->m_cnMapRegAlloc = MIN_MAP_REGISTERS;
if ( NdisMAllocateMapRegisters(
pAdapter->m_hAdapter,
0,
TRUE,
pAdapter->m_cnMapRegAlloc,
NDIS_BUFFER_SIZE ) != NDIS_STATUS_SUCCESS )
{
pAdapter->m_cnMapRegAlloc = 0;
return NdisStatus;
}
}
#if (NDISVER >= 50)
NdisStatus = NdisAllocateMemoryWithTag(( PVOID* ) &pAdapter->m_MapReg,
sizeof( MAP_REG ) * pAdapter->m_cnMapRegAlloc, 'rciM' );
#else
NdisStatus = NdisAllocateMemory(( PVOID* ) &pAdapter->m_MapReg,
sizeof( MAP_REG ) * pAdapter->m_cnMapRegAlloc,
0, HighestAcceptableMax );
#endif
if ( NdisStatus != NDIS_STATUS_SUCCESS )
{
return( NdisStatus );
}
InitMapRegisters( pAdapter );
pAdapter->m_cnPackets = pHardware->m_RxDescInfo.cnAlloc;
#if (NDISVER >= 50)
NdisStatus = NdisAllocateMemoryWithTag(( PVOID* ) &pAdapter->m_PacketArray,
sizeof( PNDIS_PACKET ) * pAdapter->m_cnPackets, 'rciM' );
#else
NdisStatus = NdisAllocateMemory(( PVOID* ) &pAdapter->m_PacketArray,
sizeof( PNDIS_PACKET ) * pAdapter->m_cnPackets,
0, HighestAcceptableMax );
#endif
if ( NdisStatus != NDIS_STATUS_SUCCESS )
{
pAdapter->m_cnPackets = 0;
return( NdisStatus );
}
return NDIS_STATUS_SUCCESS;
} /* AllocateMapRegisters */
/*
AllocateSoftDescriptors
Description:
This local function allocates software descriptors for manipulation in
memory.
Parameters:
PTDescInfo pDescInfo
Pointer to descriptor information structure.
int fTransmit
Indication that descriptors are for transmit.
Return (NDIS_STATUS):
NDIS_STATUS_SUCCESS if successful; otherwise an error code indicating
failure.
*/
static NDIS_STATUS AllocateSoftDescriptors (
PTDescInfo pDescInfo,
int fTransmit )
{
NDIS_STATUS NdisStatus;
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
NDIS_PHYSICAL_ADDRESS_CONST( -1, -1 );
#if (NDISVER >= 50)
NdisStatus = NdisAllocateMemoryWithTag(( PVOID* ) &pDescInfo->pRing,
sizeof( TDesc ) * pDescInfo->cnAlloc, 'rciM' );
#else
NdisStatus = NdisAllocateMemory(( PVOID* ) &pDescInfo->pRing,
sizeof( TDesc ) * pDescInfo->cnAlloc,
0, HighestAcceptableMax );
#endif
if ( NdisStatus != NDIS_STATUS_SUCCESS )
{
return( NdisStatus );
}
NdisZeroMemory( pDescInfo->pRing, sizeof( TDesc ) * pDescInfo->cnAlloc );
HardwareInitDescriptors( pDescInfo, fTransmit );
return NDIS_STATUS_SUCCESS;
} /* AllocateSoftDescriptors */
/*
AllocateDescriptors
Description:
This local function allocates hardware descriptors for receiving and
transmitting.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
Return (NDIS_STATUS):
NDIS_STATUS_SUCCESS if successful; otherwise an error code indicating
failure.
*/
static NDIS_STATUS AllocateDescriptors (
PNDIS_ADAPTER pAdapter )
{
PHARDWARE pHardware = &pAdapter->m_Hardware;
int nOffset;
NDIS_STATUS NdisStatus;
/* Allocate memory for RX & TX descriptors. */
pAdapter->m_DescPool.ulAllocSize =
pHardware->m_RxDescInfo.nSize * pHardware->m_RxDescInfo.cnAlloc +
pHardware->m_TxDescInfo.nSize * pHardware->m_TxDescInfo.cnAlloc +
DESC_ALIGNMENT;
pAdapter->m_DescPool.bCached = FALSE;
NdisMAllocateSharedMemory( pAdapter->m_hAdapter,
pAdapter->m_DescPool.ulAllocSize,
pAdapter->m_DescPool.bCached,
&pAdapter->m_DescPool.pAllocVirtual,
&pAdapter->m_DescPool.AllocPhysicalAddr );
if ( pAdapter->m_DescPool.pAllocVirtual == NULL )
{
pAdapter->m_DescPool.ulAllocSize = 0;
return NDIS_STATUS_RESOURCES;
}
else if ( NdisGetPhysicalAddressHigh(
pAdapter->m_DescPool.AllocPhysicalAddr ) != 0 )
{
NdisMFreeSharedMemory( pAdapter->m_hAdapter,
pAdapter->m_DescPool.ulAllocSize,
pAdapter->m_DescPool.bCached,
pAdapter->m_DescPool.pAllocVirtual,
pAdapter->m_DescPool.AllocPhysicalAddr );
pAdapter->m_DescPool.ulAllocSize = 0;
pAdapter->m_DescPool.pAllocVirtual = NULL;
return NDIS_STATUS_RESOURCES;
}
NdisZeroMemory( pAdapter->m_DescPool.pAllocVirtual,
pAdapter->m_DescPool.ulAllocSize );
/* Align to the next cache line boundary. */
nOffset = ((( ULONG ) pAdapter->m_DescPool.pAllocVirtual % DESC_ALIGNMENT )
? ( DESC_ALIGNMENT -
(( ULONG ) pAdapter->m_DescPool.pAllocVirtual % DESC_ALIGNMENT )) : 0 );
pAdapter->m_DescPool.pVirtual = pAdapter->m_DescPool.pAllocVirtual +
nOffset;
pAdapter->m_DescPool.ulPhysical = NdisGetPhysicalAddressLow(
pAdapter->m_DescPool.AllocPhysicalAddr ) + nOffset;
/* Allocate receive/transmit descriptors. */
pHardware->m_RxDescInfo.phwRing = ( PTHw_Desc )
pAdapter->m_DescPool.pVirtual;
pHardware->m_RxDescInfo.ulRing = pAdapter->m_DescPool.ulPhysical;
nOffset = pHardware->m_RxDescInfo.cnAlloc * pHardware->m_RxDescInfo.nSize;
pHardware->m_TxDescInfo.phwRing = ( PTHw_Desc )
( pAdapter->m_DescPool.pVirtual + nOffset );
pHardware->m_TxDescInfo.ulRing = pAdapter->m_DescPool.ulPhysical + nOffset;
NdisStatus = AllocateSoftDescriptors( &pHardware->m_RxDescInfo, FALSE );
if ( NdisStatus != NDIS_STATUS_SUCCESS )
{
return( NdisStatus );
}
NdisStatus = AllocateSoftDescriptors( &pHardware->m_TxDescInfo, TRUE );
if ( NdisStatus != NDIS_STATUS_SUCCESS )
{
return( NdisStatus );
}
return NDIS_STATUS_SUCCESS;
} /* AllocateDescriptors */
/*
InitBuffers
Description:
This local routine initializes the DMA buffer information structure.
Parameters:
PBUFFER_INFO pBufInfo
Pointer to DMA buffer information structure.
Return (None):
*/
static void InitBuffers (
PBUFFER_INFO pBufInfo )
{
PDMA_BUFFER pDma;
int i;
#ifdef UNDER_CE
PDMA_BUFFER pPrevious = NULL;
pBufInfo->pTop = pBufInfo->BufArray;
pBufInfo->cnAvail = pBufInfo->cnAlloc;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -