summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h7
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c81
2 files changed, 87 insertions, 1 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 3883033f987c..32a7d190f371 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -107,6 +107,13 @@
#define WLAN_WAIT_TIME_SESSIONOPENCLOSE 15000
#define WLAN_WAIT_TIME_ABORTSCAN 2000
+#ifdef QCA_WIFI_2_0
+
+/** Maximum time(ms) to wait for mc thread suspend **/
+#define WLAN_WAIT_TIME_MCTHREAD_SUSPEND 1200
+
+#endif
+
/** Maximum time(ms) to wait for tdls add sta to complete **/
#define WAIT_TIME_TDLS_ADD_STA 1500
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
};