📄 miniport.c
字号:
//---------------------------------------------------------------------------
// Copyright (C) 2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//--------------------------------------------------------------------------
//
// File: miniport.c
// Source file for platform specific SDIO WLAN functions
//------------------------------------------------------------------------------
#include "precomp.h"
NDIS_HANDLE NdisWrapperHandle = NULL;
/*****************************************************************************
**
** NAME DriverEntry
**
** PARAMETERS DriverObject Pointer to the driver object for this device.
** RegistryPath Registry path for this driver's key.
**
** RETURNS NT_SUCCESS or error code. See ntddk.h.
**
** DESCRIPTION This is the initial entry point for all NT Drivers.
**
******************************************************************************/
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_MINIPORT_CHARACTERISTICS NicChar;
// initialize the wrapper.
NdisMInitializeWrapper(
&NdisWrapperHandle,
DriverObject,
RegistryPath,
NULL);
if ( NdisWrapperHandle == NULL )
{
DBG_LEV0(("ERROR: NdisMInitializeWrapper failed!\n"));
return(NDIS_STATUS_FAILURE);
}
NdisZeroMemory( &NicChar, sizeof(NicChar) );
// initialize the Miniport characteristics
NicChar.MajorNdisVersion = NDIS_MAJOR_VERSION;
NicChar.MinorNdisVersion = NDIS_MINOR_VERSION;
NicChar.CheckForHangHandler = boMiniportCheckForHang;
NicChar.DisableInterruptHandler = NULL;
NicChar.EnableInterruptHandler = NULL;
NicChar.HaltHandler = vMiniportHalt;
NicChar.HandleInterruptHandler = NULL;
NicChar.ISRHandler = NULL;
NicChar.InitializeHandler = iMiniportInitialize;
NicChar.QueryInformationHandler = iMiniportQueryInformation;
NicChar.ResetHandler = iMiniportReset;
NicChar.ReturnPacketHandler = vMiniportReturnPacket;
NicChar.SendPacketsHandler = vMiniportSendPackets;
NicChar.SetInformationHandler = iMiniportSetInformation;
// register this Miniport driver with the NDIS wrapper
Status = NdisMRegisterMiniport(
NdisWrapperHandle,
&NicChar,
sizeof(NDIS_MINIPORT_CHARACTERISTICS));
DBG_LEV1(("DriverEntry: NdisMRegisterMiniport (stats = %x)\n", Status));
if ( Status != NDIS_STATUS_SUCCESS )
{
NdisTerminateWrapper( &NdisWrapperHandle, NULL );
}
return Status;
}
/*****************************************************************************
**
** NAME iMiniportInitialize
**
** PARAMETERS puiOpenErrorStatus Additional status code if open error
** status is returned.
** puiSelectedMediumIndex Index of media selected by Miniport.
** paeMediumArray Array of media available.
** uiMediumArraySize Size of media array.
** hMiniportAdapterHandle Handle to NDIS context for Miniport.
** hConfigurationHandle Handle to registry entries for Miniport.
**
** RETURNS NDIS_STATUS_SUCCESS or error code.
**
** DESCRIPTION This function is called to initialize each instance of the
** device. The function is called at IRQL Passive Level and may
** block on an event pending the completion of the boot procedure.
**
******************************************************************************/
NDIS_STATUS
iMiniportInitialize(
OUT PNDIS_STATUS puiOpenErrorStatus,
OUT PUINT puiSelectedMediumIndex,
IN PNDIS_MEDIUM paeMediumArray,
IN UINT uiMediumArraySize,
IN NDIS_HANDLE hMiniportAdapterHandle,
IN NDIS_HANDLE hConfigurationHandle)
{
NDIS_STATUS iStatus = NDIS_STATUS_FAILURE;
UINT uiLoop;
PEND_CONTEXT psAdapter = NULL;
NDIS_HANDLE hRegistryHandle = NULL;
DBG_LEV1(("iMiniportInitialize()\n"));
// Search for the medium type 802.3 in the given array.
for ( uiLoop = 0;
(uiLoop < uiMediumArraySize) && (paeMediumArray[uiLoop] != NdisMedium802_3);
uiLoop++);
do {
if ( uiLoop >= uiMediumArraySize )
{
DBG_LEV0(("ERROR: Couldn't find Ethernet in medium array.\n"));
iStatus = NDIS_STATUS_UNSUPPORTED_MEDIA;
break;
}
*puiSelectedMediumIndex = uiLoop;
// Allocate memory to hold the Adapter context.
iStatus = NdisAllocateMemoryWithTag( &psAdapter, sizeof(END_CONTEXT), 'caAC' );
if ( iStatus != NDIS_STATUS_SUCCESS )
{
DBG_LEV0(("ERROR: Couldn't allocate Adapter context!\n"));
break;
}
// Open configuration.
NdisOpenConfiguration( &iStatus, &hRegistryHandle, hConfigurationHandle );
if ( iStatus != NDIS_STATUS_SUCCESS )
{
DBG_LEV0(("ERROR: Couldn't open registry configuration!\n"));
break;
}
// Register the NIC, passing in a reference to the Adapter context.
NdisMSetAttributesEx(hMiniportAdapterHandle,
(NDIS_HANDLE)psAdapter,
END_CHECKFORHANG_INTERVAL,
#ifdef NDIS51_MINIPORT
NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS,
#else
0,
#endif
NdisInterfacePcMcia);
// Initialize the Adapter context.
NdisZeroMemory( psAdapter, sizeof(END_CONTEXT) );
psAdapter->hMiniportAdapterHandle = hMiniportAdapterHandle;
psAdapter->hConfigurationHandle = hConfigurationHandle;
psAdapter->eNetState = NET_STOPPED;
psAdapter->eMediaState = NdisMediaStateDisconnected;
psAdapter->ulPacketFilter = 0;
psAdapter->sHAL.psAdapter = psAdapter;
// Extract the device configuration from registry.
if (bCFGextractConfiguration( &psAdapter->sCFG, hRegistryHandle ))
{
iStatus = NDIS_STATUS_SUCCESS;
}
else
{
iStatus = NDIS_STATUS_FAILURE;
}
if ( iStatus != NDIS_STATUS_SUCCESS )
{
DBG_LEV0(("ERROR: Failed to read configuration (iStatus = %x)\n", iStatus));
iStatus = NDIS_STATUS_FAILURE;
break;
}
DBG_LEV3(("extract configuration done success\n"));
psAdapter->sHAL.boSupport4BitMode = psAdapter->sCFG.boSupport4BitMode;
psAdapter->sHAL.boSupportBlockMode = psAdapter->sCFG.boSupportBlockMode;
psAdapter->sHAL.ulBlockSize = psAdapter->sCFG.ulBlockSize;
psAdapter->sHAL.ulMaxBlockNumber = psAdapter->sCFG.ulMaxBlockNumber;
psAdapter->sHAL.ulMaxByteNumber = psAdapter->sCFG.ulMaxByteNumber;
psAdapter->sHAL.ulMaxClockFreq = psAdapter->sCFG.ulMaxClockFreq;
DBG_LEV3(("HAL struct SDIO params filled in\n"));
// Get SDIO device handle and initialize SDIO.
iStatus = iENDgetDeviceHandleSDIO( psAdapter, hRegistryHandle );
if ( iStatus == NDIS_STATUS_SUCCESS )
{
iStatus = iENDinitializeSDIO( psAdapter );
}
DBG_LEV3(("ENDinitializeSDIO complete\n"));
if ( iStatus != NDIS_STATUS_SUCCESS )
{
DBG_LEV0(("ERROR: Failed to claim necessary hardware resources.\n"));
iStatus = NDIS_STATUS_RESOURCES;
break;
}
// Allocate buffer pool for receiving packets.
NdisAllocateBufferPool( &iStatus, &psAdapter->hRxBufferPool, MAX_RX_PACKETS );
if ( iStatus == NDIS_STATUS_SUCCESS )
{
// Allocate packet pool for receiving packets.
NdisAllocatePacketPool( &iStatus, &psAdapter->hRxPacketPool,
MAX_RX_PACKETS, PROTOCOL_RESERVED_SIZE_IN_PACKET );
}
else
{
DBG_LEV0(("ERROR: Receive resources allocation failure (iStatus = %x)\n", iStatus));
iStatus = NDIS_STATUS_RESOURCES;
break;
}
// Initialize MAC address and check if need override.
vCFGgetMACID( &psAdapter->sCFG, (IEEE_ADDR *)psAdapter->ucCurrentAddress );
if ( *(PUSHORT)psAdapter->ucCurrentAddress != 0 ||
*(PUSHORT)(psAdapter->ucCurrentAddress+2) != 0 ||
*(PUSHORT)(psAdapter->ucCurrentAddress+4) != 0 )
psAdapter->boMACAddressOverride = TRUE;
// Initialize 802.11 WLAN block.
vENDInitializeWLAN( &psAdapter->sWlan, &psAdapter->sCFG );
// Get card status and CIS.
vHALGetCardInfo( &psAdapter->sHAL );
#ifdef CA_CE_GROUND
DBG_LEV1(("waiting for CE ground download.\n"));
#else // CA_CE_GROUND
// Download F/W.
if ( !boHALdownload( &psAdapter->sHAL, TRUE ) )
{
DBG_LEV0(("ERROR: Download F/W failed.\n"));
iStatus = NDIS_STATUS_FAILURE;
break;
}
DBG_LEV3(("HALdownload complete\n"));
// Initialize a timer for reset.
NdisMInitializeTimer(&psAdapter->sResetTimer,
hMiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION) vENDresetTimer,
(PVOID) psAdapter);
// Initialize a timer for MIC failure.
NdisMInitializeTimer(&psAdapter->sMicFailTimer,
hMiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION) vENDmicFailTimer,
(PVOID) psAdapter);
NdisMInitializeTimer(&psAdapter->sCFInterfacePSTimer,
hMiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION) vHALPSTimer,
(PVOID) psAdapter);
// Register Shutdown handler.
NdisMRegisterAdapterShutdownHandler(hMiniportAdapterHandle,
psAdapter,
vMiniportShutdown);
// Enable interrupt after downloading F/W.
vHALenableInterrupt( &psAdapter->sHAL );
#endif //CA_CE_GROUND
iStatus = NDIS_STATUS_SUCCESS;
} while ( FALSE );
// Close configuration.
if ( hRegistryHandle )
{
NdisCloseConfiguration( hRegistryHandle );
}
// If initialization failure, release all resources allocated.
if ( iStatus != NDIS_STATUS_SUCCESS )
{
vENDreleaseResources( psAdapter );
}
return iStatus;
}
/*****************************************************************************
**
** NAME vMiniportHalt
**
** PARAMETERS MiniportAdapterContext Pointer to Adapter context.
**
** RETURNS na
**
** DESCRIPTION This function is called when adapter is being stopped.
** Remove the adapter instance that was previously initialized.
**
******************************************************************************/
VOID
vMiniportHalt(
IN NDIS_HANDLE MiniportAdapterContext)
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)MiniportAdapterContext;
BOOLEAN boTimerCancelled;
DBG_LEV1(("vMiniportHalt()\n"));
// Disable interrupt.
vHALdisableInterrupt( &psAdapter->sHAL );
// Cancel reset timer if scheduled.
if ( psAdapter->boResetInProgress )
{
NdisMCancelTimer( &psAdapter->sResetTimer, &boTimerCancelled );
}
// Stop the device.
vHALstop( &psAdapter->sHAL );
// Unregister the Shutdown handler.
NdisMDeregisterAdapterShutdownHandler( psAdapter->hMiniportAdapterHandle );
// Release the hardware resources claimed by the device and the software resources.
vENDreleaseResources( psAdapter );
}
/*****************************************************************************
**
** NAME vMiniportShutdown
**
** PARAMETERS MiniportAdapterContext Pointer to Adapter context.
**
** DESCRIPTION This function is called during system shutdown.
** Disable interrupt and stop device, don't need to release
** any resources allocated.
**
******************************************************************************/
VOID
vMiniportShutdown(
IN PVOID MiniportAdapterContext)
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)MiniportAdapterContext;
// Disable interrupt.
vHALdisableInterrupt( &psAdapter->sHAL );
// Stop the device.
vHALstop( &psAdapter->sHAL );
}
/*****************************************************************************
**
** NAME iMiniportReset
**
** PARAMETERS AddressingReset TRUE if the wrapper should call
** MiniportSetInformation to restore
** addressing information.
** MiniportAdapterContext Pointer to Adapter context.
**
** RETURNS NDIS_STATUS_PENDING or error code.
**
** DESCRIPTION This function is called when NDIS determines that the NIC has
** hung. The function is responsible for restoring the hardware
** and software state to the initial state.
**
******************************************************************************/
NDIS_STATUS
iMiniportReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext)
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)MiniportAdapterContext;
PPENDING_OID psPendingOID = &psAdapter->sPendingOID;
PWLAN_CONTEXT psWlan = &psAdapter->sWlan;
PHAL_CONTEXT psHAL = &psAdapter->sHAL;
PCFG_CONTEXT psCFG = &psAdapter->sCFG;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -