summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnjaneedevi Kapparapu <akappa@codeaurora.org>2014-12-19 17:40:40 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2014-12-19 17:41:48 +0530
commit0cedf29cf8284e062ef49867a3ef2269e4698821 (patch)
tree74a6385721256fc85255526098f6b7d20d33018c
parent79931468980c34ea933b1149bd3e7472cec4225d (diff)
parentdb383ea2e6ea280c849fbca3e0b43c2f04d7e63f (diff)
Release 4.0.10.003 QCACLD WLAN Driver
Merge remote-tracking branch 'origin/caf/caf-wlan/master' * origin/caf/caf-wlan/master: Cafstaging Release 4.0.10.003 qcacld: usb: Fix target crash dump in USB bundle mode qcacld: Add bus auto suspend feature flag and ini entry qcacld: [WMA] Add support for autonomous bus suspend qcacld: [CORESTACK] Add support for auto suspend qcacld: [HDD] Add support for PCIe link auto suspend feature qcacld: Fix to stop the SME from bailing out on set BSS key timeout. qcacld: SAP : BSS failed to start on channel 14 qcacld: Fix for SENDACTIONFRAME channel number check qcacld: CL 1174114 - update fw common interface files qcacld: UMAC: Consistently use enumeration from CSR for phy mode qcacld: UMAC: Adding VHT Capability info IE in broadcast probe request Change-Id: I12385b6ff87c4a16825e6f5816016bd3fdf84ecf
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h11
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h4
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h14
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c8
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c19
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c47
-rw-r--r--CORE/HDD/src/wlan_hdd_early_suspend.c66
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c22
-rwxr-xr-xCORE/HDD/src/wlan_hdd_main.c397
-rw-r--r--CORE/HDD/src/wlan_hdd_p2p.c56
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c1
-rw-r--r--CORE/MAC/inc/qwlan_version.h4
-rw-r--r--CORE/MAC/inc/sirApi.h3
-rw-r--r--CORE/MAC/src/include/sirParams.h4
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c79
-rw-r--r--CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c40
-rw-r--r--CORE/MAC/src/pe/lim/limUtils.c64
-rw-r--r--CORE/MAC/src/pe/lim/limUtils.h6
-rw-r--r--CORE/SAP/inc/sapApi.h34
-rw-r--r--CORE/SAP/src/sapApiLinkCntl.c15
-rw-r--r--CORE/SAP/src/sapChSelect.c12
-rw-r--r--CORE/SAP/src/sapFsm.c65
-rw-r--r--CORE/SAP/src/sapModule.c4
-rw-r--r--CORE/SERVICES/COMMON/wmi_version.h2
-rw-r--r--CORE/SERVICES/HIF/PCIe/hif_pci.c5
-rw-r--r--CORE/SERVICES/HIF/USB/usbdrv.c44
-rw-r--r--CORE/SERVICES/WMA/wma.c239
-rw-r--r--CORE/SERVICES/WMA/wma.h9
-rw-r--r--CORE/SME/inc/csrApi.h26
-rw-r--r--CORE/SME/inc/csrInternal.h3
-rw-r--r--CORE/SME/inc/smeInternal.h3
-rw-r--r--CORE/SME/inc/sme_Api.h24
-rw-r--r--CORE/SME/inc/sme_Trace.h3
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c9
-rw-r--r--CORE/SME/src/csr/csrApiScan.c3
-rw-r--r--CORE/SME/src/csr/csrUtil.c11
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c60
-rw-r--r--CORE/SME/src/sme_common/sme_Trace.c3
-rw-r--r--CORE/SYS/legacy/src/utils/src/macTrace.c4
-rw-r--r--CORE/WDA/inc/wlan_qct_wda.h4
-rw-r--r--Kbuild12
-rwxr-xr-xfirmware_bin/WCNSS_qcom_cfg.ini7
42 files changed, 1195 insertions, 251 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 7cf14541f523..698c944a19c1 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -2714,6 +2714,13 @@ enum dot11p_mode {
#define CFG_DOT11P_MODE_MIN ( WLAN_HDD_11P_DISABLED )
#define CFG_DOT11P_MODE_MAX ( WLAN_HDD_11P_CONCURRENT )
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+#define CFG_ENABLE_AUTO_SUSPEND "gEnableBusAutoSuspend"
+#define CFG_ENABLE_AUTO_SUSPEND_MIN ( 0 )
+#define CFG_ENABLE_AUTO_SUSPEND_MAX ( 1 )
+#define CFG_ENABLE_AUTO_SUSPEND_DEFAULT ( 0 )
+#endif
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -3301,8 +3308,10 @@ typedef struct
uint32_t sap_auth_offload_sec_type;
uint8_t sap_auth_offload_key[WLAN_PSK_STRING_LENGTH];
#endif /* SAP_AUTH_OFFLOAD */
-
uint8_t dot11p_mode;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ bool enable_bus_auto_suspend;
+#endif
} hdd_config_t;
#ifdef WLAN_FEATURE_MBSSID
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index eb7adad18a17..d87c4bd512b1 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -1036,6 +1036,10 @@ void wlan_hdd_testmode_rx_event(void *buf, size_t buf_len);
void hdd_suspend_wlan(void (*callback)(void *callbackContext, boolean suspended),
void *callbackContext);
void hdd_resume_wlan(void);
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+void hdd_auto_suspend_wlan(csrReadyToSuspendCallback ready_to_suspend_cb,
+ void *cb_context, void (auto_resumed_cb)(void *cb_parameter));
+#endif
#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC)
int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 9842c956a89e..80e926ecb265 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1504,6 +1504,11 @@ struct hdd_context_s
struct work_struct rocReqWork;
hdd_list_t hdd_roc_req_q;
bool mcc_mode;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ vos_timer_t auto_suspend_timer;
+ atomic_t auto_suspend_state;
+ atomic_t auto_suspend_stop_requested;
+#endif
};
/*---------------------------------------------------------------------------
@@ -1728,4 +1733,13 @@ static inline void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter) {}
static inline void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter) {}
#endif
int wlan_hdd_get_link_speed(hdd_adapter_t *sta_adapter, uint32_t *link_speed);
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+void hdd_start_auto_suspend_attempt(hdd_context_t *hdd_ctx, bool delayed);
+void hdd_stop_auto_suspend_attempt(hdd_context_t *hdd_ctx);
+#else
+static inline void hdd_start_auto_suspend_attempt(hdd_context_t *hdd_ctx,
+ bool delayed) {}
+static inline void hdd_stop_auto_suspend_attempt(hdd_context_t *hdd_ctx) {}
+#endif
+
#endif // end #if !defined( WLAN_HDD_MAIN_H )
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 840a6c34eec0..91efb94496e9 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -1072,6 +1072,8 @@ static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *
pAdapter->sessionId);
}
+ hdd_start_auto_suspend_attempt(pHddCtx, true);
+
//Unblock anyone waiting for disconnect to complete
complete(&pAdapter->disconnect_comp_var);
return( status );
@@ -1978,9 +1980,9 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs
default_sap_channel);
}
sme_SelectCBMode(WLAN_HDD_GET_HAL_CTX(sap_adapter),
- sapConvertSapPhyModeToCsrPhyMode(hdd_ap_ctx->sapConfig.SapHw_mode),
- hdd_ap_ctx->sapConfig.channel,
- pHddCtx->cfg_ini->vhtChannelWidth);
+ hdd_ap_ctx->sapConfig.SapHw_mode,
+ hdd_ap_ctx->sapConfig.channel,
+ pHddCtx->cfg_ini->vhtChannelWidth);
/*
* Create a workqueue and let the workqueue handle the restarting
* sap task. if we directly call sap restart function without
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 7fc6f3d3014f..8b70faf31138 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -3522,6 +3522,15 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_DOT11P_MODE_DEFAULT,
CFG_DOT11P_MODE_MIN,
CFG_DOT11P_MODE_MAX),
+
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ REG_VARIABLE( CFG_ENABLE_AUTO_SUSPEND, WLAN_PARAM_Integer,
+ hdd_config_t, enable_bus_auto_suspend,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ENABLE_AUTO_SUSPEND_DEFAULT,
+ CFG_ENABLE_AUTO_SUSPEND_MIN,
+ CFG_ENABLE_AUTO_SUSPEND_MAX ),
+#endif
};
#ifdef WLAN_FEATURE_MBSSID
@@ -4185,6 +4194,10 @@ void print_hdd_cfg(hdd_context_t *pHddCtx)
"Name = [gMDNSResponseTypeSRVTarget] Value = [%s]",
pHddCtx->cfg_ini->mdns_resp_type_srv_target);
#endif
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ hddLog(LOG2, "Name = [gEnableBusAutoSuspend] Value = [%u]",
+ pHddCtx->cfg_ini->enable_bus_auto_suspend);
+#endif
}
#define CFG_VALUE_MAX_LEN 256
@@ -4632,7 +4645,6 @@ static VOS_STATUS hdd_apply_cfg_ini( hdd_context_t *pHddCtx, tCfgIniEntry* iniTa
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "RegName = %s, VarOffset %u VarSize %u VarDefault %s",
pRegEntry->RegName, pRegEntry->VarOffset, pRegEntry->VarSize, (char*)pRegEntry->VarDefault);
#endif
-
if ( match_status == VOS_STATUS_SUCCESS)
{
len_value_str = strlen(value_str);
@@ -5960,7 +5972,6 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
/* Update PNO offload status */
smeConfig->pnoOffload = pHddCtx->cfg_ini->PnoOffload;
#endif
-
/* Update maximum interfaces information */
smeConfig->max_intf_count = pHddCtx->max_intf_count;
@@ -5977,6 +5988,10 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
pHddCtx->cfg_ini->conc_custom_rule1;
smeConfig->csrConfig.is_sta_connection_in_5gz_enabled =
pHddCtx->cfg_ini->is_sta_connection_in_5gz_enabled;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ smeConfig->enable_bus_auto_suspend =
+ pHddCtx->cfg_ini->enable_bus_auto_suspend;
+#endif
/* Update 802.11p config */
smeConfig->csrConfig.enable_dot11p = (pHddCtx->cfg_ini->dot11p_mode !=
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 73e0cfca4bf2..e600edeaeb8a 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -5786,7 +5786,7 @@ static int wlan_hdd_rate_is_11g(u8 rate)
/* Check for 11g rate and set proper 11g only mode */
static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
- u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
+ u8* pCheckRatesfor11g, eCsrPhyMode* pSapHw_mode)
{
u8 i, num_rates = pIe[0];
@@ -5796,13 +5796,13 @@ static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
{
/* If rate set have 11g rate than change the mode to 11G */
- *pSapHw_mode = eSAP_DOT11_MODE_11g;
+ *pSapHw_mode = eCSR_DOT11_MODE_11g;
if (pIe[i] & BASIC_RATE_MASK)
{
/* If we have 11g rate as basic rate, it means mode
is 11g only mode.
*/
- *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
+ *pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
*pCheckRatesfor11g = FALSE;
}
}
@@ -5823,7 +5823,7 @@ static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
u8 require_ht = FALSE;
u8 *pIe=NULL;
- pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
+ pConfig->SapHw_mode= eCSR_DOT11_MODE_11b;
pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
pBeacon->head_len, WLAN_EID_SUPP_RATES);
@@ -5846,7 +5846,7 @@ static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
if( pConfig->channel > 14 )
{
- pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
+ pConfig->SapHw_mode= eCSR_DOT11_MODE_11a;
}
pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
@@ -5854,9 +5854,9 @@ static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
if(pIe)
{
- pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
+ pConfig->SapHw_mode= eCSR_DOT11_MODE_11n;
if(require_ht)
- pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
+ pConfig->SapHw_mode= eCSR_DOT11_MODE_11n_ONLY;
}
}
@@ -6984,16 +6984,16 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
/* Overwrite the hostapd setting for HW mode only for 11ac.
* This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
* Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
- if( (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) &&
+ if( (pConfig->SapHw_mode == eCSR_DOT11_MODE_11n) &&
sapForce11ACFor11n &&
(( (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO ) ||
( (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac ) ||
( (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY )) )
{
if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
- pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac_ONLY;
+ pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
else
- pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
+ pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
/* If ACS disable and selected channel <= 14
OR
@@ -7015,7 +7015,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
== FALSE)) ||
(WLAN_HDD_GET_CTX(pHostapdAdapter)->isVHT80Allowed == FALSE))
{
- pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
+ pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
}
}
#endif
@@ -7023,7 +7023,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
if ( AUTO_CHANNEL_SELECT != pConfig->channel )
{
sme_SelectCBMode(hHal,
- sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
+ pConfig->SapHw_mode,
pConfig->channel,
WLAN_HDD_GET_CTX(pHostapdAdapter)->cfg_ini->vhtChannelWidth);
}
@@ -9841,7 +9841,6 @@ static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
allow_suspend:
/* release the wake lock at the end of the scan*/
hdd_allow_suspend();
-
/* Acquire wakelock to handle the case where APP's tries to suspend
* immediately after the driver gets connect request(i.e after scan)
* from supplicant, this result in app's is suspending and not able
@@ -9852,6 +9851,10 @@ allow_suspend:
wlan_hdd_tdls_scan_done_callback(pAdapter);
#endif
+#ifdef CONFIG_CNSS
+ cnss_allow_auto_suspend(__func__);
+#endif
+
EXIT();
return 0;
}
@@ -10315,7 +10318,9 @@ int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
* be stuck in full power because of resume BMPS
*/
hdd_prevent_suspend();
-
+#ifdef CONFIG_CNSS
+ cnss_prevent_auto_suspend(__func__);
+#endif
hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
"requestType %d, scanType %d, minChnTime %d, maxChnTime %d,p2pSearch %d, skipDfsChnlIn P2pSearch %d",
scanRequest.requestType, scanRequest.scanType,
@@ -10343,6 +10348,9 @@ int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
}
hdd_allow_suspend();
+#ifdef CONFIG_CNSS
+ cnss_allow_auto_suspend(__func__);
+#endif
goto free_mem;
}
@@ -11380,6 +11388,7 @@ static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
ENTER();
+
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
TRACE_CODE_HDD_CFG80211_CONNECT,
pAdapter->sessionId, pAdapter->device_mode));
@@ -11406,6 +11415,9 @@ static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
"%s: HDD context is not valid", __func__);
return status;
}
+
+ hdd_stop_auto_suspend_attempt(pHddCtx);
+
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/* Supplicant indicate its decision to offload key management
* by setting the third bit in flags in case of Secure connection
@@ -15236,8 +15248,11 @@ int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
}
#endif
+
hdd_resume_wlan();
+ hdd_start_auto_suspend_attempt(pHddCtx, 0);
+
spin_lock(&pHddCtx->schedScan_lock);
pHddCtx->isWiphySuspended = FALSE;
if (TRUE != pHddCtx->isSchedScanUpdatePending) {
@@ -15416,6 +15431,8 @@ int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
/* Wait for the target to be ready for suspend */
INIT_COMPLETION(pHddCtx->ready_to_suspend);
+ hdd_stop_auto_suspend_attempt(pHddCtx);
+
hdd_suspend_wlan(&wlan_hdd_cfg80211_ready_to_suspend, pHddCtx);
rc = wait_for_completion_timeout(&pHddCtx->ready_to_suspend,
@@ -15486,6 +15503,8 @@ resume_all:
resume_tx:
hdd_resume_wlan();
+ hdd_start_auto_suspend_attempt(pHddCtx, 0);
+
return -ETIME;
}
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index 7b94d7c83d30..be28f31e2324 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -1755,6 +1755,8 @@ VOS_STATUS hdd_wlan_shutdown(void)
vos_clear_concurrent_session_count();
+ hdd_stop_auto_suspend_attempt(pHddCtx);
+
hdd_reset_all_adapters(pHddCtx);
vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
@@ -2141,6 +2143,7 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc)
pHddCtx->target_hw_version,
pHddCtx->target_hw_name);
#endif
+ hdd_start_auto_suspend_attempt(pHddCtx, false);
goto success;
err_unregister_pmops:
@@ -2193,3 +2196,66 @@ success:
send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
return VOS_STATUS_SUCCESS;
}
+
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+/**
+ * hdd_auto_suspend_wlan() - Pass auto suspend indication to SME.
+ *
+ * @ready_to_suspend_cb: Callback invoked when bus is suspended.
+ * @cb_context: optional parameter for callback indication.
+ * @auto_resumed_cb: Callback invoked when bus resumes.
+ *
+ * HDD will send this indication to SME when it thinks that it
+ * has detected the ideal condition for bus auto suspend.
+ *
+ * Return: none
+ */
+void hdd_auto_suspend_wlan(csrReadyToSuspendCallback ready_to_suspend_cb,
+ void *cb_context, void (auto_resumed_cb)(void *cb_parameter))
+{
+ hdd_context_t *hdd_ctx;
+ hdd_adapter_t *adapter;
+ v_CONTEXT_t vos_ctx;
+ eHalStatus status;
+ int ret;
+ tpSirWlanSuspendParam suspend_param;
+
+ hddLog(LOG1, FL("Auto suspend WLAN"));
+
+ vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+ if (!vos_ctx) {
+ return;
+ }
+
+ hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret) {
+ return;
+ }
+
+ adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
+ if (!adapter) {
+ hddLog(LOGE, "%s: invalid station adapter", __func__);
+ return;
+ }
+
+ suspend_param = vos_mem_malloc(sizeof(*suspend_param));
+ if (NULL == suspend_param) {
+ hddLog(VOS_TRACE_LEVEL_FATAL, FL("vos_mem_alloc failed"));
+ return;
+ }
+
+ suspend_param->connectedState = FALSE;
+ suspend_param->sessionId = adapter->sessionId;
+ suspend_param->resumed_callback = auto_resumed_cb;
+
+ status = sme_configure_bus_auto_suspend_ind(hdd_ctx->hHal,
+ suspend_param, ready_to_suspend_cb, cb_context);
+ if (eHAL_STATUS_SUCCESS != status) {
+ hddLog(LOGE, FL("sme auto suspend failure %d"), status);
+ }
+ vos_mem_free(suspend_param);
+
+ return;
+}
+#endif
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 6a3d9e6292ce..9dc7598ebc59 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -2556,12 +2556,12 @@ static iw_softap_setparam(struct net_device *dev,
if (set_value != 0xff) {
rix = RC_2_RATE_IDX(set_value);
if (set_value & 0x80) {
- if (pConfig->SapHw_mode == eSAP_DOT11_MODE_11b ||
- pConfig->SapHw_mode == eSAP_DOT11_MODE_11b_ONLY ||
- pConfig->SapHw_mode == eSAP_DOT11_MODE_11g ||
- pConfig->SapHw_mode == eSAP_DOT11_MODE_11g_ONLY ||
- pConfig->SapHw_mode == eSAP_DOT11_MODE_abg ||
- pConfig->SapHw_mode == eSAP_DOT11_MODE_11a) {
+ if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11b ||
+ pConfig->SapHw_mode == eCSR_DOT11_MODE_11b_ONLY ||
+ pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
+ pConfig->SapHw_mode == eCSR_DOT11_MODE_11g_ONLY ||
+ pConfig->SapHw_mode == eCSR_DOT11_MODE_abg ||
+ pConfig->SapHw_mode == eCSR_DOT11_MODE_11a) {
hddLog(LOGE, "Not valid mode for HT");
ret = -EIO;
break;
@@ -2569,7 +2569,7 @@ static iw_softap_setparam(struct net_device *dev,
preamble = WMI_RATE_PREAMBLE_HT;
nss = HT_RC_2_STREAMS(set_value) - 1;
} else if (set_value & 0x10) {
- if (pConfig->SapHw_mode == eSAP_DOT11_MODE_11a) {
+ if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a) {
hddLog(VOS_TRACE_LEVEL_ERROR, "Not valid for cck");
ret = -EIO;
break;
@@ -2579,8 +2579,8 @@ static iw_softap_setparam(struct net_device *dev,
if (rix != 0x3)
rix |= 0x4;
} else {
- if (pConfig->SapHw_mode == eSAP_DOT11_MODE_11b ||
- pConfig->SapHw_mode == eSAP_DOT11_MODE_11b_ONLY) {
+ if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11b ||
+ pConfig->SapHw_mode == eCSR_DOT11_MODE_11b_ONLY) {
hddLog(VOS_TRACE_LEVEL_ERROR, "Not valid for OFDM");
ret = -EIO;
break;
@@ -2604,8 +2604,8 @@ static iw_softap_setparam(struct net_device *dev,
tsap_Config_t *pConfig =
&pHostapdAdapter->sessionCtx.ap.sapConfig;
- if (pConfig->SapHw_mode != eSAP_DOT11_MODE_11ac &&
- pConfig->SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY) {
+ if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac &&
+ pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) {
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: SET_VHT_RATE error: SapHw_mode= 0x%x, ch = %d",
__func__, pConfig->SapHw_mode, pConfig->channel);
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 5bd9fc7cee23..8573ce6b46a2 100755
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -244,6 +244,8 @@ struct android_wifi_af_params {
#define WLAN_WAIT_TIME_READY_TO_EXTWOW 2000
#endif
+#define AUTO_SUSPEND_DELAY_MS 1500
+
static vos_wake_lock_t wlan_wake_lock;
/* set when SSR is needed after unload */
static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
@@ -282,6 +284,384 @@ extern int hdd_ftm_stop(hdd_context_t *pHddCtx);
v_VOID_t wlan_hdd_auto_shutdown_cb(v_VOID_t);
#endif
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+enum auto_suspend_state {
+ HDD_BUS_NOT_AUTO_SUSPENDED,
+ HDD_BUS_AUTO_SUSPEND_IN_PROGRESS,
+ HDD_BUS_AUTO_SUSPENDED,
+};
+
+/**
+ * hdd_auto_resumed_cb() - Callback to restart auto suspend attempt.
+ *
+ * @param: Optional parameter to the callback.
+ *
+ * Callback registered to restart auto suspend attempt, if bus is resumed
+ * because of a control message or management frame transaction.
+ *
+ * Return: none
+ */
+static void hdd_auto_resumed_cb(void *param)
+{
+ hdd_context_t *hdd_ctx;
+ v_CONTEXT_t vos_ctx;
+ int ret;
+
+ vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+ if (NULL == vos_ctx) {
+ hddLog(LOGE, FL("invalid VOS context"));
+ return;
+ }
+ hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret) {
+ return;
+ }
+
+ atomic_set(&hdd_ctx->auto_suspend_state, HDD_BUS_NOT_AUTO_SUSPENDED);
+
+ /* if there was a stop request, don't restart auto suspend
+ * attempt on resume.
+ */
+ if (atomic_read(&hdd_ctx->auto_suspend_stop_requested)) {
+ hddLog(LOGE, FL("Auto suspend not restarting on resume"));
+ return;
+ }
+
+ hddLog(LOG1, FL("auto suspend retry"));
+ hdd_start_auto_suspend_attempt(hdd_ctx, false);
+}
+
+enum auto_suspend_perm {
+ HDD_AUTO_SUSPEND_ALLOWED,
+ HDD_AUTO_SUSPEND_RETRY,
+ HDD_AUTO_SUSPEND_DENIED,
+};
+
+/**
+ * hdd_is_auto_suspend_allowed() - Check if HDD allows auto suspend.
+ *
+ * @hdd_ctx: HDD context
+ *
+ * Scan thru the adapters and see if any adapter state is preventing
+ * auto suspend.
+ *
+ * Return: Allowed or denied or retry
+ */
+static int hdd_is_auto_suspend_allowed(hdd_context_t *hdd_ctx)
+{
+ hdd_adapter_list_node_t *node = NULL, *next = NULL;
+ enum auto_suspend_perm perm = HDD_AUTO_SUSPEND_ALLOWED;
+ VOS_STATUS status;
+ hdd_adapter_t *adapter;
+
+ status = hdd_get_front_adapter(hdd_ctx, &node);
+ if (VOS_STATUS_SUCCESS != status) {
+ hddLog(LOGE, FL("Failed to scan thru adapters for auto suspend"));
+ perm = HDD_AUTO_SUSPEND_DENIED;
+ goto out;
+ }
+
+ while (node && VOS_STATUS_SUCCESS == status) {
+ adapter = node->pAdapter;
+ if (!adapter)
+ break;
+
+ switch (adapter->device_mode) {
+
+ case WLAN_HDD_INFRA_STATION:
+ if ((WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
+ == eConnectionState_Associated) ||
+ (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
+ == eConnectionState_Connecting) ||
+ (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
+ ==eConnectionState_Disconnecting)) {
+ perm = HDD_AUTO_SUSPEND_DENIED;
+ }
+ break;
+
+ case WLAN_HDD_P2P_DEVICE:
+ break;
+
+ case WLAN_HDD_SOFTAP:
+ case WLAN_HDD_P2P_GO:
+ case WLAN_HDD_P2P_CLIENT:
+ case WLAN_HDD_IBSS:
+ default:
+ hddLog(LOG1, FL("Auto suspend denied %d"), adapter->device_mode);
+ perm = HDD_AUTO_SUSPEND_DENIED;
+ break;
+ }
+
+ if (perm == HDD_AUTO_SUSPEND_DENIED)
+ break;
+
+ status = hdd_get_next_adapter(hdd_ctx, node, &next);
+ node = next;
+ }
+
+out:
+ return perm;
+}
+
+/**
+ * hdd_start_auto_suspend_attempt() - start auto suspend attempt at HDD.
+ *
+ * @hdd_ctx: HDD context
+ * @delayed: if set, then conditions are checked only after first timer expiry
+ *
+ * Start bus auto suspend timer if HDD is allowing auto suspend.
+ *
+ * Return: none
+ */
+void hdd_start_auto_suspend_attempt(hdd_context_t *hdd_ctx, bool delayed)
+{
+ enum auto_suspend_perm perm;
+ int ret;
+
+ hdd_config_t *cfg;
+
+ cfg = hdd_ctx->cfg_ini;
+
+ if (!cfg) {
+ hddLog(LOGE, FL("cfg not available"));
+ return;
+ }
+
+ if (!cfg->enable_bus_auto_suspend) {
+ hddLog(LOGE, FL("Auto suspend disabled"));
+ return;
+ }
+
+ atomic_set(&hdd_ctx->auto_suspend_stop_requested, 0);
+
+ ret = atomic_read(&hdd_ctx->auto_suspend_state);
+ if (ret == HDD_BUS_AUTO_SUSPENDED ||
+ ret == HDD_BUS_AUTO_SUSPEND_IN_PROGRESS) {
+ hddLog(LOGE, FL("Auto suspend in progress or suspended %d"), ret);
+ return;
+ }
+
+ if (VOS_TIMER_STATE_RUNNING ==
+ vos_timer_getCurrentState(&hdd_ctx->auto_suspend_timer)) {
+ hddLog(LOG1, FL("ignore, auto suspend timer running"));
+ return;
+ }
+
+ if (!delayed) {
+ perm = hdd_is_auto_suspend_allowed(hdd_ctx);
+ if (perm == HDD_AUTO_SUSPEND_DENIED) {
+ hddLog(LOG1, FL("HDD not ready for auto suspend"));
+ return;
+ }
+ }
+
+ hddLog(LOG1, FL("starting auto suspend timer %d"), delayed);
+
+ vos_timer_start(&hdd_ctx->auto_suspend_timer, AUTO_SUSPEND_DELAY_MS);
+
+ hddLog(LOG1, FL("HDD auto suspend timer started"));
+
+ return;
+}
+
+/**
+ * hdd_stop_auto_suspend_attempt() - stop auto suspend attempt at HDD.
+ *
+ * @hdd_ctx: HDD context
+ *
+ * Stop auto suspend timer if it is already running.
+ *
+ * Return: none
+ */
+void hdd_stop_auto_suspend_attempt(hdd_context_t *hdd_ctx)
+{
+ int ret;
+ hdd_config_t *cfg;
+
+ cfg = hdd_ctx->cfg_ini;
+ if (!cfg) {
+ hddLog(LOGE, FL("cfg not available"));
+ return;
+ }
+
+ if (!cfg->enable_bus_auto_suspend) {
+ hddLog(LOGE, FL("Auto suspend disabled"));
+ return;
+ }
+
+ atomic_set(&hdd_ctx->auto_suspend_stop_requested, 1);
+
+ if (VOS_TIMER_STATE_RUNNING !=
+ vos_timer_getCurrentState(&hdd_ctx->auto_suspend_timer)) {
+ /* if timer is not running, then we may have already suspended */
+ ret = atomic_read(&hdd_ctx->auto_suspend_state);
+ if (ret != HDD_BUS_NOT_AUTO_SUSPENDED) {
+ hddLog(LOG1, FL("HDD initiating resume"));
+ cnss_auto_resume();
+ }
+ return;
+ }
+
+ hddLog(LOG1, FL("stop auto suspend timer"));
+ vos_timer_stop(&hdd_ctx->auto_suspend_timer);
+ atomic_set(&hdd_ctx->auto_suspend_state, HDD_BUS_NOT_AUTO_SUSPENDED);
+}
+
+/**
+ * ready_to_auto_suspend() - Callback to receive auto suspend indication.
+ *
+ * @cb_context: Optional callback context
+ * @suspended: Will be set to true, if bus suspend is successful.
+ *
+ * Callback registered to receive auto suspend indication processed at the
+ * bus layer.
+ *
+ * Return: none
+ */
+static void ready_to_auto_suspend(void *cb_context, boolean suspended)
+{
+ hdd_context_t *hdd_ctx;
+ v_CONTEXT_t vos_ctx;
+ int ret;
+
+ vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+ if (NULL == vos_ctx) {
+ hddLog(LOGE, FL("invalid VOS context"));
+ return;
+ }
+ hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD,
+ vos_ctx);
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret) {
+ hddLog(LOGE, FL("invalid HDD context"));
+ return;
+ }
+
+ hdd_allow_suspend();
+
+ if (!suspended)
+ hddLog(LOG1, FL("Failed response for auto suspend")); {
+ return;
+ }
+
+ /* if we already started this timer, then resume has happened */
+ if (VOS_TIMER_STATE_RUNNING ==
+ vos_timer_getCurrentState(&hdd_ctx->auto_suspend_timer)) {
+ hddLog(LOG1, FL("HDD auto suspend ready when timer is running"));
+ return;
+ }
+
+ atomic_set(&hdd_ctx->auto_suspend_state, HDD_BUS_AUTO_SUSPENDED);
+ hddLog(LOG1, FL("HDD auto suspended"));
+}
+
+/**
+ * hdd_auto_suspend_timer_cb() - Timer callback function for auto suspend.
+ *
+ * @usr_data: Callback data (used to stored HDD context)
+ *
+ * Callback function registered for auto suspend VOS timer.
+ *
+ * Return: none
+ */
+static void hdd_auto_suspend_timer_cb(v_PVOID_t usr_data)
+{
+ int ret;
+ enum auto_suspend_perm perm;
+ hdd_context_t *hdd_ctx = usr_data;
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret) {
+ hddLog(LOGE, FL("HDD context is not valid"));
+ goto out;
+ }
+
+ if (true == hdd_ctx->hdd_wlan_suspended) {
+ hddLog(LOGE, FL("Ignore auto suspend, suspend in progress"));
+ goto out;
+ }
+ ret = atomic_read(&hdd_ctx->auto_suspend_state);
+ if (ret == HDD_BUS_AUTO_SUSPEND_IN_PROGRESS ||
+ ret == HDD_BUS_AUTO_SUSPENDED) {
+ hddLog(LOGE, FL("Callback in invalid auto suspend state %d"), ret);
+ goto out;
+ }
+
+ perm = hdd_is_auto_suspend_allowed(hdd_ctx);
+ if (perm == HDD_AUTO_SUSPEND_DENIED) {
+ hddLog(LOG1, FL("HDD auto-suspend denied, not re-starting timer"));
+ goto out;
+ }
+
+ ret = cnss_is_auto_suspend_allowed(__func__);
+ if (ret || perm == HDD_AUTO_SUSPEND_RETRY) {
+ hddLog(LOG1, FL("Auto suspend retry %d"), ret);
+ vos_timer_start(&hdd_ctx->auto_suspend_timer,
+ AUTO_SUSPEND_DELAY_MS);
+ goto out;
+ }
+
+ atomic_set(&hdd_ctx->auto_suspend_state, HDD_BUS_AUTO_SUSPEND_IN_PROGRESS);
+
+ /* Prevent system suspend until auto suspend is completed,
+ * that is to avoid race condition with system suspend
+ */
+ hdd_prevent_suspend();
+
+ hddLog(LOG1, FL("HDD starting auto-suspend."));
+
+ hdd_auto_suspend_wlan(ready_to_auto_suspend, hdd_ctx, hdd_auto_resumed_cb);
+
+out:
+ return;
+}
+
+/**
+ * hdd_init_auto_suspend_timer() - Initialize auto suspend timer.
+ *
+ * @hdd_ctx: HDD context
+ *
+ * Initialize bus auto suspend timer.
+ *
+ * Return: none
+ */
+static void hdd_init_auto_suspend_timer(hdd_context_t *hdd_ctx)
+{
+ vos_timer_init(&hdd_ctx->auto_suspend_timer,
+ VOS_TIMER_TYPE_SW, hdd_auto_suspend_timer_cb, hdd_ctx);
+ hddLog(LOG1, FL("HDD auto suspend timer initialized"));
+
+ return;
+}
+
+/**
+ * hdd_init_auto_suspend_timer() - De-initialize auto suspend timer.
+ *
+ * @hdd_ctx: HDD context
+ *
+ * Stop and destroy bus auto suspend timer.
+ *
+ * Return: none
+ */
+static void hdd_deinit_auto_suspend_timer(hdd_context_t *hdd_ctx)
+{
+ if (VOS_TIMER_STATE_RUNNING ==
+ vos_timer_getCurrentState(&hdd_ctx->auto_suspend_timer)) {
+ vos_timer_stop(&hdd_ctx->auto_suspend_timer);
+ }
+
+ if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
+ &hdd_ctx->auto_suspend_timer))) {
+ hddLog(LOGE, FL("Failed to deallocate auto suspend timer"));
+ }
+}
+
+#else
+static inline void hdd_init_auto_suspend_timer(hdd_context_t *hdd_ctx) {}
+static inline void hdd_deinit_auto_suspend_timer(hdd_context_t *hdd_ctx) {}
+#endif
+
/* Store WLAN driver version info in a global variable such that crash debugger
can extract it from driver debug symbol and crashdump for post processing */
tANI_U8 g_wlan_driver_version[ ] = QWLAN_VERSIONSTR;
@@ -2606,12 +2986,12 @@ hdd_parse_send_action_frame_v1_data(const tANI_U8 *pValue,
return -EINVAL;
}
- /*getting the next argument ie the channel number */
+ /* getting the next argument ie the channel number */
v = sscanf(inPtr, "%31s ", tempBuf);
if (1 != v) return -EINVAL;
v = kstrtos32(tempBuf, 10, &tempInt);
- if (v < 0 || tempInt < 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)
+ if (v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)
return -EINVAL;
*pChannel = tempInt;
@@ -10887,6 +11267,8 @@ void hdd_wlan_exit(hdd_context_t *pHddCtx)
}
#endif
+ hdd_deinit_auto_suspend_timer(pHddCtx);
+
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
if (VOS_TIMER_STATE_RUNNING ==
vos_timer_getCurrentState(&pHddCtx->skip_acs_scan_timer)) {
@@ -11187,6 +11569,7 @@ int hdd_wlan_set_ht2040_mode(hdd_adapter_t *pAdapter, v_U16_t staId,
}
#endif
+
/**--------------------------------------------------------------------------
\brief notify FW with modem power status
@@ -12443,6 +12826,9 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
INIT_WORK(&pHddCtx->rocReqWork, hdd_roc_req_work);
#endif
+ hdd_init_auto_suspend_timer(pHddCtx);
+ hdd_start_auto_suspend_attempt(pHddCtx, false);
+
complete(&wlan_start_comp);
goto success;
@@ -14210,9 +14596,9 @@ void wlan_hdd_check_sta_ap_concurrent_ch_intf(void *data)
pHddApCtx->sapConfig.channel = intf_ch;
sme_SelectCBMode(hHal,
- sapConvertSapPhyModeToCsrPhyMode(pHddApCtx->sapConfig.SapHw_mode),
- pHddApCtx->sapConfig.channel,
- pHddCtx->cfg_ini->vhtChannelWidth);
+ pHddApCtx->sapConfig.SapHw_mode,
+ pHddApCtx->sapConfig.channel,
+ pHddCtx->cfg_ini->vhtChannelWidth);
wlan_hdd_restart_sap(ap_adapter);
}
#endif
@@ -14397,7 +14783,6 @@ void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
#endif
-
//Register the module init/exit functions
module_init(hdd_module_init);
module_exit(hdd_module_exit);
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index 94f760df3f2e..8ed75afc3d75 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -57,6 +57,11 @@
//Ms to Micro Sec
#define MS_TO_MUS(x) ((x)*1000)
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+static DEFINE_MUTEX(auto_suspend_lock);
+static bool auto_suspend_prevented;
+#endif
+
static tANI_U8* hdd_getActionString(tANI_U16 MsgType)
{
switch (MsgType)
@@ -121,6 +126,48 @@ const char *tdls_action_frame_type[] = {"TDLS Setup Request",
extern struct net_device_ops net_ops_struct;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+/**
+ * p2p_prevent_bus_auto_suspend() - Prevent bus auto suspend.
+ *
+ * API used by p2p logic to prevent bus auto suspend in the middle
+ * of p2p scanning and/or listening. This API will make sure that
+ * it does not increment the CNSS lock when it already has a lock on it.
+ *
+ * Return: none
+ */
+static void p2p_prevent_bus_auto_suspend(void)
+{
+ mutex_lock(&auto_suspend_lock);
+ if (!auto_suspend_prevented) {
+ cnss_prevent_auto_suspend(__func__);
+ auto_suspend_prevented = true;
+ }
+ mutex_unlock(&auto_suspend_lock);
+}
+
+/**
+ * p2p_allow_bus_auto_suspend() - Allow bus auto suspend.
+ *
+ * Release bus suspend lock if p2p logic is holding it.
+ *
+ * Return: none
+ */
+static void p2p_allow_bus_auto_suspend(void)
+{
+ mutex_lock(&auto_suspend_lock);
+ if (auto_suspend_prevented) {
+ cnss_allow_auto_suspend(__func__);
+ auto_suspend_prevented = false;
+ }
+ mutex_unlock(&auto_suspend_lock);
+}
+
+#else
+static inline void p2p_prevent_bus_auto_suspend(void) {}
+static inline void p2p_allow_bus_auto_suspend(void) {}
+#endif
+
static bool wlan_hdd_is_type_p2p_action( const u8 *buf )
{
const u8 *ouiPtr;
@@ -256,6 +303,7 @@ wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void* pCtx,
pAdapter->is_roc_inprogress = FALSE;
mutex_unlock(&cfgState->remain_on_chan_ctx_lock);
hdd_allow_suspend();
+ p2p_allow_bus_auto_suspend();
return eHAL_STATUS_SUCCESS;
}
@@ -338,6 +386,7 @@ void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter)
__func__);
}
hdd_allow_suspend();
+ p2p_allow_bus_auto_suspend();
} else
mutex_unlock(&cfgState->remain_on_chan_ctx_lock);
}
@@ -482,7 +531,7 @@ void wlan_hdd_remain_on_chan_timeout(void *data)
}
hdd_allow_suspend();
-
+ p2p_allow_bus_auto_suspend();
}
static int wlan_hdd_execute_remain_on_channel(hdd_adapter_t *pAdapter,
@@ -534,6 +583,7 @@ static int wlan_hdd_execute_remain_on_channel(hdd_adapter_t *pAdapter,
duration = P2P_ROC_DURATION_MULTIPLIER_GO_ABSENT * duration;
+ p2p_prevent_bus_auto_suspend();
hdd_prevent_suspend();
INIT_COMPLETION(pAdapter->rem_on_chan_ready_event);
@@ -583,6 +633,7 @@ static int wlan_hdd_execute_remain_on_channel(hdd_adapter_t *pAdapter,
mutex_unlock(&cfgState->remain_on_chan_ctx_lock);
vos_mem_free (pRemainChanCtx);
hdd_allow_suspend();
+ p2p_allow_bus_auto_suspend();
return -EINVAL;
}
@@ -605,6 +656,7 @@ static int wlan_hdd_execute_remain_on_channel(hdd_adapter_t *pAdapter,
(WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
#endif
hdd_allow_suspend();
+ p2p_allow_bus_auto_suspend();
return -EINVAL;
}
@@ -1096,6 +1148,8 @@ int __wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
"%s:wait on cancel_rem_on_chan_var timed out ", __func__);
}
hdd_allow_suspend();
+ p2p_allow_bus_auto_suspend();
+
return 0;
}
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 92bd73ec2985..feda7b6cc6a4 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -7644,7 +7644,6 @@ static int iw_get_char_setnone(struct net_device *dev, struct iw_request_info *i
snprintf(extra, WE_MAX_STR_LEN, "11ABG");
break;
case eCSR_DOT11_MODE_11a:
- case eCSR_DOT11_MODE_11a_ONLY:
snprintf(extra, WE_MAX_STR_LEN, "11A");
break;
case eCSR_DOT11_MODE_11b:
diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h
index d6a0493b5e12..8b34304d4e6b 100644
--- a/CORE/MAC/inc/qwlan_version.h
+++ b/CORE/MAC/inc/qwlan_version.h
@@ -42,9 +42,9 @@ BRIEF DESCRIPTION:
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 10
#define QWLAN_VERSION_EXTRA ""
-#define QWLAN_VERSION_BUILD 002
+#define QWLAN_VERSION_BUILD 003
-#define QWLAN_VERSIONSTR "4.0.10.002"
+#define QWLAN_VERSIONSTR "4.0.10.003"
#define AR6320_REV1_VERSION 0x5000000
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 2504e1827f01..5f941c997819 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -3505,6 +3505,9 @@ typedef struct sSirWlanSuspendParam
tANI_U8 configuredMcstBcstFilterSetting;
tANI_U8 sessionId;
tANI_U8 connectedState;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ void (*resumed_callback)(void *);
+#endif
}tSirWlanSuspendParam,*tpSirWlanSuspendParam;
typedef struct sSirWlanResumeParam
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 37bd57885816..5be46a805c17 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -693,6 +693,10 @@ typedef struct sSirMbMsgP2p
#endif /* WLAN_FEATURE_APFIND */
#define SIR_HAL_OCB_SET_SCHED_REQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 307)
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+#define SIR_HAL_WLAN_AUTO_SUSPEND_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 308)
+#define SIR_HAL_WLAN_AUTO_RESUME_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 309)
+#endif
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index 23c509b14fc5..33a209d2f91a 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -3396,71 +3396,64 @@ void limProcessMlmSetStaKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
}
void limProcessMlmSetBssKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
{
- tANI_U8 respReqd = 1;
tLimMlmSetKeysCnf mlmSetKeysCnf;
tANI_U16 resultCode;
tANI_U8 sessionId = 0;
tpPESession psessionEntry;
+ tpLimMlmSetKeysReq lpLimMlmSetKeysReq;
+
SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
vos_mem_set((void *)&mlmSetKeysCnf, sizeof( tLimMlmSetKeysCnf ), 0);
- //BTAMP
- if( NULL == limMsgQ->bodyptr )
- {
- PELOGE(limLog(pMac, LOGE,FL("limMsgQ bodyptr is null"));)
+ if (NULL == limMsgQ->bodyptr) {
+ PELOGE(limLog(pMac, LOGE, FL("limMsgQ bodyptr is null"));)
return;
}
sessionId = ((tpSetBssKeyParams) limMsgQ->bodyptr)->sessionId;
- if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL)
- {
- PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));)
- vos_mem_free( limMsgQ->bodyptr );
+ if ((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) {
+ PELOGE(limLog(pMac, LOGE,
+ FL("session does not exist for given sessionId [%d]"),
+ sessionId);)
+ vos_mem_free(limMsgQ->bodyptr);
limMsgQ->bodyptr = NULL;
return;
}
- if( eLIM_MLM_WT_SET_BSS_KEY_STATE == psessionEntry->limMlmState )
- resultCode = (tANI_U16) (((tpSetBssKeyParams) limMsgQ->bodyptr)->status);
+ if (eLIM_MLM_WT_SET_BSS_KEY_STATE == psessionEntry->limMlmState)
+ resultCode = (tANI_U16) (((tpSetBssKeyParams)limMsgQ->bodyptr)->status);
else
- resultCode = (tANI_U16) (((tpSetStaKeyParams) limMsgQ->bodyptr)->status); //BCAST key also uses tpSetStaKeyParams. Done this way for readabilty.
+ /*BCAST key also uses tpSetStaKeyParams. Done this way for readabilty */
+ resultCode = (tANI_U16) (((tpSetStaKeyParams)limMsgQ->bodyptr)->status);
- //
- // TODO & FIXME_GEN4
- // Need to inspect tSirMsgQ.reserved for a valid Dialog token!
- //
- // Validate MLME state
- if( eLIM_MLM_WT_SET_BSS_KEY_STATE != psessionEntry->limMlmState &&
- eLIM_MLM_WT_SET_STA_BCASTKEY_STATE != psessionEntry->limMlmState )
- {
- // Mesg received from HAL in Invalid state!
- limLog( pMac, LOGE, FL( "Received unexpected [Mesg Id - %d] in state %X" ), limMsgQ->type, psessionEntry->limMlmState );
- // There's not much that MLME can do at this stage...
- respReqd = 0;
+ if (eLIM_MLM_WT_SET_BSS_KEY_STATE != psessionEntry->limMlmState &&
+ eLIM_MLM_WT_SET_STA_BCASTKEY_STATE != psessionEntry->limMlmState) {
+ /* Mesg received from lower layer is in Invalid state */
+ limLog(pMac, LOGE,
+ FL("Received unexpected [Mesg Id - %d] in state %X"),
+ limMsgQ->type, psessionEntry->limMlmState );
+ mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_STATE;
}
else
mlmSetKeysCnf.resultCode = resultCode;
vos_mem_free(limMsgQ->bodyptr);
limMsgQ->bodyptr = NULL;
- // Restore MLME state
+ /* Restore MLME state */
psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
- MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
- if( respReqd )
- {
- tpLimMlmSetKeysReq lpLimMlmSetKeysReq = (tpLimMlmSetKeysReq) pMac->lim.gpLimMlmSetKeysReq;
- mlmSetKeysCnf.sessionId = sessionId;
-
- // Prepare and Send LIM_MLM_SETKEYS_CNF
- if( NULL != lpLimMlmSetKeysReq )
- {
- vos_mem_copy((tANI_U8 *) &mlmSetKeysCnf.peerMacAddr,
- (tANI_U8 *) lpLimMlmSetKeysReq->peerMacAddr,
- sizeof(tSirMacAddr));
- // Free the buffer cached for the global pMac->lim.gpLimMlmSetKeysReq
- vos_mem_free(pMac->lim.gpLimMlmSetKeysReq);
- pMac->lim.gpLimMlmSetKeysReq = NULL;
- }
- limPostSmeMessage(pMac, LIM_MLM_SETKEYS_CNF, (tANI_U32 *) &mlmSetKeysCnf);
- }
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE,
+ psessionEntry->peSessionId, psessionEntry->limMlmState));
+ lpLimMlmSetKeysReq = (tpLimMlmSetKeysReq) pMac->lim.gpLimMlmSetKeysReq;
+ mlmSetKeysCnf.sessionId = sessionId;
+
+ /* Prepare and Send LIM_MLM_SETKEYS_CNF */
+ if (NULL != lpLimMlmSetKeysReq) {
+ vos_mem_copy((tANI_U8 *) &mlmSetKeysCnf.peerMacAddr,
+ (tANI_U8 *) lpLimMlmSetKeysReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ /* Free the buffer cached for the global pMac->lim.gpLimMlmSetKeysReq */
+ vos_mem_free(pMac->lim.gpLimMlmSetKeysReq);
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+ }
+ limPostSmeMessage(pMac, LIM_MLM_SETKEYS_CNF, (tANI_U32 *) &mlmSetKeysCnf);
}
/**
* limProcessMlmRemoveKeyRsp()
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index 93b8e3fb2efe..a22bdbb31e1c 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -1122,7 +1122,12 @@ static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac,
tANI_U8 *p;
tANI_U8 *ht_cap_ie;
tSirMsgQ msg;
- tANI_U16 i, len, ht_cap_len = 0;
+ tANI_U16 i, len;
+ tANI_U16 ht_cap_len = 0, addn_ie_len = 0;
+#ifdef WLAN_FEATURE_11AC
+ tANI_U8 *vht_cap_ie;
+ tANI_U16 vht_cap_len = 0;
+#endif /* WLAN_FEATURE_11AC */
tSirRetStatus rc = eSIR_SUCCESS;
pMac->lim.fOffloadScanPending = 0;
@@ -1138,7 +1143,21 @@ static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac,
FL("Adding HT Caps IE since dot11mode=%d"), pScanReq->dot11mode);
ht_cap_len = 2 + sizeof(tHtCaps); /* 2 bytes for EID and Length */
len += ht_cap_len;
+ addn_ie_len += ht_cap_len;
+ }
+
+#ifdef WLAN_FEATURE_11AC
+ if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
+ limLog(pMac, LOG1,
+ FL("Adding VHT Caps IE since dot11mode=%d"),
+ pScanReq->dot11mode);
+ /* 2 bytes for EID and Length */
+ vht_cap_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
+ sizeof(tSirVhtMcsInfo);
+ len += vht_cap_len;
+ addn_ie_len += vht_cap_len;
}
+#endif /* WLAN_FEATURE_11AC */
pScanOffloadReq = vos_mem_malloc(len);
if ( NULL == pScanOffloadReq )
@@ -1204,7 +1223,7 @@ static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac,
p[i] = pScanReq->channelList.channelNumber[i];
pScanOffloadReq->uIEFieldLen = pScanReq->uIEFieldLen;
- pScanOffloadReq->uIEFieldOffset = len - ht_cap_len -
+ pScanOffloadReq->uIEFieldOffset = len - addn_ie_len -
pScanOffloadReq->uIEFieldLen;
vos_mem_copy(
(tANI_U8 *) pScanOffloadReq + pScanOffloadReq->uIEFieldOffset,
@@ -1220,10 +1239,25 @@ static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac,
vos_mem_set(ht_cap_ie, ht_cap_len, 0);
*ht_cap_ie = SIR_MAC_HT_CAPABILITIES_EID;
*(ht_cap_ie + 1) = ht_cap_len - 2;
- lim_set_ht_caps(pMac, NULL, ht_cap_ie, len - ht_cap_len);
+ lim_set_ht_caps(pMac, NULL, ht_cap_ie, ht_cap_len);
pScanOffloadReq->uIEFieldLen += ht_cap_len;
}
+#ifdef WLAN_FEATURE_11AC
+ /* Copy VHT Capability info if dot11mode is VHT Capable */
+ if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
+ /* Populate EID and Length field here */
+ vht_cap_ie = (tANI_U8 *) pScanOffloadReq +
+ pScanOffloadReq->uIEFieldOffset +
+ pScanOffloadReq->uIEFieldLen;
+ vos_mem_set(vht_cap_ie, vht_cap_len, 0);
+ *vht_cap_ie = SIR_MAC_VHT_CAPABILITIES_EID;
+ *(vht_cap_ie + 1) = vht_cap_len - 2;
+ lim_set_vht_caps(pMac, NULL, vht_cap_ie, vht_cap_len);
+ pScanOffloadReq->uIEFieldLen += vht_cap_len;
+ }
+#endif /* WLAN_FEATURE_11AC */
+
rc = wdaPostCtrlMsg(pMac, &msg);
if (rc != eSIR_SUCCESS)
{
diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c
index c6fca3359b17..23b29b257f6d 100644
--- a/CORE/MAC/src/pe/lim/limUtils.c
+++ b/CORE/MAC/src/pe/lim/limUtils.c
@@ -7525,6 +7525,70 @@ void lim_set_ht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry,
}
}
+#ifdef WLAN_FEATURE_11AC
+void lim_set_vht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry,
+ tANI_U8 *p_ie_start,tANI_U32 num_bytes)
+{
+ v_U8_t *p_ie=NULL;
+ tDot11fIEVHTCaps dot11_vht_cap;
+
+ PopulateDot11fVHTCaps(p_mac, p_session_entry, &dot11_vht_cap);
+ p_ie = limGetIEPtr(p_mac, p_ie_start, num_bytes, DOT11F_EID_VHTCAPS,
+ ONE_BYTE);
+
+ if(p_ie) {
+ tSirMacVHTCapabilityInfo *vht_cap =
+ (tSirMacVHTCapabilityInfo *) &p_ie[2];
+ tSirVhtMcsInfo *vht_mcs = (tSirVhtMcsInfo *)
+ &p_ie[2 + sizeof(tSirMacVHTCapabilityInfo)];
+ union {
+ tANI_U16 u_value;
+ tSirMacVHTRxSupDataRateInfo vht_rx_supp_rate;
+ tSirMacVHTTxSupDataRateInfo vht_tx_supp_rate;
+ } u_vht_data_rate_info;
+
+
+ vht_cap->maxMPDULen = dot11_vht_cap.maxMPDULen;
+ vht_cap->supportedChannelWidthSet =
+ dot11_vht_cap.supportedChannelWidthSet;
+ vht_cap->ldpcCodingCap = dot11_vht_cap.ldpcCodingCap;
+ vht_cap->shortGI80MHz = dot11_vht_cap.shortGI80MHz;
+ vht_cap->shortGI160and80plus80MHz =
+ dot11_vht_cap.shortGI160and80plus80MHz;
+ vht_cap->txSTBC = dot11_vht_cap.txSTBC;
+ vht_cap->rxSTBC = dot11_vht_cap.rxSTBC;
+ vht_cap->suBeamFormerCap = dot11_vht_cap.suBeamFormerCap;
+ vht_cap->suBeamformeeCap = dot11_vht_cap.suBeamformeeCap;
+ vht_cap->csnofBeamformerAntSup = dot11_vht_cap.csnofBeamformerAntSup;
+ vht_cap->numSoundingDim = dot11_vht_cap.numSoundingDim;
+ vht_cap->muBeamformerCap = dot11_vht_cap.muBeamformerCap;
+ vht_cap->muBeamformeeCap = dot11_vht_cap.muBeamformeeCap;
+ vht_cap->vhtTXOPPS = dot11_vht_cap.vhtTXOPPS;
+ vht_cap->htcVHTCap = dot11_vht_cap.htcVHTCap;
+ vht_cap->maxAMPDULenExp = dot11_vht_cap.maxAMPDULenExp;
+ vht_cap->vhtLinkAdaptCap = dot11_vht_cap.vhtLinkAdaptCap;
+ vht_cap->rxAntPattern = dot11_vht_cap.rxAntPattern;
+ vht_cap->txAntPattern = dot11_vht_cap.txAntPattern;
+ vht_cap->reserved1 = dot11_vht_cap.reserved1;
+
+ /* Populate VHT MCS Information */
+ vht_mcs->rxMcsMap = dot11_vht_cap.rxMCSMap;
+ u_vht_data_rate_info.vht_rx_supp_rate.rxSupDataRate =
+ dot11_vht_cap.rxHighSupDataRate;
+ u_vht_data_rate_info.vht_rx_supp_rate.reserved =
+ dot11_vht_cap.reserved2;
+ vht_mcs->rxHighest = u_vht_data_rate_info.u_value;
+
+ vht_mcs->txMcsMap = dot11_vht_cap.txMCSMap;
+ u_vht_data_rate_info.vht_tx_supp_rate.txSupDataRate =
+ dot11_vht_cap.txSupDataRate;
+ u_vht_data_rate_info.vht_tx_supp_rate.reserved =
+ dot11_vht_cap.reserved3;
+ vht_mcs->txHighest = u_vht_data_rate_info.u_value;
+ }
+}
+#endif /* WLAN_FEATURE_11AC */
+
#ifdef SAP_AUTH_OFFLOAD
static tpDphHashNode
_sap_offload_parse_assoc_req(tpAniSirGlobal pmac,
diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h
index 696ca6e62af3..ae83c1559e6a 100644
--- a/CORE/MAC/src/pe/lim/limUtils.h
+++ b/CORE/MAC/src/pe/lim/limUtils.h
@@ -587,6 +587,12 @@ void lim_set_ht_caps(tpAniSirGlobal p_mac,
tpPESession p_session_entry,
tANI_U8 *p_ie_start,
tANI_U32 num_bytes);
+#ifdef WLAN_FEATURE_11AC
+void lim_set_vht_caps(tpAniSirGlobal p_mac,
+ tpPESession p_session_entry,
+ tANI_U8 *p_ie_start,
+ tANI_U32 num_bytes);
+#endif /* WLAN_FEATURE_11AC */
#ifdef SAP_AUTH_OFFLOAD
void lim_sap_offload_add_sta(tpAniSirGlobal pmac,
diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h
index 42e5d3c84b6b..add56382c0f9 100644
--- a/CORE/SAP/inc/sapApi.h
+++ b/CORE/SAP/inc/sapApi.h
@@ -147,21 +147,6 @@ typedef enum{
}eSapReasonCode;
typedef enum {
- eSAP_DOT11_MODE_abg = 0x0001,
- eSAP_DOT11_MODE_11a = 0x0002,
- eSAP_DOT11_MODE_11b = 0x0004,
- eSAP_DOT11_MODE_11g = 0x0008,
- eSAP_DOT11_MODE_11n = 0x0010,
- eSAP_DOT11_MODE_11g_ONLY = 0x0080,
- eSAP_DOT11_MODE_11n_ONLY = 0x0100,
- eSAP_DOT11_MODE_11b_ONLY = 0x0400,
-#ifdef WLAN_FEATURE_11AC
- eSAP_DOT11_MODE_11ac = 0x1000,
- eSAP_DOT11_MODE_11ac_ONLY = 0x2000
-#endif
-} eSapPhyMode;
-
-typedef enum {
eSAP_ACCEPT_UNLESS_DENIED = 0,
eSAP_DENY_UNLESS_ACCEPTED = 1,
eSAP_SUPPORT_ACCEPT_AND_DENY = 2, /* this type is added to support both accept and deny lists at the same time */
@@ -456,7 +441,7 @@ typedef __ani_attr_pre_packed struct sap_SSIDInfo {
typedef struct sap_Config {
tSap_SSIDInfo_t SSIDinfo;
- eSapPhyMode SapHw_mode; /* Wireless Mode */
+ eCsrPhyMode SapHw_mode; /* Wireless Mode */
eSapMacAddrACL SapMacaddr_acl;
v_MACADDR_t accept_mac[MAX_ACL_MAC_ADDRESS]; /* MAC filtering */
v_BOOL_t ieee80211d; /*Specify if 11D is enabled or disabled*/
@@ -2222,23 +2207,6 @@ VOS_STATUS
WLANSAP_ResetSapConfigAddIE(tsap_Config_t *pConfig,
eUpdateIEsType updateType);
-
-
-/*==========================================================================
-FUNCTION sapConvertSapPhyModeToCsrPhyMode
-
-DESCRIPTION Function to implement selection of CSR PhyMode using SAP PhyMode
-
-DEPENDENCIES PARAMETERS
-
-IN sapPhyMode : SAP Phy Module
-
-RETURN VALUE If SUCCESS or FAILURE
-
-SIDE EFFECTS
-============================================================================*/
-eCsrPhyMode sapConvertSapPhyModeToCsrPhyMode( eSapPhyMode sapPhyMode );
-
/*==========================================================================
FUNCTION WLANSAP_extend_to_acs_range
diff --git a/CORE/SAP/src/sapApiLinkCntl.c b/CORE/SAP/src/sapApiLinkCntl.c
index 550563061596..ab82a867b59c 100644
--- a/CORE/SAP/src/sapApiLinkCntl.c
+++ b/CORE/SAP/src/sapApiLinkCntl.c
@@ -247,8 +247,8 @@ WLANSAP_ScanCallback
}
sme_SelectCBMode(halHandle,
- sapConvertSapPhyModeToCsrPhyMode(psapContext->csrRoamProfile.phyMode),
- psapContext->channel, vhtChannelWidth);
+ psapContext->csrRoamProfile.phyMode,
+ psapContext->channel, vhtChannelWidth);
#ifdef SOFTAP_CHANNEL_RANGE
if(psapContext->channelList != NULL)
{
@@ -442,12 +442,12 @@ WLANSAP_PreStartBssAcsScanCallback
}
sme_SelectCBMode(halHandle,
- sapConvertSapPhyModeToCsrPhyMode(psapContext->csrRoamProfile.phyMode),
- psapContext->channel, vhtChannelWidth);
+ psapContext->csrRoamProfile.phyMode,
+ psapContext->channel, vhtChannelWidth);
/* determine secondary channel for 11n mode */
- if ((eSAP_DOT11_MODE_11n == psapContext->csrRoamProfile.phyMode) ||
- (eSAP_DOT11_MODE_11n_ONLY == psapContext->csrRoamProfile.phyMode)) {
+ if ((eCSR_DOT11_MODE_11n == psapContext->csrRoamProfile.phyMode) ||
+ (eCSR_DOT11_MODE_11n_ONLY == psapContext->csrRoamProfile.phyMode)) {
ePhyChanBondState cbMode;
if (psapContext->channel > 14)
@@ -1076,8 +1076,7 @@ WLANSAP_RoamCallback
case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS:
case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_FAILURE:
{
- eCsrPhyMode phyMode =
- sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode);
+ eCsrPhyMode phyMode = sapContext->csrRoamProfile.phyMode;
/* Both success and failure cases are handled intentionally handled
* together. Irrespective of whether the channel switch IE was
diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c
index 836ca58ac794..7cd30ce2d706 100644
--- a/CORE/SAP/src/sapChSelect.c
+++ b/CORE/SAP/src/sapChSelect.c
@@ -696,7 +696,7 @@ v_BOOL_t sapChanSelInit(tHalHandle halHandle,
/* OFDM rates are not supported on channel 14 */
if(*pChans == 14 &&
- eCSR_DOT11_MODE_11b != sme_GetPhyMode(halHandle))
+ eCSR_DOT11_MODE_11b != pSapCtx->csrRoamProfile.phyMode)
{
continue;
}
@@ -2330,7 +2330,7 @@ void sapSortChlWeightAll(ptSapContext pSapCtx,
}
eChannelWidthInfo sapGetChannelWidthInfo(tHalHandle halHandle, ptSapContext pSapCtx,
- v_U32_t operatingBand, eSapPhyMode phyMode)
+ v_U32_t operatingBand, eCsrPhyMode phyMode)
{
v_U32_t cbMode;
eChannelWidthInfo chWidth = CHWIDTH_HT20;
@@ -2343,16 +2343,16 @@ eChannelWidthInfo sapGetChannelWidthInfo(tHalHandle halHandle, ptSapContext pSap
"%s: cbMode=%d, phyMode=%d",
__func__, cbMode, phyMode);
- if (phyMode == eSAP_DOT11_MODE_11n ||
- phyMode == eSAP_DOT11_MODE_11n_ONLY)
+ if (phyMode == eCSR_DOT11_MODE_11n ||
+ phyMode == eCSR_DOT11_MODE_11n_ONLY)
{
if (cbMode)
chWidth = CHWIDTH_HT40;
else
chWidth = CHWIDTH_HT20;
}
- else if (pSapCtx->csrRoamProfile.phyMode == eCSR_CFG_DOT11_MODE_11AC ||
- pSapCtx->csrRoamProfile.phyMode == eCSR_CFG_DOT11_MODE_11AC_ONLY) {
+ else if (pSapCtx->csrRoamProfile.phyMode == eCSR_DOT11_MODE_11ac ||
+ pSapCtx->csrRoamProfile.phyMode == eCSR_DOT11_MODE_11ac_ONLY) {
chWidth = CHWIDTH_HT80;
}
else {
diff --git a/CORE/SAP/src/sapFsm.c b/CORE/SAP/src/sapFsm.c
index 4b53d07082aa..e87a1c7d719a 100644
--- a/CORE/SAP/src/sapFsm.c
+++ b/CORE/SAP/src/sapFsm.c
@@ -2077,8 +2077,7 @@ sapGotoChannelSel
PMAC_STRUCT(hHal)->roam.configParam.nVhtChannelWidth;
}
sme_SelectCBMode(hHal,
- sapConvertSapPhyModeToCsrPhyMode(
- sapContext->csrRoamProfile.phyMode),
+ sapContext->csrRoamProfile.phyMode,
channel, vhtChannelWidth);
}
@@ -3362,8 +3361,7 @@ sapFsm
con_ch = sme_CheckConcurrentChannelOverlap(hHal,
sapContext->channel,
- sapConvertSapPhyModeToCsrPhyMode(
- sapContext->csrRoamProfile.phyMode),
+ sapContext->csrRoamProfile.phyMode,
sapContext->cc_switch_mode);
if (con_ch)
{
@@ -3384,9 +3382,7 @@ sapFsm
vhtChannelWidth =
pMac->roam.configParam.nVhtChannelWidth;
}
- sme_SelectCBMode(hHal,
- sapConvertSapPhyModeToCsrPhyMode(
- sapContext->csrRoamProfile.phyMode),
+ sme_SelectCBMode(hHal, sapContext->csrRoamProfile.phyMode,
sapContext->channel, vhtChannelWidth);
}
@@ -3449,17 +3445,15 @@ sapFsm
vhtChannelWidth =
pMac->roam.configParam.nVhtChannelWidth;
}
- sme_SelectCBMode(hHal,
- sapConvertSapPhyModeToCsrPhyMode(
- sapContext->csrRoamProfile.phyMode),
+ sme_SelectCBMode(hHal, sapContext->csrRoamProfile.phyMode,
sapContext->channel, vhtChannelWidth);
}
if (sapContext->channel > 14 &&
(sapContext->csrRoamProfile.phyMode ==
- eSAP_DOT11_MODE_11g ||
+ eCSR_DOT11_MODE_11g ||
sapContext->csrRoamProfile.phyMode ==
- eSAP_DOT11_MODE_11g_ONLY))
- sapContext->csrRoamProfile.phyMode = eSAP_DOT11_MODE_11a;
+ eCSR_DOT11_MODE_11g_ONLY))
+ sapContext->csrRoamProfile.phyMode = eCSR_DOT11_MODE_11a;
#ifdef WLAN_FEATURE_MBSSID
/* when AP2 is started while AP1 is performing ACS, we may not
@@ -3489,9 +3483,9 @@ sapFsm
__func__, sapContext->channel);
if (sapContext->apAutoChannelSelection &&
(sapContext->csrRoamProfile.phyMode ==
- eSAP_DOT11_MODE_11n ||
+ eCSR_DOT11_MODE_11n ||
sapContext->csrRoamProfile.phyMode ==
- eSAP_DOT11_MODE_11n_ONLY)) {
+ eCSR_DOT11_MODE_11n_ONLY)) {
tSap_Event sapApAppEvent;
sapApAppEvent.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
sapApAppEvent.sapevt.sapChannelChange.operatingChannel =
@@ -3531,8 +3525,7 @@ sapFsm
/* Radar found while performing channel availability
* check, need to switch the channel again
*/
- eCsrPhyMode phyMode =
- sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode);
+ eCsrPhyMode phyMode = sapContext->csrRoamProfile.phyMode;
tHalHandle hHal =
(tHalHandle)vos_get_context(VOS_MODULE_ID_SME, sapContext->pvosGCtx);
@@ -3940,8 +3933,7 @@ sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, t
//set the phyMode to accept anything
//Best means everything because it covers all the things we support
/*eCSR_DOT11_MODE_BEST*/
- profile->phyMode =
- sapConvertSapPhyModeToCsrPhyMode(pconfig_params->SapHw_mode);
+ profile->phyMode = pconfig_params->SapHw_mode;
//Configure beaconInterval
profile->beaconInterval = (tANI_U16)pconfig_params->beacon_int;
@@ -4015,41 +4007,6 @@ sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, t
return eSAP_STATUS_SUCCESS; /* Success. */
}
-/**
- * FUNCTION: sapConvertSapPhyModeToCsrPhyMode
- * Called internally by SAP
- */
-eCsrPhyMode sapConvertSapPhyModeToCsrPhyMode( eSapPhyMode sapPhyMode )
-{
- switch (sapPhyMode)
- {
- case (eSAP_DOT11_MODE_abg):
- return eCSR_DOT11_MODE_abg;
- case (eSAP_DOT11_MODE_11b):
- return eCSR_DOT11_MODE_11b;
- case (eSAP_DOT11_MODE_11g):
- return eCSR_DOT11_MODE_11g;
- case (eSAP_DOT11_MODE_11n):
- return eCSR_DOT11_MODE_11n;
- case (eSAP_DOT11_MODE_11a):
- return eCSR_DOT11_MODE_11a;
- case (eSAP_DOT11_MODE_11g_ONLY):
- return eCSR_DOT11_MODE_11g_ONLY;
- case (eSAP_DOT11_MODE_11n_ONLY):
- return eCSR_DOT11_MODE_11n_ONLY;
- case (eSAP_DOT11_MODE_11b_ONLY):
- return eCSR_DOT11_MODE_11b_ONLY;
-#ifdef WLAN_FEATURE_11AC
- case (eSAP_DOT11_MODE_11ac_ONLY):
- return eCSR_DOT11_MODE_11ac_ONLY;
- case (eSAP_DOT11_MODE_11ac):
- return eCSR_DOT11_MODE_11ac;
-#endif
- default:
- return eCSR_DOT11_MODE_AUTO;
- }
-}
-
void sapFreeRoamProfile(tCsrRoamProfile *profile)
{
if(profile->pRSNReqIE)
diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c
index b0039037f7a9..ff64687110a3 100644
--- a/CORE/SAP/src/sapModule.c
+++ b/CORE/SAP/src/sapModule.c
@@ -3977,9 +3977,9 @@ WLANSAP_ACS_CHSelect(v_PVOID_t pvosGCtx,
((pMac->roam.configParam.phyMode == eCSR_DOT11_MODE_abg) ||
(pMac->roam.configParam.phyMode == eCSR_DOT11_MODE_11a) ||
(pMac->roam.configParam.phyMode == eCSR_DOT11_MODE_11g)))
- sapContext->csrRoamProfile.phyMode = eSAP_DOT11_MODE_abg;
+ sapContext->csrRoamProfile.phyMode = eCSR_DOT11_MODE_abg;
else
- sapContext->csrRoamProfile.phyMode = eSAP_DOT11_MODE_11n;
+ sapContext->csrRoamProfile.phyMode = eCSR_DOT11_MODE_11n;
if ((pConfig->channel == AUTO_CHANNEL_SELECT) &&
(sapContext->isScanSessionOpen == eSAP_FALSE)) {
diff --git a/CORE/SERVICES/COMMON/wmi_version.h b/CORE/SERVICES/COMMON/wmi_version.h
index 0bb68c1a10e5..38fc945c5518 100644
--- a/CORE/SERVICES/COMMON/wmi_version.h
+++ b/CORE/SERVICES/COMMON/wmi_version.h
@@ -36,7 +36,7 @@
#define __WMI_VER_MINOR_ 0
/** WMI revision number has to be incremented when there is a
* change that may or may not break compatibility. */
-#define __WMI_REVISION_ 87
+#define __WMI_REVISION_ 88
/** The Version Namespace should not be normally changed. Only
* host and firmware of the same WMI namespace will work
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c
index 9062c8c3a852..fd2fd5fb057c 100644
--- a/CORE/SERVICES/HIF/PCIe/hif_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c
@@ -2612,6 +2612,11 @@ HIFTargetSleepStateAdjust(A_target_id_t targid,
if (sc->recovery)
return -EACCES;
+ if (adf_os_atomic_read(&sc->pci_link_suspended)) {
+ pr_err("invalid access, PCIe link is suspended");
+ VOS_BUG(0);
+ }
+
if (sleep_ok) {
adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock);
hif_state->keep_awake_count--;
diff --git a/CORE/SERVICES/HIF/USB/usbdrv.c b/CORE/SERVICES/HIF/USB/usbdrv.c
index ee5d3e1ed82a..5c7fa9a81735 100644
--- a/CORE/SERVICES/HIF/USB/usbdrv.c
+++ b/CORE/SERVICES/HIF/USB/usbdrv.c
@@ -48,6 +48,10 @@
#define IS_ISOC_EP(attr) (((attr) & 3) == 0x01)
#define IS_DIR_IN(addr) ((addr) & 0x80)
+#define IS_FW_CRASH_DUMP(x) ((x == FW_ASSERT_PATTERN) || \
+ (x == FW_REG_PATTERN) || \
+ ((x & FW_RAMDUMP_PATTERN_MASK) == FW_RAMDUMP_PATTERN))?1:0
+
static void usb_hif_post_recv_transfers(HIF_USB_PIPE *recv_pipe,
int buffer_length);
static void usb_hif_post_recv_bundle_transfers(HIF_USB_PIPE *recv_pipe,
@@ -656,25 +660,29 @@ static void usb_hif_usb_recv_bundle_complete(struct urb *urb)
do {
A_UINT16 frame_len;
- /* Hack into HTC header for bundle processing */
- HtcHdr = (HTC_FRAME_HDR *) netdata;
- if (HtcHdr->EndpointID >= ENDPOINT_MAX) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
- ("athusb: Rx: invalid EndpointID=%d\n",
- HtcHdr->EndpointID));
- break;
- }
+ if (IS_FW_CRASH_DUMP(*(A_UINT32 *) netdata))
+ frame_len = netlen;
+ else {
+ /* Hack into HTC header for bundle processing */
+ HtcHdr = (HTC_FRAME_HDR *) netdata;
+ if (HtcHdr->EndpointID >= ENDPOINT_MAX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("athusb: Rx: invalid EndpointID=%d\n",
+ HtcHdr->EndpointID));
+ break;
+ }
- payloadLen = HtcHdr->PayloadLen;
- payloadLen = A_LE2CPU16(payloadLen);
+ payloadLen = HtcHdr->PayloadLen;
+ payloadLen = A_LE2CPU16(payloadLen);
- if (payloadLen > HIF_USB_RX_BUFFER_SIZE) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
- ("athusb: payloadLen too long %u\n",
- payloadLen));
- break;
+ if (payloadLen > HIF_USB_RX_BUFFER_SIZE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("athusb: payloadLen too long %u\n",
+ payloadLen));
+ break;
+ }
+ frame_len = (HTC_HDR_LENGTH + payloadLen);
}
- frame_len = (HTC_HDR_LENGTH + payloadLen);
if (netlen >= frame_len) {
/* allocate a new skb and copy */
@@ -1072,10 +1080,6 @@ A_STATUS usb_hif_submit_ctrl_in(HIF_DEVICE_USB *device,
return ret;
}
-#define IS_FW_CRASH_DUMP(x) ((x == FW_ASSERT_PATTERN) || \
- (x == FW_REG_PATTERN) || \
- ((x & FW_RAMDUMP_PATTERN_MASK) == FW_RAMDUMP_PATTERN))?1:0
-
void usb_hif_io_comp_work(struct work_struct *work)
{
HIF_USB_PIPE *pipe = container_of(work, HIF_USB_PIPE, io_complete_work);
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 2fd40b7318b0..f67de1dbb324 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -17865,6 +17865,45 @@ end:
return ret;
}
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+static VOS_STATUS wma_auto_resume_req(tp_wma_handle wma)
+{
+ VOS_STATUS ret = VOS_STATUS_SUCCESS;
+ uint8_t ptrn_id;
+
+ /*
+ * This could happen when FW intiated resume(WAKE IRQ) and
+ * WMA intiated resume(management frame or control message
+ * happens at the same time.
+ */
+ if (!wma->resumed_cb) {
+ WMA_LOGD("ignoring auto resume, already resumed");
+ return ret;
+ }
+
+ WMA_LOGD("Clearing already configured wow patterns in fw");
+ /* Clear existing wow patterns in FW. */
+ for (ptrn_id = 0; ptrn_id < wma->wlan_resource_config.num_wow_filters;
+ ptrn_id++) {
+ ret = wma_del_wow_pattern_in_fw(wma, ptrn_id);
+ if (ret != VOS_STATUS_SUCCESS)
+ goto end;
+ }
+
+end:
+ /* need to reset if hif_pci_suspend_fails */
+ wma_set_wow_bus_suspend(wma, 0);
+ /* unpause the vdev if left paused and hif_pci_suspend fails */
+ wma_unpause_vdev(wma);
+
+ WMA_LOGD("WMA invoking resume callback");
+ wma->resumed_cb(NULL);
+ wma->resumed_cb = NULL;
+
+ return ret;
+}
+#endif
+
/*
* Pushes wow patterns from local cache to FW and configures
* wakeup trigger events.
@@ -18301,6 +18340,20 @@ static VOS_STATUS wma_suspend_req(tp_wma_handle wma, tpSirWlanSuspendParam info)
return VOS_STATUS_SUCCESS;
}
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ /* WMA could already be suspended by auto suspend, in
+ * that case just send the ready to suspend indication.
+ * Also no resume callback is required by HDD; and WMA
+ * resume will be taken care by HDD resume.
+ */
+ if (wma_get_wow_bus_suspend(wma)) {
+ WMA_LOGI("WMA is already suspended by auto suspend");
+ wma_send_status_to_suspend_ind(wma, TRUE);
+ wma->resumed_cb = NULL;
+ return VOS_STATUS_SUCCESS;
+
+ }
+#endif
wma->no_of_suspend_ind = 0;
wma->wow.gtk_pdev_enable = 0;
/*
@@ -18393,6 +18446,101 @@ send_ready_to_suspend:
return VOS_STATUS_SUCCESS;
}
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+/* Handles auto suspend indication request received from umac. */
+static VOS_STATUS wma_auto_suspend_req(tp_wma_handle wma,
+ tpSirWlanSuspendParam info)
+{
+ struct wma_txrx_node *iface;
+ bool pno_in_progress = FALSE;
+ VOS_STATUS ret;
+ uint8_t i;
+
+ if (info->sessionId > wma->max_bssid) {
+ WMA_LOGE("Invalid vdev id (%d)", info->sessionId);
+ return VOS_STATUS_E_INVAL;
+ }
+
+ iface = &wma->interfaces[info->sessionId];
+ if (!iface) {
+ WMA_LOGD("vdev %d node is not found", info->sessionId);
+ return VOS_STATUS_SUCCESS;
+ }
+
+
+ if (!wma->wow.magic_ptrn_enable && !iface->ptrn_match_enable) {
+ goto send_ready_to_suspend;
+ }
+ /* auto suspend comes with the callback to indicate
+ * HDD when the bus resumes from auto suspend.
+ */
+ if (!info->resumed_callback) {
+ WMA_LOGP("No resume callback to register with WMA");
+ return VOS_STATUS_E_INVAL;
+ }
+ wma->resumed_cb = info->resumed_callback;
+
+ if (wma_get_wow_bus_suspend(wma)) {
+ WMA_LOGE("WMA is already suspended");
+ wma_send_status_to_suspend_ind(wma, true);
+ return VOS_STATUS_SUCCESS;
+ }
+
+ iface->conn_state = (info->connectedState) ? TRUE : FALSE;
+ wma->wow.gtk_pdev_enable = 0;
+ /*
+ * Enable WOW only if PNO is required.
+ */
+ for (i = 0; i < wma->max_bssid; i++) {
+#ifdef FEATURE_WLAN_SCAN_PNO
+ if (wma->interfaces[i].pno_in_progress) {
+ WMA_LOGD("PNO is in progress, enabling wow");
+ pno_in_progress = TRUE;
+ break;
+ }
+#endif
+ }
+ for (i = 0; i < wma->max_bssid; i++) {
+ wma->wow.gtk_pdev_enable |= wma->wow.gtk_err_enable[i];
+ WMA_LOGD("VDEV_ID:%d, gtk_err_enable[%d]:%d, gtk_pdev_enable:%d",
+ i, i, wma->wow.gtk_err_enable[i],
+ wma->wow.gtk_pdev_enable);
+ }
+ if (!pno_in_progress) {
+ WMA_LOGD("skip wow if PNO not in progress");
+ goto send_ready_to_suspend;
+ }
+
+ WMA_LOGD("WOW Suspend");
+
+ ret = wma_feed_wow_config_to_fw(wma, pno_in_progress);
+ if (ret != VOS_STATUS_SUCCESS) {
+ wma_send_status_to_suspend_ind(wma, false);
+ return ret;
+ }
+
+send_ready_to_suspend:
+ /* Once WMA is suspended, then the bus suspend
+ * should happen to complete the driver auto suspend.
+ */
+ ret = cnss_auto_suspend();
+ if (ret) {
+ WMA_LOGE("%s: CNSS auto suspend failed", __func__);
+ wma_auto_resume_req(wma);
+ if (wma->resumed_cb) {
+ wma->resumed_cb(NULL);
+ wma->resumed_cb = NULL;
+ }
+ wma_send_status_to_suspend_ind(wma, false);
+ return ret;
+ }
+ wma_send_status_to_suspend_ind(wma, true);
+ wma_set_wow_bus_suspend(wma, 1);
+
+ return VOS_STATUS_SUCCESS;
+}
+#endif
+
/*
* Sends host wakeup indication to FW. On receiving this indication,
* FW will come out of WOW.
@@ -18573,6 +18721,26 @@ int wma_disable_wow_in_fw(WMA_HANDLE handle)
/* Unpause the vdev as we are resuming */
wma_unpause_vdev(wma);
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ /* When the bus resumes from auto suspend, send a message
+ * to WMA to resume itself. This should only happen for
+ * FW initiated wakeup.
+ */
+ if (wma->resumed_cb) {
+ vos_msg_t vos_msg = {0};
+ vos_msg.type = WDA_WLAN_AUTO_RESUME_IND;
+ vos_msg.bodyptr = NULL;
+ vos_msg.bodyval = 0;
+
+ if (VOS_STATUS_SUCCESS !=
+ vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg)) {
+ WMA_LOGP("%s: Failed to post WDA_WLAN_AUTO_RESUME_IND msg",
+ __func__);
+ ret = -1;
+ }
+ WMA_LOGD("WDA_WLAN_AUTO_RESUME_IND posted %d", ret);
+ }
+#endif
vos_wake_lock_timeout_acquire(&wma->wow_wake_lock, 2000);
return ret;
@@ -22891,6 +23059,35 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
goto end;
}
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ if (wma_get_wow_bus_suspend(wma_handle) &&
+ wma_handle->resumed_cb) {
+
+ switch (msg->type) {
+ /* Any command other than these should initiate auto
+ * resume, if WMA is auto suspended
+ */
+ case WDA_WLAN_SUSPEND_IND:
+ case WDA_WLAN_RESUME_REQ:
+ case WDA_WLAN_AUTO_SUSPEND_IND:
+ case WDA_WLAN_AUTO_RESUME_IND:
+ break;
+
+ default:
+ WMA_LOGI("WMA initiating bus resume");
+ if (cnss_auto_resume()) {
+ WMA_LOGE("%s: CNSS auto resume failed",
+ __func__);
+ }
+ /* Once bus is resumed, resume WMA itself */
+ wma_auto_resume_req(wma_handle);
+
+ break;
+ }
+ }
+#endif
+
+
switch (msg->type) {
#ifdef FEATURE_WLAN_ESE
case WDA_TSM_STATS_REQ:
@@ -23497,13 +23694,22 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
vos_mem_free(msg->bodyptr);
break;
#endif /* WLAN_FEATURE_APFIND */
-
case WDA_OCB_SET_SCHED_REQUEST:
wma_ocb_set_sched_req(wma_handle,
(sir_ocb_set_sched_request_t *)(msg->bodyptr));
vos_mem_free(msg->bodyptr);
break;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ case WDA_WLAN_AUTO_SUSPEND_IND:
+ wma_auto_suspend_req(wma_handle,
+ (tpSirWlanSuspendParam)msg->bodyptr);
+ vos_mem_free(msg->bodyptr);
+ break;
+ case WDA_WLAN_AUTO_RESUME_IND:
+ wma_auto_resume_req(wma_handle);
+ break;
+#endif
default:
WMA_LOGD("unknow msg type %x", msg->type);
/* Do Nothing? MSG Body should be freed at here */
@@ -26185,6 +26391,15 @@ VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen,
WMA_LOGE("pMac Handle is NULL");
return VOS_STATUS_E_FAILURE;
}
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ if (wma_get_wow_bus_suspend(wma_handle) && wma_handle->resumed_cb) {
+ WMA_LOGE("TX attempt when suspended");
+ VOS_ASSERT(0);
+ if (cnss_auto_resume())
+ WMA_LOGE("%s: CNSS auto resume failed", __func__);
+ wma_auto_resume_req(wma_handle);
+ }
+#endif
/*
* Currently only support to
* send 80211 Mgmt and 80211 Data are added.
@@ -26698,7 +26913,7 @@ int wma_resume_target(WMA_HANDLE handle)
}
wmi_pending_cmds = wmi_get_pending_cmds(wma_handle->wmi_handle);
while (wmi_pending_cmds && timeout++ < WMA_MAX_RESUME_RETRY) {
- msleep(1);
+ msleep(100);
wmi_pending_cmds = wmi_get_pending_cmds(wma_handle->wmi_handle);
}
@@ -26710,6 +26925,26 @@ int wma_resume_target(WMA_HANDLE handle)
if (EOK == ret)
wmi_set_target_suspend(wma_handle->wmi_handle, FALSE);
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ /* When the bus resumes from auto suspend, send a message
+ * to WMA to resume itself. This should only happen for
+ * FW initiated wakeup.
+ */
+ if (wma_handle->resumed_cb) {
+ vos_msg_t vos_msg = {0};
+ vos_msg.type = WDA_WLAN_AUTO_RESUME_IND;
+ vos_msg.bodyptr = NULL;
+ vos_msg.bodyval = 0;
+
+ if (VOS_STATUS_SUCCESS !=
+ vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg)) {
+ WMA_LOGP("%s: Failed to post WDA_WLAN_AUTO_RESUME_IND msg",
+ __func__);
+ ret = -1;
+ }
+ WMA_LOGD("WDA_WLAN_AUTO_RESUME_IND posted %d", ret);
+ }
+#endif
return ret;
}
diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h
index b2473525ad68..97d142c0cce0 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -79,7 +79,7 @@
#define WMA_READY_EVENTID_TIMEOUT 2000
#define WMA_TGT_SUSPEND_COMPLETE_TIMEOUT 3000
#define WMA_WAKE_LOCK_TIMEOUT 1000
-#define WMA_MAX_RESUME_RETRY 1000
+#define WMA_MAX_RESUME_RETRY 10
#define WMA_RESUME_TIMEOUT 3000
#define WMA_TGT_WOW_TX_COMPLETE_TIMEOUT 2000
#define MAX_MEM_CHUNKS 32
@@ -739,6 +739,13 @@ typedef struct {
u_int32_t hw_bd_id;
u_int32_t hw_bd_info[HW_BD_INFO_SIZE];
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ /* Callback registered by auto suspend to indicate HDD that driver
+ * resumed from auto suspend. This callback is only needed for
+ * auto resume.
+ */
+ void (*resumed_cb)(void *param);
+#endif
#ifdef FEATURE_WLAN_D0WOW
atomic_t in_d0wow;
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index f8017dea351e..93fe7ec5cfeb 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -122,9 +122,8 @@ typedef enum
}eCsrSecurityType;
-typedef enum
-{
- eCSR_DOT11_MODE_abg = 0x0001, //11a/b/g only, no HT, no proprietary
+typedef enum {
+ eCSR_DOT11_MODE_abg = 0x0001, /* 11a/b/g only, no HT, no proprietary */
eCSR_DOT11_MODE_11a = 0x0002,
eCSR_DOT11_MODE_11b = 0x0004,
eCSR_DOT11_MODE_11g = 0x0008,
@@ -132,18 +131,20 @@ typedef enum
eCSR_DOT11_MODE_11g_ONLY = 0x0020,
eCSR_DOT11_MODE_11n_ONLY = 0x0040,
eCSR_DOT11_MODE_11b_ONLY = 0x0080,
- eCSR_DOT11_MODE_11a_ONLY = 0x0100,
#ifdef WLAN_FEATURE_11AC
- eCSR_DOT11_MODE_11ac = 0x0200,
- eCSR_DOT11_MODE_11ac_ONLY = 0x0400,
+ eCSR_DOT11_MODE_11ac = 0x0100,
+ eCSR_DOT11_MODE_11ac_ONLY = 0x0200,
#endif
- //This is for WIFI test. It is same as eWNIAPI_MAC_PROTOCOL_ALL except when it starts IBSS in 11B of 2.4GHz
- //It is for CSR internal use
- eCSR_DOT11_MODE_AUTO = 0x0800,
+ /*
+ * This is for WIFI test. It is same as eWNIAPI_MAC_PROTOCOL_ALL
+ * except when it starts IBSS in 11B of 2.4GHz
+ * It is for CSR internal use
+ */
+ eCSR_DOT11_MODE_AUTO = 0x0400,
- eCSR_NUM_PHY_MODE = 16, //specify the number of maximum bits for phyMode
-}eCsrPhyMode;
+ eCSR_NUM_PHY_MODE = 16, /* specify the number of maximum bits for phyMode */
+} eCsrPhyMode;
typedef tANI_U8 tCsrBssid[VOS_MAC_ADDR_SIZE];
@@ -884,7 +885,8 @@ typedef struct tagCsrRoamProfile
//that we need to join. Index 1 is the SSID for self BSS.
tCsrSSIDs SSIDs;
tCsrBSSIDs BSSIDs;
- tANI_U32 phyMode; //this is a bit mask of all the needed phy mode defined in eCsrPhyMode
+ /* this is a bit mask of all the needed phy mode defined in eCsrPhyMode */
+ eCsrPhyMode phyMode;
eCsrRoamBssType BSSType;
tCsrAuthList AuthType;
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 15283be7d679..bb8aad3662b1 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -1087,8 +1087,7 @@ typedef struct tagCsrRoamStruct
(eCSR_DOT11_MODE_11g == (pMac)->roam.configParam.phyMode || eCSR_DOT11_MODE_11g_ONLY == (pMac)->roam.configParam.phyMode)
#define CSR_IS_PHY_MODE_A_ONLY(pMac) \
- ((eCSR_DOT11_MODE_11a == (pMac)->roam.configParam.phyMode) ||\
- (eCSR_DOT11_MODE_11a_ONLY == (pMac)->roam.configParam.phyMode))
+ (eCSR_DOT11_MODE_11a == (pMac)->roam.configParam.phyMode)
#ifdef WLAN_FEATURE_11AC
#define CSR_IS_PHY_MODE_DUAL_BAND(phyMode) \
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index dcdbcdaf2169..3b4af201158c 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -181,6 +181,9 @@ typedef struct tagSmeStruct
/* get temperature event context and callback */
void *pTemperatureCbContext;
void (*pGetTemperatureCb)(int temperature, void *context);
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ bool enable_bus_auto_suspend;
+#endif
} tSmeStruct, *tpSmeStruct;
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 4e7240314e1b..d6bad521203e 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -118,6 +118,9 @@ typedef struct _smeConfigParams
tANI_U8 max_intf_count;
tANI_BOOLEAN enable5gEBT;
tANI_BOOLEAN enableSelfRecovery;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ bool enable_bus_auto_suspend;
+#endif
} tSmeConfigParams, *tpSmeConfigParams;
typedef enum
@@ -4233,4 +4236,25 @@ eHalStatus sme_set_sap_auth_offload(tHalHandle hHal,
VOS_STATUS sme_apfind_set_cmd(struct sme_ap_find_request_req *input);
#endif /* WLAN_FEATURE_APFIND */
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+/**
+ * sme_configure_bus_auto_suspend_ind() - Auto suspend request to lower MAC
+ *
+ * @hHal: The handle returned by macOpen.
+ * @suspend_param: Callback to be called when ready to auto suspend event is
+ * received.
+ * @callback: The callback API that should be invoked when auto suspended.
+ * @context: Context associated with csrReadyToSuspendCallback.
+ *
+ * SME will pass this request to lower mac to Indicate that the wlan needs
+ * to be auto suspended.
+ *
+ * Return: HAL status success or failure
+ */
+eHalStatus sme_configure_bus_auto_suspend_ind(tHalHandle hHal,
+ tSirWlanSuspendParam *suspend_param,
+ csrReadyToSuspendCallback callback,
+ void *context);
+#endif
+
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/inc/sme_Trace.h b/CORE/SME/inc/sme_Trace.h
index dfdb9962fc6e..799cf3b5b278 100644
--- a/CORE/SME/inc/sme_Trace.h
+++ b/CORE/SME/inc/sme_Trace.h
@@ -136,6 +136,9 @@ enum {
TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE,
TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES,
TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME,
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ TRACE_CODE_SME_RX_HDD_CONFIG_AUTO_SUSPENDIND,
+#endif
};
void smeTraceInit(tpAniSirGlobal pMac);
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 4bfea18957e2..6965efeb01ab 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -2110,7 +2110,7 @@ eHalStatus csrSetPhyMode(tHalHandle hHal, tANI_U32 phyMode, eCsrBand eBand, tANI
if(eCSR_BAND_24 == eBand)
{
if(CSR_IS_RADIO_A_ONLY(pMac)) break;
- if((eCSR_DOT11_MODE_11a & phyMode) || (eCSR_DOT11_MODE_11a_ONLY & phyMode)) break;
+ if(eCSR_DOT11_MODE_11a & phyMode) break;
}
if(eCSR_BAND_5G == eBand)
{
@@ -2131,13 +2131,6 @@ eHalStatus csrSetPhyMode(tHalHandle hHal, tANI_U32 phyMode, eCsrBand eBand, tANI
if(eCSR_DOT11_MODE_11n_ONLY != phyMode) break;
newPhyMode = eCSR_DOT11_MODE_11n_ONLY;
}
- else if(eCSR_DOT11_MODE_11a_ONLY & phyMode)
- {
- if(eCSR_DOT11_MODE_11a_ONLY != phyMode) break;
- if(eCSR_BAND_24 == eBand) break;
- newPhyMode = eCSR_DOT11_MODE_11a_ONLY;
- eBand = eCSR_BAND_5G;
- }
else if(eCSR_DOT11_MODE_11g_ONLY & phyMode)
{
if(eCSR_DOT11_MODE_11g_ONLY != phyMode) break;
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index 6cacf288df9d..ac68fb376b31 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -4822,9 +4822,6 @@ static tANI_BOOLEAN csrScanIsBssAllowed(tpAniSirGlobal pMac, tSirBssDescription
case eCSR_DOT11_MODE_11b_ONLY:
fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11b == phyMode);
break;
- case eCSR_DOT11_MODE_11a_ONLY:
- fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a == phyMode);
- break;
case eCSR_DOT11_MODE_11n:
#ifdef WLAN_FEATURE_11AC
case eCSR_DOT11_MODE_11ac:
diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c
index 1a4b22bd2d14..79a4868538f7 100644
--- a/CORE/SME/src/csr/csrUtil.c
+++ b/CORE/SME/src/csr/csrUtil.c
@@ -1658,14 +1658,6 @@ tANI_BOOLEAN csrGetPhyModeInUse( eCsrPhyMode phyModeIn, eCsrPhyMode bssPhyMode,
}
break;
- case eCSR_DOT11_MODE_11a_ONLY: //11a
- if( eCSR_DOT11_MODE_11a == bssPhyMode )
- {
- fMatch = TRUE;
- cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
- }
- break;
-
case eCSR_DOT11_MODE_11g:
if(!f5GhzBand)
{
@@ -1949,7 +1941,7 @@ eCsrCfgDot11Mode csrFindBestPhyMode( tpAniSirGlobal pMac, tANI_U32 phyMode )
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
}
}
- else if( ( eCSR_DOT11_MODE_11a | eCSR_DOT11_MODE_11a_ONLY ) & phyMode )
+ else if(eCSR_DOT11_MODE_11a & phyMode)
{
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
}
@@ -5464,7 +5456,6 @@ eCsrCfgDot11Mode csrGetCfgDot11ModeFromCsrPhyMode(tCsrRoamProfile *pProfile, eCs
switch(phyMode)
{
case eCSR_DOT11_MODE_11a:
- case eCSR_DOT11_MODE_11a_ONLY:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
break;
case eCSR_DOT11_MODE_11b:
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index d368ce0c3450..c72985e586b9 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1645,6 +1645,10 @@ eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams)
pMac->enable5gEBT = pSmeConfigParams->enable5gEBT;
pMac->sme.enableSelfRecovery = pSmeConfigParams->enableSelfRecovery;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ pMac->sme.enable_bus_auto_suspend =
+ pSmeConfigParams->enable_bus_auto_suspend;
+#endif
return status;
}
@@ -4303,6 +4307,9 @@ eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam)
pParam->fP2pListenOffload = pMac->fP2pListenOffload;
pParam->max_intf_count = pMac->sme.max_intf_count;
pParam->enableSelfRecovery = pMac->sme.enableSelfRecovery;
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ pParam->enable_bus_auto_suspend = pMac->sme.enable_bus_auto_suspend;
+#endif
sme_ReleaseGlobalLock( &pMac->sme );
}
@@ -11722,7 +11729,6 @@ VOS_STATUS sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode,
eCSR_DOT11_MODE_11n_ONLY != eCsrPhyMode &&
eCSR_DOT11_MODE_11a != eCsrPhyMode &&
- eCSR_DOT11_MODE_11a_ONLY != eCsrPhyMode &&
eCSR_DOT11_MODE_abg != eCsrPhyMode
)
@@ -11855,7 +11861,6 @@ VOS_STATUS sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode,
for 802.11g only phy mode also channel bonding should be zero.
*/
if ( eCSR_DOT11_MODE_11a == eCsrPhyMode ||
- eCSR_DOT11_MODE_11a_ONLY == eCsrPhyMode ||
eCSR_DOT11_MODE_abg == eCsrPhyMode)
{
smeConfig.csrConfig.channelBondingMode5GHz =
@@ -13557,6 +13562,57 @@ eHalStatus sme_ModifyAddIE(tHalHandle hHal,
return (status);
}
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+/**
+ * sme_configure_bus_auto_suspend_ind() - Auto suspend request to lower MAC
+ *
+ * @hHal: The handle returned by macOpen.
+ * @suspend_param: Callback to be called when ready to auto suspend event is
+ * received.
+ * @callback: The callback API that should be invoked when auto suspended.
+ * @context: Context associated with csrReadyToSuspendCallback.
+ *
+ * SME will pass this request to lower mac to Indicate that the wlan needs
+ * to be auto suspended.
+ *
+ * Return: HAL status success or failure
+ */
+eHalStatus sme_configure_bus_auto_suspend_ind(tHalHandle hHal,
+ tSirWlanSuspendParam *suspend_param,
+ csrReadyToSuspendCallback callback,
+ void *context)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+ vos_msg_t vosMessage;
+ tSirWlanSuspendParam *sme_suspend_param;
+
+ MTRACE(vos_trace(VOS_MODULE_ID_SME,
+ TRACE_CODE_SME_RX_HDD_CONFIG_AUTO_SUSPENDIND, NO_SESSION, 0));
+
+ sme_suspend_param = vos_mem_malloc(sizeof(tSirWlanSuspendParam));
+ if (!sme_suspend_param) {
+ smsLog(pMac, LOGE,
+ FL("Not able to allocate memory for suspend indication"));
+ return eHAL_STATUS_FAILURE;
+ }
+ *sme_suspend_param = *suspend_param;
+
+ pMac->readyToSuspendCallback = callback;
+ pMac->readyToSuspendContext = context;
+
+ vosMessage.bodyptr = sme_suspend_param;
+ vosMessage.type = WDA_WLAN_AUTO_SUSPEND_IND;
+ vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
+ if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
+ pMac->readyToSuspendCallback = NULL;
+ pMac->readyToSuspendContext = NULL;
+ status = eHAL_STATUS_FAILURE;
+ }
+ return(status);
+}
+#endif
/*----------------------------------------------------------------------------
\fn sme_UpdateAddIE
diff --git a/CORE/SME/src/sme_common/sme_Trace.c b/CORE/SME/src/sme_common/sme_Trace.c
index c38d09a14cc4..a7a0ef04827d 100644
--- a/CORE/SME/src/sme_common/sme_Trace.c
+++ b/CORE/SME/src/sme_common/sme_Trace.c
@@ -144,6 +144,9 @@ static tANI_U8* smeTraceGetRxMsgString( tANI_U32 code )
CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE);
CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES);
CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME);
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_AUTO_SUSPENDIND);
+#endif
default:
return( "UNKNOWN" );
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index 72d4aba5bf56..9f7ff1811352 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -834,6 +834,10 @@ tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg )
#ifdef WLAN_FEATURE_APFIND
CASE_RETURN_STRING(WDA_APFIND_SET_CMD);
#endif /*WLAN_FEATURE_APFIND*/
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+ CASE_RETURN_STRING(WDA_WLAN_AUTO_SUSPEND_IND);
+ CASE_RETURN_STRING(WDA_WLAN_AUTO_RESUME_IND);
+#endif
default:
return((tANI_U8*) "UNKNOWN" );
break;
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index 8a4b7bc0eb7b..9cd68309e997 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1022,6 +1022,10 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#endif /* WLAN_FEATURE_APFIND */
#define WDA_OCB_SET_SCHED_REQUEST SIR_HAL_OCB_SET_SCHED_REQUEST
+#ifdef FEATURE_BUS_AUTO_SUSPEND
+#define WDA_WLAN_AUTO_SUSPEND_IND SIR_HAL_WLAN_AUTO_SUSPEND_IND
+#define WDA_WLAN_AUTO_RESUME_IND SIR_HAL_WLAN_AUTO_RESUME_IND
+#endif
tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
diff --git a/Kbuild b/Kbuild
index 30ef1e91ab0e..7d04fc9b27ee 100644
--- a/Kbuild
+++ b/Kbuild
@@ -231,6 +231,13 @@ ifeq ($(CONFIG_ROME_IF),pci)
CONFIG_EXT_WOW := 1
endif
+# Enable bus auto suspend for PCIe
+ifeq ($(CONFIG_ROME_IF),pci)
+ ifeq ($(CONFIG_CNSS),y)
+ CONFIG_BUS_AUTO_SUSPEND := 1
+ endif
+endif
+
#Set this to 1 to catch erroneous Target accesses during debug.
CONFIG_ATH_PCIE_ACCESS_DEBUG := 0
@@ -1288,6 +1295,11 @@ ifeq ($(CONFIG_PCI_MSM), y)
CDEFINES += -DFEATURE_WLAN_D0WOW
endif
+# Flag to enable bus auto suspend
+ifeq ($(CONFIG_BUS_AUTO_SUSPEND), 1)
+CDEFINES += -DFEATURE_BUS_AUTO_SUSPEND
+endif
+
# Some kernel include files are being moved. Check to see if
# the old version of the files are present
diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini
index b2bd255d7eda..79070176807b 100755
--- a/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/firmware_bin/WCNSS_qcom_cfg.ini
@@ -635,6 +635,13 @@ gEnableSelfRecovery=1
# 1=Enable, 0=Disable (default)
gEnableMacAddrSpoof=0
+# Enable Auto suspend feature
+# When this feature is enabled, it will shutdown the PCIe link
+# when inactivity is detected in STA disconnected mode.
+# 0 - disable
+# 1 - enable
+gEnableBusAutoSuspend=0
+
END
# Note: Configuration parser would not read anything past the END marker