diff options
| author | Raja Mani <rmani@qti.qualcomm.com> | 2013-11-08 15:03:38 +0530 |
|---|---|---|
| committer | Madan Mohan Koyyalamudi <mkoyyala@qca.qualcomm.com> | 2013-11-14 20:15:07 -0800 |
| commit | a8a6b86bf7cc0244577bc4f18a10fdc8efc49066 (patch) | |
| tree | f68de9b5ca1a90d8e81959ee977f435d33eaefcd /CORE/HDD/src | |
| parent | b53f9f324a3ffb33dcb85978afc7e20212b3e0f3 (diff) | |
cld: Handle cfg80211 suspend and resume
Two callbacks are exposed from HDD to CFG80211 layer to handle suspend
and resume. During cfg80211 suspend, Ongoing SCAN on each interface is
stopped and MC thread is moved to suspend state. During cfg80211 resume,
MC thread is resumed back.
Change-Id: I1e891c8a773ced2655dbae2ee655aee5332fccfe
CRs-Fixed: 540571
Diffstat (limited to 'CORE/HDD/src')
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 42f827695062..7b5392aa4906 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -91,7 +91,9 @@ #include "wlan_hdd_tdls.h" #endif #include "wlan_nv.h" - +#ifdef QCA_WIFI_2_0 +#include "vos_sched.h" +#endif #if defined(QCA_WIFI_2_0) && defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC) #include "testmode.h" #endif @@ -8227,6 +8229,79 @@ static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy, } #endif +#ifdef QCA_WIFI_2_0 +int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + pVosSchedContext vosSchedContext = get_vos_sched_ctxt(); + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + hdd_scaninfo_t *pScanInfo; + VOS_STATUS status; + int rc; + + /* Stop ongoing scan on each interface */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + pScanInfo = &pAdapter->scan_info; + + if (pScanInfo->mScanPending && pAdapter->request) + { + INIT_COMPLETION(pScanInfo->abortscan_event_var); + hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId); + + status = wait_for_completion_interruptible_timeout( + &pScanInfo->abortscan_event_var, + msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN)); + if (!status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred while waiting for abort scan" , + __func__); + return -ETIME; + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + /* Suspend MC thread */ + set_bit(MC_SUSPEND_EVENT_MASK, &vosSchedContext->mcEventFlag); + wake_up_interruptible(&vosSchedContext->mcWaitQueue); + + /* Wait for suspend confirmation from MC thread */ + rc = wait_for_completion_interruptible_timeout(&pHddCtx->mc_sus_event_var, + msecs_to_jiffies(WLAN_WAIT_TIME_MCTHREAD_SUSPEND)); + if (!rc) + { + clear_bit(MC_SUSPEND_EVENT_MASK, &vosSchedContext->mcEventFlag); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop mc thread", __func__); + return -ETIME; + } + + pHddCtx->isMcThreadSuspended = TRUE; + + return 0; +} + +int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + pVosSchedContext vosSchedContext = get_vos_sched_ctxt(); + + /* Resume MC thread */ + complete(&vosSchedContext->ResumeMcEvent); + + pHddCtx->isMcThreadSuspended = FALSE; + + return 0; +} +#endif + /* cfg80211_ops */ static struct cfg80211_ops wlan_hdd_cfg80211_ops = { @@ -8297,5 +8372,9 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl, #endif +#ifdef QCA_WIFI_2_0 + .suspend = wlan_hdd_cfg80211_suspend_wlan, + .resume = wlan_hdd_cfg80211_resume_wlan, +#endif }; |
