A_STATUS ar6000_enter_exit_deep_sleep_state(AR_SOFTC_T *ar, A_BOOL exit) { A_STATUS status = A_OK; if (down_interruptible(&ar->arSem)) { return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,exit, ar->arWlanPowerState)); #ifdef CONFIG_PM AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff)); #endif do { WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent ; WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode; if (exit) { A_UINT16 fg_start_period; /* Not in deep sleep state.. exit */ if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) { break; } fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; hostSleepMode.awake = TRUE; hostSleepMode.asleep = FALSE; if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != A_OK) { break; } wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE; ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)&wmiSleepEvent, sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); /* Enable foreground scanning */ if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period, ar->scParams.fg_end_period, ar->scParams.bg_period, ar->scParams.minact_chdwell_time, ar->scParams.maxact_chdwell_time, ar->scParams.pas_chdwell_time, ar->scParams.shortScanRatio, ar->scParams.scanCtrlFlags, ar->scParams.max_dfsch_act_time, ar->scParams.maxact_scan_per_ssid)) != A_OK) { break; } if (ar->arSsidLen) { if (ar6000_connect_to_ap(ar) != A_OK) { /* no need to report error if connection failed */ break; } } /* Change the state to ON */ ar->arWlanPowerState = WLAN_POWER_STATE_ON; } else { WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = FALSE }; /* Already in deep sleep state.. exit */ if (ar->arWlanPowerState == WLAN_POWER_STATE_DEEP_SLEEP) { break; } /* make sure we disable wow for deep sleep */ if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!=A_OK) { break; } wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP; ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)&wmiSleepEvent, sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); /* Disconnect from the AP and disable foreground scanning */ AR6000_SPIN_LOCK(&ar->arLock, 0); if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { AR6000_SPIN_UNLOCK(&ar->arLock, 0); wmi_disconnect_cmd(ar->arWmi); } else { AR6000_SPIN_UNLOCK(&ar->arLock, 0); } ar->scan_triggered = 0; if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != A_OK) { break; } ar6000_TxDataCleanup(ar); #ifndef ATH6K_CONFIG_OTA_MODE wmi_powermode_cmd(ar->arWmi, REC_POWER); #endif hostSleepMode.awake = FALSE; hostSleepMode.asleep = TRUE; if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!=A_OK) { break; } if (ar->arTxPending[ar->arControlEp]) { A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent, ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ); if (!timeleft || signal_pending(current)) { status = A_ERROR; break; } } status = hifWaitForPendingRecv(ar->arHifDevice); ar->arWlanPowerState = WLAN_POWER_STATE_DEEP_SLEEP; } } while (0); if (status!=A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", exit)); } up(&ar->arSem); return status; }
A_STATUS RunConnectionTest() { A_STATUS status = A_OK; HTC_ENDPOINT_ID endpointID; int length; DWORD startTime; DWORD currentTime; DWORD dhcpRequestTimeStart; int dhcpAttempt = 0; /* set initial status and state */ g_WifiMTE.TestState = TEST_STATE_WAIT_WMI_READY; startTime = A_GET_SECONDS_TICK(); while (A_SUCCESS(status) && (g_WifiMTE.TestState != TEST_GEN_FAILURE)) { currentTime = A_GET_SECONDS_TICK(); A_ASSERT(startTime <= currentTime); if ((currentTime - startTime) >= CONNECTION_TEST_EXPIRATION) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("Time Expired! Current State: %d \r\n", g_WifiMTE.TestState)); status = A_ERROR; break; } endpointID = ENDPOINT_MAX; /* poll for a message */ status = HTCGetMessage(g_WifiMTE.htcHandle, &endpointID, g_WifiMTE.pReceivePayloadStart, /* reuse transmit buffer */ MAX_MESSAGE_BUFFER_SIZE, &length, 0); /* no timeout */ if (A_FAILED(status)) { break; } if (endpointID == ENDPOINT_MAX) { /* polling was successful, but no message was retrieved */ continue; } if (endpointID == g_WifiMTE.ControlEp) { /* process control message */ status = wmi_control_rx(g_WifiMTE.pReceivePayloadStart, length); } else if (endpointID == g_WifiMTE.DataEp) { A_UINT8 *pNetFrameStart; int networkFrameLength; A_UINT16 etherType; /* process data message */ /* get the frame information, the payload is the WMI message */ wmi_get_network_frame_info(g_WifiMTE.pReceivePayloadStart, length, &pNetFrameStart, &networkFrameLength, ðerType); if ((networkFrameLength != 0) && (etherType == 0x0800)) { /* an IP packet arrived */ if (!g_WifiMTE.GotDhcpOffer) { /* run it through DHCP */ if (CheckDHCPOffer(pNetFrameStart,networkFrameLength)) { g_WifiMTE.GotDhcpOffer = TRUE; } } } } else { A_ASSERT(FALSE); status = A_EPROTO; break; } if (A_FAILED(status)) { break; } /* run through state machine */ switch (g_WifiMTE.TestState) { case TEST_STATE_WAIT_WMI_READY : if (g_WifiMTE.WMIReady) { DBG_LOG_PRINT(DBG_ZONE_INIT, ("WMI is ready\n")); /* next state is to wait for connection */ g_WifiMTE.TestState = TEST_STATE_WAIT_WMI_CONNECT; status = ar6000_set_wmi_protocol_ver(g_WifiMTE.HifDevice, g_WifiMTE.TargetInfo.target_type, WMI_PROTOCOL_VERSION); if (A_FAILED(status)) { A_ASSERT(FALSE); break; } /* make sure we are fully awake */ DBG_LOG_PRINT(DBG_ZONE_INIT, ("Changing power mode\n")); status = wmi_powermode_cmd(MAX_PERF_POWER); if (A_FAILED(status)) { break; } DBG_LOG_PRINT(DBG_ZONE_INIT, ("Sending connect\n")); /* connect to SSID */ status = wmi_connect_cmd(INFRA_NETWORK, OPEN_AUTH, NONE_AUTH, NONE_CRYPT, 0, NONE_CRYPT, 0, g_WifiMTE.SSIDLength, g_WifiMTE.SSID, NULL, g_WifiMTE.WiFiChannel, 0); } break; case TEST_STATE_WAIT_WMI_CONNECT : if (g_WifiMTE.APConnected) { /* next state */ g_WifiMTE.TestState = TEST_WAIT_DHCP_REPLY; /* capture start time to retry DHCP request */ dhcpRequestTimeStart = A_GET_SECONDS_TICK(); DBG_LOG_PRINT(DBG_ZONE_INIT, ("Sending DHCP Discover... \r\n")); status = SendDhcpDiscover(g_WifiMTE.TransmitBuffer); if (A_FAILED(status)) { break; } } break; case TEST_WAIT_DHCP_REPLY : if ((A_GET_SECONDS_TICK() - dhcpRequestTimeStart) > 1) { dhcpAttempt++; /* time expired, resend DHCP again */ DBG_LOG_PRINT(DBG_ZONE_INIT, ("Retrying DHCP request.. re-attempt : %d \r\n", dhcpAttempt)); dhcpRequestTimeStart = A_GET_SECONDS_TICK(); /* resend again */ status = SendDhcpDiscover(g_WifiMTE.TransmitBuffer); if (A_FAILED(status)) { break; } } if (g_WifiMTE.GotDhcpOffer) { /* issue get status command and wait for response */ g_WifiMTE.TestState = TEST_WAIT_WMI_STATS; status = wmi_get_stats_cmd(); } break; case TEST_WAIT_WMI_STATS: if (g_WifiMTE.ReceivedStats) { g_WifiMTE.TestState = TEST_END_SUCCESS; } break; case TEST_END_SUCCESS: break; default: g_WifiMTE.TestState = TEST_GEN_FAILURE; A_ASSERT(FALSE); break; } if (g_WifiMTE.TestState == TEST_END_SUCCESS) { /* all done */ break; } } if (g_WifiMTE.APConnected) { /* if we were connected, issue the disconnect command to disconnect from the AP */ wmi_disconnect_cmd(); /* before exiting make sure the target sends out the disconnect */ A_MDELAY(200); } g_WifiMTE.MteStatus = GetMTEStatus(); return status; }