?? car6k.cpp
字號:
if (A_OK != status)
goto done;
status = configTargetParams();
done:
NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: -StartEndpoints status=%u", status);
return status;
}
void
CAR6KMini::StopEndpoints()
//
// Undoes the initialization done by StartEndpoints.
//
{
NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: +StopEndpoints");
if (m_HTCStarted) {
HTCStop(m_pHTCTarget);
m_HTCStarted = false;
}
if (!m_Config.byPassWmi) {
if (m_pWMI) {
wmi_shutdown((wmi_t *)m_pWMI);
m_WMIReady = false;
m_pWMI = NULL;
}
}
NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: -StopEndpoints");
}
void
ResetPowerWorkItemFunction(
PNDIS_WORK_ITEM WorkItem,
PVOID Context)
{
CAR6KMini *pAdapter = (CAR6KMini *)Context;
pAdapter->ResetPowerWorkItem();
}
void
AR6KWorkItemFunction(
PNDIS_WORK_ITEM WorkItem,
PVOID Context)
//
// This function is called after NdisScheduleWorkItem is called in MiniportInitialize.
//
{
CAR6KMini *pAdapter = (CAR6KMini *)Context;
pAdapter->IndicateReceivePackets();
}
/* Set the internal state variables based on the registry parameters */
A_STATUS
CAR6KMini::configRegistryParameters()
{
switch(m_Config.powerSaveMode) {
case 0:
m_80211_PowerMode = Ndis802_11PowerModeCAM;
break;
case 1:
m_ListenInterval = MAX_LISTEN_INTERVAL;
m_80211_PowerMode = Ndis802_11PowerModeMAX_PSP;
break;
case 2:
m_ListenInterval = MIN_LISTEN_INTERVAL;
m_80211_PowerMode = Ndis802_11PowerModeFast_PSP;
break;
default:
return A_ERROR;
}
return A_OK;
}
/* Configure the target from the registry settings only in wmi mode */
A_STATUS
CAR6KMini::configTargetParams()
{
A_STATUS wmiStatus = A_OK;
A_UINT8 powerMode = 0;
if (!m_Config.byPassWmi) {
if (m_Config.bkScanEnable) {
wmiStatus = wmi_scanparams_cmd((wmi_t *)m_pWMI,0,0,(A_UINT16)m_Config.bkScanPeriod,
70,0,WMI_SHORTSCANRATIO_DEFAULT);
} else {
wmiStatus = wmi_scanparams_cmd((wmi_t *)m_pWMI,0,0,0,
70,0,WMI_SHORTSCANRATIO_DEFAULT);
}
if (wmiStatus == A_OK) {
if (m_Config.discTimeout) {
wmiStatus = wmi_disctimeout_cmd((wmi_t *)m_pWMI, m_Config.discTimeout);
}
}
/* restore the target Power Save settings */
if ( wmiStatus == A_OK ) {
switch( m_80211_PowerMode ) {
case Ndis802_11PowerModeCAM:
powerMode = MAX_PERF_POWER;
break;
case Ndis802_11PowerModeMAX_PSP:
powerMode = REC_POWER;
break;
case Ndis802_11PowerModeFast_PSP:
powerMode = REC_POWER;
break;
default:
// this will never occur.
break;
}
wmiStatus = wmi_powermode_cmd((struct wmi_t *)m_pWMI, powerMode);
}
}
return wmiStatus;
}
#ifdef WINDOWS_MOBILE
A_STATUS setWiFiStator()
{
HKEY handle;
LONG result;
DWORD data;
A_STATUS status = A_ERROR;
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\STATE\\HARDWARE"),0,0,&handle);
if (result == ERROR_SUCCESS) {
data = 0x1; //Start with WLAN module available
result = RegSetValueEx(handle,_T("WiFi"),0,REG_DWORD,(LPBYTE)&data,sizeof(DWORD));
if (result == ERROR_SUCCESS) {
status = A_OK;
}
RegCloseKey(handle);
}
return status;
}
#endif
A_UINT32
CAR6KMini::getResetPowerState()
{
#ifdef WINDOWS_MOBILE
BOOL wirelessState;
#endif
A_UINT32 powerState;
// Read the reset state configured thru the registry
powerState = m_Config.resetPowerState;
#ifdef WINDOWS_MOBILE
// For windows mobile read the flight mode status
if (GetWirelessState(&wirelessState) == ERROR_SUCCESS) {
powerState = powerState & (wirelessState ? 1 : 0);
}
#endif
NDIS_DEBUG_PRINTF(ATH_LOG_INF,"Reset Power State = %d \n",powerState);
return powerState;
}
#if defined CF
#ifdef WINDOWS_MOBILE
#define AR6K_DEVICE_POWER_NAME TEXT("SYSTEM\\netui-AR6K1")
#else
#define AR6K_DEVICE_POWER_NAME _T("{98C5250D-C29A-4985-AE5F-AFE5367E5006}\\AR6K_CF1")
#endif
#elif defined SDIO
#define AR6K_DEVICE_POWER_NAME _T("{98C5250D-C29A-4985-AE5F-AFE5367E5006}\\AR6K_SD1")
#else
#error "Bus type not defined"
#endif
void
CAR6KMini::ResetPowerWorkItem()
{
A_UINT32 powerState;
#ifdef WINDOWS_MOBILE
RDD * pDevice = NULL;
RDD * pTD;
HRESULT hr = S_OK;
HANDLE driverStateEvent;
#else
CEDEVICE_POWER_STATE cePowerState;
DWORD status;
#endif
A_STATUS athStatus=A_ERROR;
NDIS_DEBUG_PRINTF(ATH_LOG_TRC,"ResetPowerWorkItem :: Entry\n");
NdisResetEvent(&m_ResetPowerWorkItemExitedEvent);
if (!m_Config.byPassWmi) {
// Dual-Purpose workitem
// Indicate disconnect after the MiniportInit complete successfully
// This is needed for 802.11 miniports
while (m_Halting == false) {
NdisMSleep(1000);
if ((m_InitComplete) && (m_WMIReady)) {
NdisMIndicateStatus(m_MiniportAdapterHandle, NDIS_STATUS_MEDIA_DISCONNECT, 0, 0);
NdisMIndicateStatusComplete(m_MiniportAdapterHandle);
break;
}
}
powerState = getResetPowerState();
if ((!powerState) && (m_Halting == false)) {
#ifdef WINDOWS_MOBILE
// Windows mobile notifies this event when the driver has completed initalization
driverStateEvent = CreateEvent(NULL, FALSE, FALSE, AR6K_DEVICE_POWER_NAME);
if (driverStateEvent != NULL) {
WaitForSingleObject(driverStateEvent, INFINITE);
CloseHandle(driverStateEvent);
}
// Wait till the WiFi entry is created
while (m_Halting == false) {
hr = GetWirelessDevices(&pDevice, 0);
if (hr == S_OK) {
if (pDevice) {
pTD = pDevice;
// loop through the linked list of devices
while (pTD) {
if (pTD->DeviceType==POWER_MANAGED) {
hr=ChangeRadioState(pTD, 0, POWER_POST_SAVE);
if (hr == S_OK) {
athStatus = A_OK;
// Update the registry state
UpdateRadioStoredState(pTD,0);
}
}
pTD = pTD->pNext;
}
// Free the list of devices retrieved with GetWirelessDevices()
FreeDeviceList(pDevice);
pDevice = NULL;
break;
}
} else {
break;
}
NdisMSleep(1000);
}
if (pDevice) {
FreeDeviceList(pDevice);
}
#else //WINDOWS_MOBILE
// Don't call the Power Manager APIs directly.
// Doing so assumes the PM is sysgen'ed into every image.
typedef DWORD DevicePowerNotifyProto(PVOID, CEDEVICE_POWER_STATE, DWORD);
typedef DWORD GetDevicePowerProto (PVOID, DWORD, PCEDEVICE_POWER_STATE);
DevicePowerNotifyProto *pfnDevicePowerNotify = NULL;
GetDevicePowerProto *pfnGetDevicePower = NULL;
HMODULE hCoreDll = (HMODULE) LoadLibrary(TEXT("coredll.dll"));
if (NULL != hCoreDll) {
pfnDevicePowerNotify = (DevicePowerNotifyProto *)
GetProcAddress(hCoreDll, TEXT("DevicePowerNotify"));
pfnGetDevicePower = (GetDevicePowerProto *)
GetProcAddress(hCoreDll, TEXT("GetDevicePower"));
}
if ((NULL == pfnDevicePowerNotify) || (NULL == pfnGetDevicePower))
{
athStatus = A_ERROR;
} else {
// Improper way to find whether NDIS has created the power
// reletionship for the miniport using RegisterPowerRelationship
// with the power manager
while (m_Halting == false) {
status= pfnGetDevicePower((PVOID)AR6K_DEVICE_POWER_NAME, POWER_NAME, &cePowerState);
if (status != ERROR_FILE_NOT_FOUND) {
break;
}
NdisMSleep(1000);
}
if ((status == ERROR_SUCCESS) && (m_Halting == false)) {
cePowerState = D4;
status = pfnDevicePowerNotify((PVOID)AR6K_DEVICE_POWER_NAME,cePowerState,POWER_NAME);
if (status == ERROR_SUCCESS) {
athStatus = A_OK;
}
}
}
if (NULL != hCoreDll) {
FreeLibrary(hCoreDll);
}
#endif
if (athStatus == A_ERROR) {
NDIS_DEBUG_PRINTF(ATH_LOG_ERR,"ResetPowerWorkItem :: Reset power state set failed\n");
} else {
NDIS_DEBUG_PRINTF(ATH_LOG_INF,"ResetPowerWorkItem :: Reset power state set success\n");
}
}
}
NdisSetEvent(&m_ResetPowerWorkItemExitedEvent);
NDIS_DEBUG_PRINTF(ATH_LOG_TRC,"ResetPowerWorkItem :: Exit\n");
return;
}
NDIS_STATUS
CAR6KMini::Initialize(
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE ConfigHandle)
//
// This function is called by NDIS when a new adapter
// instance is being instantiated.
//
// Read configuration settings from the registry and
// initialize the AR6000 adapter.
//
{
NDIS_STATUS Status;
A_STATUS athStatus = A_OK;
NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: +Initialize");
NdisInitializeEvent(&m_tgtReadyEvent);
NdisInitializeEvent(&m_WMIReadyEvent);
NdisInitializeEvent(&m_RxPendingEvent);
NdisInitializeEvent(&m_RxWorkItemExitedEvent);
NdisInitializeEvent(&m_tgtStatsEvent);
NdisInitializeEvent(&m_ResetPowerWorkItemExitedEvent);
NdisSetEvent(&m_RxWorkItemExitedEvent);
NdisSetEvent(&m_ResetPowerWorkItemExitedEvent);
NdisResetEvent(&m_tgtReadyEvent);
m_MaxTransmitBuffers = DEFAULT_MAX_TRANSMIT_BUFFERS;
m_MaxTransmitBufferPayloadDataLength = DEFAULT_MAX_TRANSMIT_BUFFER_PAYLOAD_DATA_LENGTH;
InitializeListHead(&m_TransmitBufferList);
InitializeListHead(&m_TransmitNdisPacketList);
InitializeListHead(&m_RxPendingPacketList);
memset(m_DesiredAPBSSID, 0xFF, sizeof(m_DesiredAPBSSID));
m_PowerChangeEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("AR6K_PowerChange"));
if (m_PowerChangeEvent == NULL) {
goto done;
}
// Perform base class initialization first
Status = CMiniport::Initialize(MiniportAdapterHandle, ConfigHandle);
if (NDIS_STATUS_SUCCESS != Status)
goto done;
Status = ParseRegistryParameters(ConfigHandle, &m_Config);
if (NDIS_STATUS_SUCCESS != Status)
goto done;
if (configRegistryParameters() != A_OK)
goto done;
//
// If the SDIO component is uninitialized, then we should not be
// getting called. If we do, for some reason, then return an error.
//
Status = TransmitBufferListAllocate();
if (NDIS_STATUS_SUCCESS != Status)
goto done;
NdisAllocatePacketPool(&Status, &m_RxPacketPool, AR6000_MAX_RX_BUFFERS, 16);
if (NDIS_STATUS_SUCCESS != Status)
goto done;
// Create a work item to peform receive packet indications
NdisInitializeWorkItem(&m_WorkItem, AR6KWorkItemFunction, this);
Status = NdisScheduleWorkItem(&m_WorkItem);
if (NDIS_STATUS_SUCCESS != Status)
goto done;
// Create a work item to power off wlan upon reset
NdisInitializeWorkItem(&m_ResetPowerWorkItem, ResetPowerWorkItemFunction, this);
Status = NdisScheduleWorkItem(&m_ResetPowerWorkItem);
if (NDIS_STATUS_SUCCESS != Status)
goto done;
// Register with HTC
athStatus = HTCInit();
if (athStatus != A_OK)
goto done;
m_HTCInited = true;
athStatus = HTCEventReg(NULL, ENDPOINT_UNUSED, HTC_TARGET_AVAILABLE, AR6KTargetAvailableEventHandler, this);
if (athStatus != A_OK)
goto done;
athStatus = HTCEventReg(NULL, ENDPOINT_UNUSED, HTC_TARGET_UNAVAILABLE, AR6KTargetUnavailableEventHandler, this);
if (athStatus != A_OK)
goto done;
NdisWaitEvent(&m_tgtReadyEvent, AR6K_DEFAULT_MS_TO_WAIT_FOR_TGT_READY);
if (!m_tgtReady)
{
NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - No TGT_READY event after %u ms, failing initialization\n", AR6K_DEFAULT_MS_TO_WAIT_FOR_TGT_READY);
athStatus = A_ERROR;
goto done;
}
#ifdef WINDOWS_MOBILE
athStatus = setWiFiStator();
if (athStatus != A_OK) {
athStatus = A_ERROR;
goto done;
}
#endif
m_InitComplete = true;
done:
if (athStatus != A_OK)
Status = NDIS_STATUS_FAILURE;
if (NDIS_STATUS_SUCCESS != Status)
{
// If we fail Initialize, then our Halt won't be called by NDIS,
// so clean up all resources allocated by Initialize.
Halt();
}
NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: -Initialize status=%x", Status);
return Status;
}
void
CAR6KMini::Halt()
//
// This function undoes Initialize.
// It stops the adapter and frees resources
//
{
NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: +Halt");
m_Halting = true;
if (m_Connected) {
NdisMIndicateStatus(m_MiniportAdapterHandle, NDIS_STATUS_MEDIA_DISCONNECT, 0, 0);
NdisMIndicateStatusComplete(m_MiniportAdapterHandle);
m_Connected = FALSE;
}
// Wakeup the Rx Work Item thread so it can exit
NdisSetEvent(&m_RxPendingEvent);
NdisWaitEvent(&m_RxWorkItemExitedEvent, 0);
// Wakeup the Get Stats thread if any
NdisSetEvent(&m_tgtStatsEvent);
NdisWaitEvent(&m_ResetPowerWorkItemExitedEvent, 0);
NdisFreeEvent(&m_tgtReadyEvent);
NdisFreeEvent(&m_WMIReadyEvent);
NdisFreeEvent(&m_RxPendingEvent);
NdisFreeEvent(&m_RxWorkItemExitedEvent);
NdisFreeEvent(&m_tgtStatsEvent);
NdisFreeEvent(&m_ResetPowerWorkItemExitedEvent);
#ifdef SUPPORT_WPA2
if( m_pPMKID ) {
A_FREE(m_pPMKID);
m_pPMKID = NULL;
}
#endif //SUPPORT_WPA2
if (m_pAssocInfo != NULL) {
A_FREE(m_pAssocInfo);
m_pAssocInfo = NULL;
}
if (m_PowerChangeEvent) {
CloseHandle(m_PowerChangeEvent);
m_PowerChangeEvent = NULL;
}
if (m_HTCInited) {
HTCShutDown(m_pHTCTarget);
m_HTCInited = false;
}
CMiniport::Halt();
if (m_pTransmitBufferArray)
A_FREE(m_pTransmitBufferArray);
if (m_RxPacketPool)
NdisFreePacketPool(m_RxPacketPool);
NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: -Halt");
}
BOOLEAN
CAR6KMini::CheckForHang()
//
// This function is called periodically (default every 2 seconds) by NDIS
// to check whether the adapter is in a hung state in which it is no longer
// sending/receiving. If this function returns TRUE, then NDIS will reset
// the adapter.
//
{
return FALSE;
}
NDIS_STATUS
CAR6KMini::Reset(
OUT PBOOLEAN pAddressingReset)
//
// This function is called by NDIS to reset the adapter.
// If addressing information needs to be reset (e.g. the multicast list),
// then *pAddressingReset should be set to TRUE.
//
{
return NDIS_STATUS_SUCCESS;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -