diff options
| author | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2014-12-19 17:40:40 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2014-12-19 17:41:48 +0530 |
| commit | 0cedf29cf8284e062ef49867a3ef2269e4698821 (patch) | |
| tree | 74a6385721256fc85255526098f6b7d20d33018c | |
| parent | 79931468980c34ea933b1149bd3e7472cec4225d (diff) | |
| parent | db383ea2e6ea280c849fbca3e0b43c2f04d7e63f (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
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); @@ -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 |
