From d5c34f00f62920b03a250020f3447932e539a3c7 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Thu, 31 Jul 2014 17:28:21 -0700 Subject: qca_cld: Synchronize request_firmware() with suspend/resume Add the support that wait until suspend and resume are completed before loading firmware. Change-Id: Ib79a2e36bd0f70f548aa8586562269c27ae9e8eb CRs-fixed: 701407 --- CORE/SERVICES/BMI/ol_fw.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index 574e3f754e04..eef562a3ca33 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -356,8 +356,8 @@ exit: return status; } -static int ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file, - u_int32_t address, bool compressed) +static int __ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file, + u_int32_t address, bool compressed) { int status = EOK; const char *filename = NULL; @@ -692,6 +692,25 @@ end: return status; } +static int ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file, + u_int32_t address, bool compressed) +{ + int ret; + +#ifdef CONFIG_CNSS + /* Wait until suspend and resume are completed before loading FW */ + cnss_lock_pm_sem(); +#endif + + ret = __ol_transfer_bin_file(scn, file, address, compressed); + +#ifdef CONFIG_CNSS + cnss_release_pm_sem(); +#endif + + return ret; +} + u_int32_t host_interest_item_address(u_int32_t target_type, u_int32_t item_offset) { switch (target_type) { -- cgit v1.2.3 From d696a71d34e57b8b06d8158066735c7e658ce17b Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Fri, 1 Aug 2014 08:50:50 -0700 Subject: wlan: HDD: LFR3: Linux kernel compatibility check LFR3 feature is dependent on kernel support for the feature. Hence, the check is enforced to be compatible with the appropriate kernel which supports the feature. Change-Id: I281d533ff97b96b9f53b0e330bacf4c94d60cdd4 CRs-Fixed: 703288 --- CORE/HDD/src/wlan_hdd_assoc.c | 8 +++----- CORE/HDD/src/wlan_hdd_cfg80211.c | 9 +++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 0e0cdaba3f2e..9350372e8f6f 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -126,10 +126,6 @@ static void hdd_indicateEseBcnReportInd(const hdd_adapter_t *pAdapter, #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ -#ifdef WLAN_FEATURE_ROAM_OFFLOAD -#define KEY_REPLAY_CTR_SIZE 8 -#endif - static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, tANI_U32 roamId, @@ -3304,10 +3300,11 @@ eHalStatus hdd_smeRoamCallback( void *pContext, tCsrRoamInfo *pRoamInfo, tANI_U3 break; } #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +#ifdef NL80211_KEY_REPLAY_CTR_LEN /* kernel supports key mgmt offload */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD case eCSR_ROAM_AUTHORIZED_EVENT: { - v_U8_t keyReplayCtr [KEY_REPLAY_CTR_SIZE]; + v_U8_t keyReplayCtr [NL80211_KEY_REPLAY_CTR_LEN]; vos_mem_zero(keyReplayCtr, sizeof(keyReplayCtr)); hddLog(VOS_TRACE_LEVEL_DEBUG, "cfg80211_authorization_event NL80211_AUTHORIZED"); @@ -3315,6 +3312,7 @@ eHalStatus hdd_smeRoamCallback( void *pContext, tCsrRoamInfo *pRoamInfo, tANI_U3 keyReplayCtr, GFP_KERNEL); break; } +#endif #endif default: break; diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index b85b584e6cb8..b2dc7d98a491 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -3716,6 +3716,8 @@ int wlan_hdd_cfg80211_init(struct device *dev, if (pCfg->ht2040CoexEnabled) wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE; #endif + +#ifdef NL80211_KEY_LEN_PMK /* kernel supports key mgmt offload */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD if (pCfg->isRoamOffloadEnabled) { wiphy->flags |= WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD; @@ -3731,6 +3733,7 @@ int wlan_hdd_cfg80211_init(struct device *dev, "%s: LFR3:Driver key mgmt offload capability flags %x", __func__,wiphy->key_mgmt_offload_support); } +#endif #endif EXIT(); @@ -7246,6 +7249,7 @@ static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy, return status; } +#ifdef NL80211_KEY_LEN_PMK /* kernel supports key mgmt offload */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD static int wlan_hdd_cfg80211_key_mgmt_set_pmk(struct wiphy *wiphy, struct net_device *ndev, @@ -7282,6 +7286,7 @@ static int wlan_hdd_cfg80211_key_mgmt_set_pmk(struct wiphy *wiphy, return VOS_STATUS_SUCCESS; } #endif +#endif /* * FUNCTION: __wlan_hdd_cfg80211_set_default_key @@ -9747,6 +9752,7 @@ static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy, hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed")); return status; } +#ifdef NL80211_KEY_LEN_PMK /* kernel supports key mgmt offload */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD if ((eHAL_STATUS_SUCCESS == status) && (req->psk)) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: psk = %p", __func__, req->psk); @@ -9768,6 +9774,7 @@ static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy, } } } +#endif #endif pHddCtx->isAmpAllowed = VOS_FALSE; EXIT(); @@ -14836,7 +14843,9 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = .set_ap_chanwidth = wlan_hdd_cfg80211_set_ap_channel_width, #endif .dump_survey = wlan_hdd_cfg80211_dump_survey, +#ifdef NL80211_KEY_LEN_PMK /* kernel supports key mgmt offload */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD .key_mgmt_set_pmk = wlan_hdd_cfg80211_key_mgmt_set_pmk, #endif +#endif }; -- cgit v1.2.3 From 38b7618e822f4ceaf83093343407bc568ebd007e Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Thu, 31 Jul 2014 23:33:56 -0700 Subject: qcacld: Add knob to control Tx beamforming in 20Mhz Add cfg parameter to enable/disable the Tx beamforming in 20Mhz. Change-Id: I5ae2d9d6d75300a1c6098b1de3275fd158a02112 CRs-Fixed: 702982 --- CORE/HDD/inc/wlan_hdd_cfg.h | 6 ++++++ CORE/HDD/src/wlan_hdd_cfg.c | 15 +++++++++++++++ CORE/MAC/inc/wniCfgAp.h | 15 ++++++++++++--- CORE/MAC/inc/wniCfgSta.h | 9 +++++++-- CORE/MAC/src/cfg/cfgParamName.c | 1 + CORE/MAC/src/cfg/cfgUtil/cfg.txt | 8 ++++++++ CORE/MAC/src/pe/lim/limAssocUtils.c | 8 ++++++++ CORE/MAC/src/pe/lim/limPropExtsUtils.c | 15 +++++++++++++++ firmware_bin/WCNSS_cfg.dat | Bin 10842 -> 10874 bytes 9 files changed, 72 insertions(+), 5 deletions(-) mode change 100755 => 100644 firmware_bin/WCNSS_cfg.dat diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index 261228246fa0..1af28a67e521 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -2102,6 +2102,11 @@ typedef enum #define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MAX ( WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX ) #define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_DEFAULT ( WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX - 1) +#define CFG_VHT_ENABLE_TXBF_IN_20MHZ "gEnableTxBFin20MHz" +#define CFG_VHT_ENABLE_TXBF_IN_20MHZ_MIN ( 0 ) +#define CFG_VHT_ENABLE_TXBF_IN_20MHZ_MAX ( 1 ) +#define CFG_VHT_ENABLE_TXBF_IN_20MHZ_DEFAULT ( 0 ) + #endif //Enable debug for remain on channel issues @@ -3082,6 +3087,7 @@ typedef struct v_BOOL_t enableMuBformee; v_BOOL_t enableVhtpAid; v_BOOL_t enableVhtGid; + v_BOOL_t enableTxBFin20MHz; #endif v_U8_t enableAmpduPs; v_U8_t enableHtSmps; diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index 51f8808b7a0a..ebc47d559ba1 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -2972,6 +2972,13 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MIN, CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MAX ), + REG_VARIABLE( CFG_VHT_ENABLE_TXBF_IN_20MHZ, WLAN_PARAM_Integer, + hdd_config_t, enableTxBFin20MHz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_TXBF_IN_20MHZ_DEFAULT, + CFG_VHT_ENABLE_TXBF_IN_20MHZ_MIN, + CFG_VHT_ENABLE_TXBF_IN_20MHZ_MAX ), + REG_VARIABLE( CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, WLAN_PARAM_Integer, hdd_config_t, txBFCsnValue, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -5474,6 +5481,14 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx ) "Failure: Could not set value for WNI_CFG_DFS_MASTER_ENABLED"); } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_ENABLE_TXBF_20MHZ, + pConfig->enableTxBFin20MHz, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + fStatus = FALSE; + hddLog(LOGE, + "Failure: Could not set value for WNI_CFG_VHT_ENABLE_TXBF_20MHZ"); + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_HEART_BEAT_THRESHOLD, pConfig->HeartbeatThresh24, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { diff --git a/CORE/MAC/inc/wniCfgAp.h b/CORE/MAC/inc/wniCfgAp.h index 7232ae7eb0b1..985687beec7c 100644 --- a/CORE/MAC/inc/wniCfgAp.h +++ b/CORE/MAC/inc/wniCfgAp.h @@ -358,6 +358,7 @@ #define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED 311 #define WNI_CFG_IBSS_ATIM_WIN_SIZE 312 #define WNI_CFG_DFS_MASTER_ENABLED 313 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ 314 /* * String parameter lengths @@ -2628,10 +2629,18 @@ #define WNI_CFG_DFS_MASTER_ENABLED_APMAX 1 #define WNI_CFG_DFS_MASTER_ENABLED_APDEF 0 -#define CFG_PARAM_MAX_NUM 314 -#define CFG_AP_IBUF_MAX_SIZE 254 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMIN 0 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMAX 1 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STADEF 0 + +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_APMIN 0 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_APMAX 1 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_APDEF 0 + +#define CFG_PARAM_MAX_NUM 315 +#define CFG_AP_IBUF_MAX_SIZE 255 #define CFG_AP_SBUF_MAX_SIZE 3414 -#define CFG_STA_IBUF_MAX_SIZE 249 +#define CFG_STA_IBUF_MAX_SIZE 250 #define CFG_STA_SBUF_MAX_SIZE 3380 #define CFG_SEM_MAX_NUM 19 diff --git a/CORE/MAC/inc/wniCfgSta.h b/CORE/MAC/inc/wniCfgSta.h index f5ade66a74ae..daf93bfd9a12 100644 --- a/CORE/MAC/inc/wniCfgSta.h +++ b/CORE/MAC/inc/wniCfgSta.h @@ -352,6 +352,7 @@ #define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED 311 #define WNI_CFG_IBSS_ATIM_WIN_SIZE 312 #define WNI_CFG_DFS_MASTER_ENABLED 313 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ 314 /* * String parameter lengths @@ -1693,8 +1694,12 @@ #define WNI_CFG_DFS_MASTER_ENABLED_STAMAX 1 #define WNI_CFG_DFS_MASTER_ENABLED_STADEF 0 -#define CFG_PARAM_MAX_NUM 314 -#define CFG_STA_IBUF_MAX_SIZE 249 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMIN 0 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMAX 1 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STADEF 0 + +#define CFG_PARAM_MAX_NUM 315 +#define CFG_STA_IBUF_MAX_SIZE 250 #define CFG_STA_SBUF_MAX_SIZE 3380 #define CFG_SEM_MAX_NUM 19 diff --git a/CORE/MAC/src/cfg/cfgParamName.c b/CORE/MAC/src/cfg/cfgParamName.c index 6a54ca82af15..d9038bdc09cb 100644 --- a/CORE/MAC/src/cfg/cfgParamName.c +++ b/CORE/MAC/src/cfg/cfgParamName.c @@ -343,4 +343,5 @@ unsigned char *gCfgParamName[] = { (unsigned char *)"TDLS_OFF_CHANNEL_ENABLED", (unsigned char *)"IBSS_ATIM_WIN_SIZE", (unsigned char *)"DFS_MASTER_ENABLED", + (unsigned char *)"VHT_ENABLE_TXBF_20MHZ", }; diff --git a/CORE/MAC/src/cfg/cfgUtil/cfg.txt b/CORE/MAC/src/cfg/cfgUtil/cfg.txt index 670bc4e07cb0..8217dbd4a085 100644 --- a/CORE/MAC/src/cfg/cfgUtil/cfg.txt +++ b/CORE/MAC/src/cfg/cfgUtil/cfg.txt @@ -4683,3 +4683,11 @@ NONE V RW NP NONE 0 1 0 + +WNI_CFG_VHT_ENABLE_TXBF_20MHZ I 4 7 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c index 9e9404e89eec..2d5533700265 100644 --- a/CORE/MAC/src/pe/lim/limAssocUtils.c +++ b/CORE/MAC/src/pe/lim/limAssocUtils.c @@ -3689,6 +3689,7 @@ tSirRetStatus limStaSendAddBss( tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp, tANI_U8 chanWidthSupp = 0; tANI_U32 shortGi20MhzSupport; tANI_U32 shortGi40MhzSupport; + tANI_U32 enableTxBF20MHz; // Package SIR_HAL_ADD_BSS_REQ message parameters pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams )); if (NULL == pAddBssParams) @@ -3966,6 +3967,13 @@ tSirRetStatus limStaSendAddBss( tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp, else { pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, + WNI_CFG_VHT_ENABLE_TXBF_20MHZ, + &enableTxBF20MHz))) { + if (VOS_FALSE == enableTxBF20MHz) { + pAddBssParams->staContext.vhtTxBFCapable = 0; + } + } } pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave; pAddBssParams->staContext.delBASupport = ( tANI_U8 )pAssocRsp->HTCaps.delayedBA; diff --git a/CORE/MAC/src/pe/lim/limPropExtsUtils.c b/CORE/MAC/src/pe/lim/limPropExtsUtils.c index 2990b226dc1f..a077224fd115 100644 --- a/CORE/MAC/src/pe/lim/limPropExtsUtils.c +++ b/CORE/MAC/src/pe/lim/limPropExtsUtils.c @@ -87,6 +87,7 @@ limExtractApCapability(tpAniSirGlobal pMac, tANI_U8 *pIE, tANI_U16 ieLen, #if !defined WLAN_FEATURE_VOWIFI tANI_U32 localPowerConstraints = 0; #endif + tANI_U32 enableTxBF20MHz; pBeaconStruct = vos_mem_malloc(sizeof(tSirProbeRespBeacon)); if ( NULL == pBeaconStruct ) @@ -146,6 +147,20 @@ limExtractApCapability(tpAniSirGlobal pMac, tANI_U8 *pIE, tANI_U16 ieLen, } } } + if (!psessionEntry->htSupportedChannelWidthSet) { + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, + WNI_CFG_VHT_ENABLE_TXBF_20MHZ, + &enableTxBF20MHz))) { + if (VOS_FALSE == enableTxBF20MHz) { + psessionEntry->txBFIniFeatureEnabled = 0; + if (cfgSetInt(pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP, 0) + != eSIR_SUCCESS) { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_VHT_SU_BEAMFORMEE_CAP at CFG")); + } + } + } + } } else { diff --git a/firmware_bin/WCNSS_cfg.dat b/firmware_bin/WCNSS_cfg.dat old mode 100755 new mode 100644 index 066840f1dee7..f9b4fd875c4a Binary files a/firmware_bin/WCNSS_cfg.dat and b/firmware_bin/WCNSS_cfg.dat differ -- cgit v1.2.3 From 6988596025761ab7c6371fc5bf8e62a4e8c9e09d Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Mon, 28 Jul 2014 16:59:55 -0700 Subject: qcacld: CL 1041324 - update fw debug log file Add TXBFEE dbglog IDs for MU-MIMO Change-Id: I15745dd4878450c6159d3507713651ffd453dead CRs-Fixed: 701024 --- CORE/SERVICES/COMMON/dbglog_id.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CORE/SERVICES/COMMON/dbglog_id.h b/CORE/SERVICES/COMMON/dbglog_id.h index 8e02e6f0113f..b808e3ca3f55 100644 --- a/CORE/SERVICES/COMMON/dbglog_id.h +++ b/CORE/SERVICES/COMMON/dbglog_id.h @@ -958,7 +958,9 @@ extern "C" { #define TXBFEE_DBGID_PACKET_IS_STEERED 16 #define TXBFEE_UPLOADH_EVENT_ALLOC_MEM_FAIL 17 #define TXBFEE_DBGID_SW_WAR_AID_ZERO 18 -#define TXBFEE_DBGID_END 19 +#define TXBFEE_DBGID_BRPOLL_RECEIVED 19 +#define TXBFEE_DBGID_GID_RECEIVED 20 +#define TXBFEE_DBGID_END 21 /* SMPS module DBGIDs */ #define STA_SMPS_DBGID_DEFINITION_START 0 -- cgit v1.2.3 From 18c5dacdf610ac0cdc55b94986232900c5cc86c1 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Wed, 30 Jul 2014 16:51:50 -0700 Subject: qca_cld: Use CNSS APIs to initialize work queue Add support to use CNSS APIs to initialize work queue in order to compile proprietary host driver if CONFIG_DEBUG_OBJECTS_WORK flag is enabled. Change-Id: I7b83e156e8dfa208178369ae0df80fa2bcffe7f6 CRs-fixed: 702037 --- CORE/CLD_TXRX/TLSHIM/tl_shim.c | 14 ++++++++++++-- CORE/HDD/src/bap_hdd_main.c | 6 +++++- CORE/HDD/src/wlan_hdd_ipa.c | 5 ++++- CORE/HDD/src/wlan_hdd_main.c | 22 +++++++++++++++++++--- CORE/HDD/src/wlan_hdd_tdls.c | 14 +++++++++++++- CORE/HDD/src/wlan_hdd_wmm.c | 6 ++++++ CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h | 12 +++++++++++- CORE/SERVICES/WMA/wma.c | 10 ++++++++++ CORE/SERVICES/WMI/wmi_unified.c | 4 ++++ 9 files changed, 84 insertions(+), 9 deletions(-) diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c index d7e1bb09314a..f6eecac17574 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -1966,10 +1966,20 @@ VOS_STATUS WLANTL_Open(void *vos_ctx, WLANTL_ConfigInfoType *tl_cfg) INIT_LIST_HEAD(&tl_shim->sta_info[i].cached_bufq); } +#ifdef CONFIG_CNSS + cnss_init_work(&tl_shim->cache_flush_work, tl_shim_cache_flush_work); +#else INIT_WORK(&tl_shim->cache_flush_work, tl_shim_cache_flush_work); +#endif + #if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) - INIT_WORK(&(tl_shim->iapp_work.deferred_work), - tlshim_mgmt_over_data_rx_handler); +#ifdef CONFIG_CNSS + cnss_init_work(&(tl_shim->iapp_work.deferred_work), + tlshim_mgmt_over_data_rx_handler); +#else + INIT_WORK(&(tl_shim->iapp_work.deferred_work), + tlshim_mgmt_over_data_rx_handler); +#endif #endif /* * TODO: Allocate memory for tx callback for maximum supported diff --git a/CORE/HDD/src/bap_hdd_main.c b/CORE/HDD/src/bap_hdd_main.c index 995d2b54eec5..85632ac8d1c9 100644 --- a/CORE/HDD/src/bap_hdd_main.c +++ b/CORE/HDD/src/bap_hdd_main.c @@ -4194,9 +4194,13 @@ static int BSL_Write(struct sk_buff *skb) // save away the pctx context...so it can be retrieved by the work procedure. pHciContext->pctx = pctx; pHciContext->magic = BT_AMP_HCI_CTX_MAGIC; +#ifdef CONFIG_CNSS + cnss_init_work(&pHciContext->hciInterfaceProcessing, + bslWriteFinish); +#else INIT_WORK(&pHciContext->hciInterfaceProcessing, bslWriteFinish); - +#endif VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Scheduling work for skb %p, BT-AMP Client context %p, work %p", __func__, skb, pctx, pHciContext); diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c index ad77e11536b0..58c4d705d4a5 100644 --- a/CORE/HDD/src/wlan_hdd_ipa.c +++ b/CORE/HDD/src/wlan_hdd_ipa.c @@ -1096,8 +1096,11 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa) if (!hdd_ipa_is_rm_enabled(hdd_ipa)) return 0; +#ifdef CONFIG_CNSS + cnss_init_work(&hdd_ipa->rm_work, hdd_ipa_rm_send_pkt_to_ipa); +#else INIT_WORK(&hdd_ipa->rm_work, hdd_ipa_rm_send_pkt_to_ipa); - +#endif memset(&create_params, 0, sizeof(create_params)); create_params.name = IPA_RM_RESOURCE_WLAN_PROD; create_params.reg_params.user_data = hdd_ipa; diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 661bb685e9f2..06c03a38bd63 100755 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -8615,12 +8615,23 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, goto err_free_netdev; } // Workqueue which gets scheduled in IPv4 notification callback - INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue); - +#ifdef CONFIG_CNSS + cnss_init_work(&pAdapter->ipv4NotifierWorkQueue, + hdd_ipv4_notifier_work_queue); +#else + INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, + hdd_ipv4_notifier_work_queue); +#endif #ifdef WLAN_NS_OFFLOAD // Workqueue which gets scheduled in IPv6 notification callback. - INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue); +#ifdef CONFIG_CNSS + cnss_init_work(&pAdapter->ipv6NotifierWorkQueue, + hdd_ipv6_notifier_work_queue); +#else + INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, + hdd_ipv6_notifier_work_queue); +#endif #endif //Stop the Interface TX queue. netif_tx_disable(pAdapter->dev); @@ -8708,8 +8719,13 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, return NULL; } +#ifdef CONFIG_CNSS + cnss_init_work(&pAdapter->sessionCtx.monitor.pAdapterForTx-> + monTxWorkQueue, hdd_mon_tx_work_queue); +#else INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue, hdd_mon_tx_work_queue); +#endif } break; case WLAN_HDD_FTM: diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c index 43875a95af4a..c6d7818d841b 100644 --- a/CORE/HDD/src/wlan_hdd_tdls.c +++ b/CORE/HDD/src/wlan_hdd_tdls.c @@ -536,10 +536,22 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) { pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED; } + #ifdef CONFIG_TDLS_IMPLICIT +#ifdef CONFIG_CNSS + cnss_init_work(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup); +#else INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup); #endif - INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan); +#endif + +#ifdef CONFIG_CNSS + cnss_init_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, + wlan_hdd_tdls_schedule_scan); +#else + INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, + wlan_hdd_tdls_schedule_scan); +#endif /* * Release tdls lock before calling in SME api diff --git a/CORE/HDD/src/wlan_hdd_wmm.c b/CORE/HDD/src/wlan_hdd_wmm.c index 728d2e0c8308..4dd638e2701b 100644 --- a/CORE/HDD/src/wlan_hdd_wmm.c +++ b/CORE/HDD/src/wlan_hdd_wmm.c @@ -2051,8 +2051,14 @@ VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter, pQosContext->qosFlowId = 0; pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT; pQosContext->magic = HDD_WMM_CTX_MAGIC; + +#ifdef CONFIG_CNSS + cnss_init_work(&pQosContext->wmmAcSetupImplicitQos, + hdd_wmm_do_implicit_qos); +#else INIT_WORK(&pQosContext->wmmAcSetupImplicitQos, hdd_wmm_do_implicit_qos); +#endif VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, "%s: Scheduling work for AC %d, context %p", diff --git a/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h b/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h index 0fdef77d1490..1b1462503ec2 100644 --- a/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h +++ b/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h @@ -32,7 +32,9 @@ #include #include #include - +#ifdef CONFIG_CNSS +#include +#endif #include typedef struct tasklet_struct __adf_os_bh_t; @@ -67,7 +69,11 @@ __adf_os_init_work(adf_os_handle_t hdl, /*Initilize func and argument in work struct */ work->fn = func; work->arg = arg; +#ifdef CONFIG_CNSS + cnss_init_work(&work->work, __adf_os_defer_func); +#else INIT_WORK(&work->work, __adf_os_defer_func); +#endif return A_STATUS_OK; } @@ -80,7 +86,11 @@ __adf_os_init_delayed_work(adf_os_handle_t hdl, /*Initilize func and argument in work struct */ work->fn = func; work->arg = arg; +#ifdef CONFIG_CNSS + cnss_init_delayed_work(&work->dwork, __adf_os_defer_delayed_func); +#else INIT_DELAYED_WORK(&work->dwork, __adf_os_defer_delayed_func); +#endif return A_STATUS_OK; } diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 2025bc3d5802..31242689605f 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -18092,8 +18092,13 @@ wma_data_tx_ack_comp_hdlr(void *wma_context, adf_os_mem_alloc(NULL, sizeof(struct wma_tx_ack_work_ctx)); wma_handle->ack_work_ctx = ack_work; if(ack_work) { +#ifdef CONFIG_CNSS + cnss_init_work(&ack_work->ack_cmp_work, + wma_data_tx_ack_work_handler); +#else INIT_WORK(&ack_work->ack_cmp_work, wma_data_tx_ack_work_handler); +#endif ack_work->wma_handle = wma_handle; ack_work->sub_type = 0; ack_work->status = status; @@ -21537,8 +21542,13 @@ wma_mgmt_tx_ack_comp_hdlr(void *wma_context, adf_os_mem_alloc(NULL, sizeof(struct wma_tx_ack_work_ctx)); if(ack_work) { +#ifdef CONFIG_CNSS + cnss_init_work(&ack_work->ack_cmp_work, + wma_mgmt_tx_ack_work_handler); +#else INIT_WORK(&ack_work->ack_cmp_work, wma_mgmt_tx_ack_work_handler); +#endif ack_work->wma_handle = wma_handle; ack_work->sub_type = pFc->subType; ack_work->status = status; diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index e2d48f27f7ea..fdb441d9064f 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -961,8 +961,12 @@ wmi_unified_attach(ol_scn_t scn_handle) #ifndef QCA_WIFI_ISOC adf_os_spinlock_init(&wmi_handle->eventq_lock); adf_nbuf_queue_init(&wmi_handle->event_queue); +#ifdef CONFIG_CNSS + cnss_init_work(&wmi_handle->rx_event_work, wmi_rx_event_work); +#else INIT_WORK(&wmi_handle->rx_event_work, wmi_rx_event_work); #endif +#endif #ifdef WMI_INTERFACE_EVENT_LOGGING adf_os_spinlock_init(&wmi_handle->wmi_record_lock); #endif -- cgit v1.2.3 From 2308297ce487c0afc8bdd64a3825462637d46e8a Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Fri, 1 Aug 2014 11:48:29 -0700 Subject: qca_cld: Update IPA ini config parameters to the latest Set correct IPA ini config parameters for proprietary driver otherwise it will lead crash. Change-Id: Iaf02c6cf0499a7d7ad8154865f90c3e2515162ab CRs-fixed: 702037 --- firmware_bin/WCNSS_qcom_cfg.ini | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini index c9cdee6e5633..939097c3c8df 100755 --- a/firmware_bin/WCNSS_qcom_cfg.ini +++ b/firmware_bin/WCNSS_qcom_cfg.ini @@ -475,17 +475,12 @@ gEnablefwprint=0 #Enable firmware log gEnablefwlog=1 -#IPA config is a bit mask and following are the configurations. -#bit0 IPA Enable -#bit1 IPA PRE Filter enable -#bit2 IPv6 enable -#bit3 IPA Resource Manager (RM) enable -#bit4 IPA Clock scaling enable -gIPAConfig=0x1f +#IPA config +gIPAEnable=0x00 gIPADescSize=800 -gIPAHighBandwidthMbps=400 -gIPAMediumBandwidthMbps=200 -gIPALowBandwidthMbps=100 +gIPAPreFilterEnable=1 +gIPARMEnable=1 +gIPAIPv6Enable=1 #P2P Listen offload gEnableP2pListenOffload=1 -- cgit v1.2.3 From c8c8896cc3a202b4294cee662963cdf94cda257b Mon Sep 17 00:00:00 2001 From: Komal Seelam Date: Fri, 1 Aug 2014 11:39:54 +0530 Subject: qcacld: Start HTC ACK timer after TX complete of wow_enable command During Stress tests, HTC ACK is recieved to host after 1sec as the WOW_ENABLE is pending in the HTC queue nearly for one sec, where the ACK timer expired in the host and the suspend failed. Fix by waiting for TX complete before starting HTC ACK 1sec timer. Change-Id: I411adafb819b91e3e30504f1238367c659902c40 CRs-Fixed: 703573 --- CORE/SERVICES/COMMON/wmi_unified_api.h | 6 +++++- CORE/SERVICES/WMA/wma.c | 28 +++++++++++++++++++++++++++- CORE/SERVICES/WMA/wma.h | 2 ++ CORE/SERVICES/WMI/wmi_unified.c | 5 ++++- CORE/SERVICES/WMI/wmi_unified_priv.h | 1 + 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CORE/SERVICES/COMMON/wmi_unified_api.h b/CORE/SERVICES/COMMON/wmi_unified_api.h index 4ae0bdc1b932..62797d90a575 100644 --- a/CORE/SERVICES/COMMON/wmi_unified_api.h +++ b/CORE/SERVICES/COMMON/wmi_unified_api.h @@ -48,7 +48,7 @@ typedef adf_nbuf_t wmi_buf_t; * @return opaque handle. */ void * -wmi_unified_attach(void *scn_handle); +wmi_unified_attach(void *scn_handle, void (*func) (void*)); /** * detach for unified WMI * @@ -146,4 +146,8 @@ wmi_set_target_suspend(wmi_unified_t wmi_handle, A_BOOL val); void wmi_set_d0wow_flag(wmi_unified_t wmi_handle, A_BOOL flag); #endif +/** + WMA Callback to get the Tx complete for WOW_ENABLE +*/ +typedef void (*wma_wow_tx_complete_cbk)(void *scn_handle); #endif /* _WMI_UNIFIED_API_H_ */ diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 31242689605f..501cfabe14fc 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -4681,6 +4681,13 @@ wma_register_extscan_event_handler(tp_wma_handle wma_handle) return; } +void wma_wow_tx_complete(void *wma) +{ + tp_wma_handle wma_handle = (tp_wma_handle)wma; + WMA_LOGD("WOW_TX_COMPLETE DONE"); + vos_event_set(&wma_handle->wow_tx_complete); +} + /* * Allocate and init wmi adaptation layer. */ @@ -4728,7 +4735,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, } /* attach the wmi */ - wmi_handle = wmi_unified_attach(wma_handle); + wmi_handle = wmi_unified_attach(wma_handle, wma_wow_tx_complete); if (!wmi_handle) { WMA_LOGP("%s: failed to attach WMI", __func__); vos_status = VOS_STATUS_E_NOMEM; @@ -4880,6 +4887,13 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, goto err_event_init; } + vos_status = vos_event_init(&wma_handle->wow_tx_complete); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: wow_tx_complete event initialization failed", + __func__); + goto err_event_init; + } + /* Init Tx Frame Complete event */ vos_status = vos_event_init(&wma_handle->tx_frm_download_comp_event); if (!VOS_IS_STATUS_SUCCESS(vos_status)) { @@ -16324,6 +16338,7 @@ int wma_enable_wow_in_fw(WMA_HANDLE handle) cmd->enable = TRUE; vos_event_reset(&wma->target_suspend); + vos_event_reset(&wma->wow_tx_complete); wma->wow_nack = 0; host_credits = wmi_get_host_credits(wma->wmi_handle); @@ -16346,6 +16361,16 @@ int wma_enable_wow_in_fw(WMA_HANDLE handle) goto error; } + if (vos_wait_single_event(&wma->wow_tx_complete, + WMA_TGT_WOW_TX_COMPLETE_TIMEOUT) + != VOS_STATUS_SUCCESS) { + WMA_LOGE("FAILED TO RECIEVE TX COMPLETE FOR WOW"); + WMA_LOGE("Credits:%d; Pending_Cmds:%d", + wmi_get_host_credits(wma->wmi_handle), + wmi_get_pending_cmds(wma->wmi_handle)); + VOS_BUG(0); + } + wmi_set_target_suspend(wma->wmi_handle, TRUE); if (vos_wait_single_event(&wma->target_suspend, @@ -22879,6 +22904,7 @@ VOS_STATUS wma_close(v_VOID_t *vos_ctx) vos_event_destroy(&wma_handle->wma_ready_event); vos_event_destroy(&wma_handle->target_suspend); vos_event_destroy(&wma_handle->wma_resume_event); + vos_event_destroy(&wma_handle->wow_tx_complete); wma_cleanup_vdev_resp(wma_handle); #ifdef QCA_WIFI_ISOC vos_event_destroy(&wma_handle->cfg_nv_tx_complete); diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index c676eb8ada52..248e645e21bd 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -81,6 +81,7 @@ #define WMA_WAKE_LOCK_TIMEOUT 1000 #define WMA_MAX_RESUME_RETRY 1000 #define WMA_RESUME_TIMEOUT 3000 +#define WMA_TGT_WOW_TX_COMPLETE_TIMEOUT 2000 #define MAX_MEM_CHUNKS 32 /* In prima 12 HW stations are supported including BCAST STA(staId 0) @@ -554,6 +555,7 @@ typedef struct { vos_event_t wma_ready_event; vos_event_t wma_resume_event; vos_event_t target_suspend; + vos_event_t wow_tx_complete; t_cfg_nv_param cfg_nv; v_U16_t max_station; diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index fdb441d9064f..ab51a641231f 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -946,7 +946,7 @@ void wmi_rx_event_work(struct work_struct *work) /* WMI Initialization functions */ void * -wmi_unified_attach(ol_scn_t scn_handle) +wmi_unified_attach(ol_scn_t scn_handle, wma_wow_tx_complete_cbk func) { struct wmi_unified *wmi_handle; wmi_handle = (struct wmi_unified *)OS_MALLOC(NULL, sizeof(struct wmi_unified), GFP_ATOMIC); @@ -970,6 +970,7 @@ wmi_unified_attach(ol_scn_t scn_handle) #ifdef WMI_INTERFACE_EVENT_LOGGING adf_os_spinlock_init(&wmi_handle->wmi_record_lock); #endif + wmi_handle->wma_wow_tx_complete_cbk = func; return wmi_handle; } @@ -1013,6 +1014,8 @@ void wmi_htc_tx_complete(void *ctx, HTC_PACKET *htc_pkt) ((u_int32_t *)adf_nbuf_data(wmi_cmd_buf) + 2)); adf_os_spin_unlock_bh(&wmi_handle->wmi_record_lock); #endif + if (cmd_id == WMI_WOW_ENABLE_CMDID) + wmi_handle->wma_wow_tx_complete_cbk(wmi_handle->scn_handle); adf_nbuf_free(wmi_cmd_buf); adf_os_mem_free(htc_pkt); adf_os_atomic_dec(&wmi_handle->pending_cmds); diff --git a/CORE/SERVICES/WMI/wmi_unified_priv.h b/CORE/SERVICES/WMI/wmi_unified_priv.h index 692dafea36eb..c65b5ed5eed1 100644 --- a/CORE/SERVICES/WMI/wmi_unified_priv.h +++ b/CORE/SERVICES/WMI/wmi_unified_priv.h @@ -92,6 +92,7 @@ struct wmi_unified { #endif /*WMI_INTERFACE_EVENT_LOGGING*/ adf_os_atomic_t is_target_suspended; + void (*wma_wow_tx_complete_cbk)(ol_scn_t scn_handle); #ifdef FEATURE_WLAN_D0WOW A_BOOL in_d0wow; #endif -- cgit v1.2.3 From d2eb653b7b8e4782d57b6ef75adb9325263581b9 Mon Sep 17 00:00:00 2001 From: Xiaochang Duan Date: Fri, 1 Aug 2014 13:30:25 -0700 Subject: qcacld: Fix TDLS race condition that caused crash issue Race condition happens between MC thread that frees peer_list in wlan_hdd_tdls_disconnection_callback() and kworker thread that resets curr_peer->link_status to eTDLS_LINK_IDLE in __wlan_hdd_tdls_pre_setup() after mgmt tx completion failed. Use lock and add value checking to protect the data structure and also prevent crash. Change-Id: I3c3b26a7b85bea1bd3f6fa515c88b2f1a547b818 CRs-Fixed: 702789 --- CORE/HDD/src/wlan_hdd_tdls.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c index c6d7818d841b..6d2551035c66 100644 --- a/CORE/HDD/src/wlan_hdd_tdls.c +++ b/CORE/HDD/src/wlan_hdd_tdls.c @@ -1781,6 +1781,8 @@ void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter) wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx); wlan_hdd_tdls_free_list(pHddTdlsCtx); + pHddTdlsCtx->curr_candidate = NULL; + mutex_unlock(&pHddCtx->tdls_lock); } @@ -2090,6 +2092,7 @@ static void __wlan_hdd_tdls_pre_setup(struct work_struct *work) hddTdlsPeer_t *curr_peer; hddTdlsPeer_t *temp_peer; int status; + tSirMacAddr peer_mac; if (NULL == pHddTdlsCtx) { @@ -2115,14 +2118,19 @@ static void __wlan_hdd_tdls_pre_setup(struct work_struct *work) return; } + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = pHddTdlsCtx->curr_candidate; if (NULL == curr_peer) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("pHddCtx is not valid")); - return; + goto done; } + + vos_mem_copy(&peer_mac, curr_peer->peerMac, sizeof(peer_mac)); + /* * If Powersave Offload is enabled * Fw will take care incase of concurrency @@ -2169,9 +2177,22 @@ static void __wlan_hdd_tdls_pre_setup(struct work_struct *work) } curr_peer->link_status = eTDLS_LINK_DISCOVERING; + mutex_unlock(&pHddCtx->tdls_lock); + status = wlan_hdd_cfg80211_send_tdls_discover_req(pHddTdlsCtx->pAdapter->wdev.wiphy, pHddTdlsCtx->pAdapter->dev, - curr_peer->peerMac); + peer_mac); + + mutex_lock(&pHddCtx->tdls_lock); + + if (NULL == pHddTdlsCtx->curr_candidate) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: current candidate Not valid any more", __func__); + goto done; + } + + curr_peer = pHddTdlsCtx->curr_candidate; if (0 != status) { @@ -2186,11 +2207,8 @@ static void __wlan_hdd_tdls_pre_setup(struct work_struct *work) curr_peer->discovery_attempt++; - mutex_lock(&pHddCtx->tdls_lock); - wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); - mutex_unlock(&pHddCtx->tdls_lock); VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %u timeout %u msec", __func__, pHddTdlsCtx->discovery_sent_cnt, pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); @@ -2202,6 +2220,7 @@ static void __wlan_hdd_tdls_pre_setup(struct work_struct *work) done: pHddTdlsCtx->curr_candidate = NULL; pHddTdlsCtx->magic = 0; + mutex_unlock(&pHddCtx->tdls_lock); return; } -- cgit v1.2.3 From 6b8e9f32fb4a3c2e8388dd3d2fe2398dea5c0948 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Fri, 1 Aug 2014 13:08:22 -0700 Subject: qca_cld: Increase FW suspend complete event timeout to 3 seconds Increase the timeout of receiving FW suspend complete event to 3 seconds. Also do VOS_BUG if host doesn't receive the event. Change-Id: If305bb0a7b0f5da9ef513cc589e6cb9706e73bad CRs-fixed: 703377 --- CORE/SERVICES/WMA/wma.c | 1 + CORE/SERVICES/WMA/wma.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 501cfabe14fc..aaa3d982d0a0 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -16381,6 +16381,7 @@ int wma_enable_wow_in_fw(WMA_HANDLE handle) wmi_get_host_credits(wma->wmi_handle), wmi_get_pending_cmds(wma->wmi_handle)); + VOS_BUG(0); wmi_set_target_suspend(wma->wmi_handle, FALSE); return VOS_STATUS_E_FAILURE; } diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 248e645e21bd..de908f578488 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -77,7 +77,7 @@ /** Private **/ #define WMA_CFG_NV_DNLD_TIMEOUT 500 #define WMA_READY_EVENTID_TIMEOUT 2000 -#define WMA_TGT_SUSPEND_COMPLETE_TIMEOUT 1000 +#define WMA_TGT_SUSPEND_COMPLETE_TIMEOUT 3000 #define WMA_WAKE_LOCK_TIMEOUT 1000 #define WMA_MAX_RESUME_RETRY 1000 #define WMA_RESUME_TIMEOUT 3000 -- cgit v1.2.3 From c7dafa32da955e5a719eb13d8d332ede3811229d Mon Sep 17 00:00:00 2001 From: Xun Luo Date: Thu, 31 Jul 2014 22:28:46 -0700 Subject: Apply unsafe channels in both clean and open air cases Unsafe channels are applied in the channel selection process, for both green field and open air scenarios. Change-Id: I5936570f7ed50fe491fe49107b49098efb8e738b CRs-Fixed: 700314 --- CORE/HDD/src/wlan_hdd_main.c | 30 +++++++++++++++++++++++++++++- CORE/SAP/src/sapChSelect.c | 5 ++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 06c03a38bd63..ba11a3ded6ee 100755 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -11290,6 +11290,9 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) adf_os_device_t adf_ctx; tSmeThermalParams thermalParam; tSirTxPowerLimit *hddtxlimit; +#ifdef FEATURE_WLAN_CH_AVOID + int unsafeChannelIndex; +#endif ENTER(); @@ -11662,6 +11665,19 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) cnss_get_wlan_unsafe_channel(pHddCtx->unsafe_channel_list, &(pHddCtx->unsafe_channel_count), sizeof(v_U16_t) * NUM_20MHZ_RF_CHANNELS); + + hddLog(VOS_TRACE_LEVEL_INFO,"%s: num of unsafe channels is %d. ", + __func__, + pHddCtx->unsafe_channel_count); + for (unsafeChannelIndex = 0; + unsafeChannelIndex < pHddCtx->unsafe_channel_count; + unsafeChannelIndex++) + { + hddLog(VOS_TRACE_LEVEL_INFO,"%s: channel %d is not safe. ", + __func__, pHddCtx->unsafe_channel_list[unsafeChannelIndex]); + + } + /* Plug in avoid channel notification callback */ sme_AddChAvoidCallback(pHddCtx->hHal, hdd_ch_avoid_cb); @@ -13277,7 +13293,19 @@ void hdd_ch_avoid_cb } #ifdef CONFIG_CNSS - cnss_set_wlan_unsafe_channel(hdd_ctxt->unsafe_channel_list, hdd_ctxt->unsafe_channel_count); + cnss_set_wlan_unsafe_channel(hdd_ctxt->unsafe_channel_list, + hdd_ctxt->unsafe_channel_count); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : number of unsafe channels is %d ", + __func__, hdd_ctxt->unsafe_channel_count); + for (channel_loop = 0; + channel_loop < hdd_ctxt->unsafe_channel_count; + channel_loop++) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: channel %d is not safe ", __func__, + hdd_ctxt->unsafe_channel_list[channel_loop]); + } #endif if (hdd_ctxt->unsafe_channel_count) { diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c index 113b813e5703..95cbf9eed8b4 100644 --- a/CORE/SAP/src/sapChSelect.c +++ b/CORE/SAP/src/sapChSelect.c @@ -2407,6 +2407,10 @@ v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResult #endif VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Running SAP Ch Select", __func__); +#ifdef FEATURE_WLAN_CH_AVOID + sapUpdateUnsafeChannelList(); +#endif + if (NULL == pScanResult) { VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, @@ -2442,7 +2446,6 @@ v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResult // pick the first channel in configured range return startChannelNum; #else /* FEATURE_WLAN_CH_AVOID defined */ - sapUpdateUnsafeChannelList(); // any safe channels in the configured range? for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) -- cgit v1.2.3 From d453b4a45c5cd859808973646c95855f3655e4a3 Mon Sep 17 00:00:00 2001 From: Rajesh Chauhan Date: Thu, 31 Jul 2014 17:30:49 -0700 Subject: qcacld: Fill correct reason code in TDLS Teardown frame Fill correct reason code in TDLS Teardown frame. Change-Id: I9d879a4a2d1ddba6d81096f613e1d6c088ac04ee CRs-Fixed: 702867 --- CORE/HDD/src/wlan_hdd_assoc.c | 71 ++++++++++++++++++++++++++++++--------- CORE/MAC/inc/wniApi.h | 10 ++++++ CORE/SERVICES/WMA/wma.c | 29 +++++++++++++++- CORE/SME/src/csr/csrTdlsProcess.c | 3 ++ 4 files changed, 96 insertions(+), 17 deletions(-) diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 9350372e8f6f..78e66fbb1d25 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -2580,6 +2580,8 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, tSmeTdlsPeerStateParams smeTdlsPeerStateParams; eHalStatus status = eHAL_STATUS_FAILURE ; tANI_U8 staIdx; + hddTdlsPeer_t *curr_peer; + tANI_U32 reason; #ifdef WLAN_FEATURE_TDLS_DEBUG VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, @@ -2690,7 +2692,6 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, } case eCSR_ROAM_RESULT_DELETE_TDLS_PEER: { - hddTdlsPeer_t *curr_peer; for ( staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++ ) { if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pRoamInfo->sessionId) && @@ -2722,7 +2723,6 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, break ; case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND: { - hddTdlsPeer_t *curr_peer; VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Sending teardown to supplicant with reason code %u", __func__, pRoamInfo->reasonCode); @@ -2788,8 +2788,6 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER: { #ifdef CONFIG_TDLS_IMPLICIT - hddTdlsPeer_t *curr_peer; - /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */ if ((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) { @@ -2831,9 +2829,10 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, else { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, - FL("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d"), + FL("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"), pHddCtx->cfg_ini->fTDLSExternalControl, - curr_peer->isForcedPeer); + curr_peer->isForcedPeer, + pRoamInfo->reasonCode); } wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer); } @@ -2848,8 +2847,6 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN: { #ifdef CONFIG_TDLS_IMPLICIT - hddTdlsPeer_t *curr_peer; - curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE); if (!curr_peer) { @@ -2861,14 +2858,36 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, { if (eTDLS_LINK_CONNECTED == curr_peer->link_status) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Received SHOULD_TEARDOWN for peer " + MAC_ADDRESS_STR " staId: %d, reason: %d"), + MAC_ADDR_ARRAY(pRoamInfo->peerMac), + pRoamInfo->staId, + pRoamInfo->reasonCode); + + if (pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_RSSI || + pRoamInfo->reasonCode == + eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE || + pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT || + pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) + { + reason = eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE; + } + else + reason = eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON; + wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter, - curr_peer, - eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + curr_peer, + reason); } else { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: TDLS link is not connected, ignore SHOULD_TEARDOWN", __func__); + FL("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"), + pRoamInfo->reasonCode); } status = eHAL_STATUS_SUCCESS; } @@ -2881,8 +2900,6 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED: { #ifdef CONFIG_TDLS_IMPLICIT - hddTdlsPeer_t *curr_peer; - curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE); if (!curr_peer) { @@ -2894,14 +2911,36 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, { if (eTDLS_LINK_CONNECTED == curr_peer->link_status) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Received SHOULD_PEER_DISCONNECTED for peer " + MAC_ADDRESS_STR " staId: %d, reason: %d"), + MAC_ADDR_ARRAY(pRoamInfo->peerMac), + pRoamInfo->staId, + pRoamInfo->reasonCode); + + if (pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_RSSI || + pRoamInfo->reasonCode == + eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE || + pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT || + pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) + { + reason = eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE; + } + else + reason = eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON; + wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter, - curr_peer, - eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + curr_peer, + reason); } else { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: TDLS link is not connected, ignore PEER_DISCONNECTED", __func__); + FL("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"), + pRoamInfo->reasonCode); } status = eHAL_STATUS_SUCCESS; } diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h index e629b740e015..ce24720314b7 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -415,6 +415,16 @@ enum eWniMsgTypes eWNI_SME_MSG_TYPES_END }; +typedef enum { + eWNI_TDLS_TEARDOWN_REASON_TX, + eWNI_TDLS_TEARDOWN_REASON_RSSI, + eWNI_TDLS_TEARDOWN_REASON_SCAN, + eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE, + eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT, + eWNI_TDLS_TEARDOWN_REASON_BAD_PTR, + eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE, +} eWniTdlsTeardownReason; + #define WNI_CFG_MSG_TYPES_BEGIN 0x1200 /*---------------------------------------------------------------------*/ diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index aaa3d982d0a0..a0678c08d8c9 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -3841,7 +3841,6 @@ static int wma_tdls_event_handler(void *handle, u_int8_t *event, u_int32_t len) tdls_event->sessionId = peer_event->vdev_id; WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_event->peer_macaddr, tdls_event->peerMac); - tdls_event->peer_reason = peer_event->peer_reason; switch(peer_event->peer_status) { case WMI_TDLS_SHOULD_DISCOVER: @@ -3859,6 +3858,34 @@ static int wma_tdls_event_handler(void *handle, u_int8_t *event, u_int32_t len) return -1; } + switch (peer_event->peer_reason) { + case WMI_TDLS_TEARDOWN_REASON_TX: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_TX; + break; + case WMI_TDLS_TEARDOWN_REASON_RSSI: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_RSSI; + break; + case WMI_TDLS_TEARDOWN_REASON_SCAN: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_SCAN; + break; + case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: + tdls_event->peer_reason = eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE; + break; + case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT; + break; + case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_BAD_PTR; + break; + case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE; + break; + default: + WMA_LOGE("%s: unknown reason(%d) in tdls event(%d) from target", + __func__, peer_event->peer_reason, peer_event->peer_status); + return -1; + } + WMA_LOGD("%s: sending msg to umac, messageType: 0x%x, " "for peer: %pM, reason: %d, smesessionId: %d", __func__, tdls_event->messageType, tdls_event->peerMac, diff --git a/CORE/SME/src/csr/csrTdlsProcess.c b/CORE/SME/src/csr/csrTdlsProcess.c index c8c708bc41cb..44bb1dab7843 100644 --- a/CORE/SME/src/csr/csrTdlsProcess.c +++ b/CORE/SME/src/csr/csrTdlsProcess.c @@ -1300,6 +1300,7 @@ eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, sizeof(tSirMacAddr)); + roamInfo.reasonCode = tevent->peer_reason; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: eWNI_SME_TDLS_SHOULD_DISCOVER for peer mac: " MAC_ADDRESS_STR " peer_reason: %d", @@ -1315,6 +1316,7 @@ eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, sizeof(tSirMacAddr)); + roamInfo.reasonCode = tevent->peer_reason; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: eWNI_SME_TDLS_SHOULD_TEARDOWN for peer mac: " MAC_ADDRESS_STR " peer_reason: %d", @@ -1330,6 +1332,7 @@ eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, sizeof(tSirMacAddr)); + roamInfo.reasonCode = tevent->peer_reason; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: eWNI_SME_TDLS_PEER_DISCONNECTED for peer mac: " MAC_ADDRESS_STR " peer_reason: %d", -- cgit v1.2.3 From d54549036eb2df2e4b00d1f1e9e97ce22eeb2a62 Mon Sep 17 00:00:00 2001 From: Rajesh Chauhan Date: Thu, 31 Jul 2014 19:10:35 -0700 Subject: qcacld: Fix issue in TDLS peer info to FW Provide FW with correct role of a TDLS peer: TDLS Initiator or Responder. Change-Id: I7eb9b187b80ba9ec81cd88ffb14d45a421813dd6 CRs-Fixed: 702975 --- CORE/HDD/src/wlan_hdd_cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index b2dc7d98a491..2087301f9654 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -12386,7 +12386,7 @@ static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *d status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, peerMac, action_code, dialog_token, status_code, peer_capability, - (tANI_U8 *)buf, len, responder); + (tANI_U8 *)buf, len, !responder); if (VOS_STATUS_SUCCESS != status) { @@ -12433,11 +12433,11 @@ static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *d if (SIR_MAC_TDLS_SETUP_RSP == action_code) { - return wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE); + return wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE); } else if (SIR_MAC_TDLS_SETUP_CNF == action_code) { - return wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE); + return wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE); } return 0; -- cgit v1.2.3 From 1346e8a305776a004c2a5e3aafbb5f645bb4517d Mon Sep 17 00:00:00 2001 From: Krishna Kumaar Natarajan Date: Wed, 30 Jul 2014 17:41:38 -0700 Subject: qcacld: Fix to remove DFS channels from TDLS frames List of supported channels sent as part of Discovery Request, Setup Request and Setup Response TDLS frames have DFS channels present. We should not be switching to DFS channels and hence this change set validate the list of channels before populating them into TDLS frames. Change-Id: Ie08cf5612cf8d214f5472c01d6f4d00de474d092 CRs-Fixed: 702165 --- CORE/MAC/src/pe/lim/limProcessTdls.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/CORE/MAC/src/pe/lim/limProcessTdls.c b/CORE/MAC/src/pe/lim/limProcessTdls.c index 210c69292bbd..0d4670b55f63 100644 --- a/CORE/MAC/src/pe/lim/limProcessTdls.c +++ b/CORE/MAC/src/pe/lim/limProcessTdls.c @@ -4955,6 +4955,8 @@ void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac, tANI_U32 numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; tANI_U8 validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; tANI_U8 i; + tANI_U8 valid_count = 0; + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, validChan, &numChans) != eSIR_SUCCESS) { @@ -4965,13 +4967,23 @@ void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac, limLog(pMac, LOGP, FL("could not retrieve Valid channel list")); } - suppChannels->num_bands = (tANI_U8) numChans; - for ( i = 0U; i < suppChannels->num_bands; i++) + /* validating the channel list for DFS channels */ + for (i = 0U; i < numChans; i++) { - suppChannels->bands[i][0] = validChan[i]; - suppChannels->bands[i][1] = 1; + if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(validChan[i])) + { + limLog(pMac, LOG1, + FL("skipping DFS channel %d from the valid channel list"), + validChan[i]); + continue; + } + suppChannels->bands[valid_count][0] = validChan[i]; + suppChannels->bands[valid_count][1] = 1; + valid_count++; } + + suppChannels->num_bands = valid_count; suppChannels->present = 1 ; return ; } -- cgit v1.2.3 From 45039f47ecc7779a0260eefc3b871860e83c99ce Mon Sep 17 00:00:00 2001 From: Atul Mittal Date: Fri, 1 Aug 2014 21:18:26 +0530 Subject: wlan: Addition of Operating class IE in tdls frames When TDLS offchannel support is enabled setup req/resp and discovery response frames need to encode supported operating class IE. Classes are derived based on the available channels for a country. Unique list of sorted, supporting classes is formed as per spec. Change-Id: I3a8d0cdbe11b873244d06b85044517f4f54c436e CRs-Fixed: 703290 --- CORE/MAC/src/pe/lim/limProcessTdls.c | 265 ++++++++++++++++++++++++++++++++++- CORE/MAC/src/pe/lim/limUtils.h | 17 +++ CORE/SME/src/csr/csrApiRoam.c | 4 +- 3 files changed, 283 insertions(+), 3 deletions(-) diff --git a/CORE/MAC/src/pe/lim/limProcessTdls.c b/CORE/MAC/src/pe/lim/limProcessTdls.c index 0d4670b55f63..5f55c8117844 100644 --- a/CORE/MAC/src/pe/lim/limProcessTdls.c +++ b/CORE/MAC/src/pe/lim/limProcessTdls.c @@ -137,6 +137,80 @@ tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac, tDot11fIEVHTCaps *pPeerVHTCaps, tpPESession psessionEntry); ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode); +/*only 31 op classes are available, 1 entry for current op class*/ +static tDot11fIESuppOperatingClasses op_classes = {0}; + +op_class_map_t global_op_class[] = { + {81, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {82, 25, BW20, {14}}, + {83, 40, BW40PLUS, {1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {84, 40, BW40MINUS, {5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {115, 20, BW20, {36, 40, 44, 48}}, + {116, 40, BW40PLUS, {36, 44}}, + {117, 40, BW40MINUS, {40, 48}}, + {118, 20, BW20, {52, 56, 60, 64}}, + {119, 40, BW40PLUS, {52, 60}}, + {120, 40, BW40MINUS, {56, 64}}, + {121, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {122, 40, BW40PLUS, {100, 108, 116, 124, 132}}, + {123, 40, BW40MINUS, {104, 112, 120, 128, 136}}, + {125, 20, BW20, {149, 153, 157, 161, 165, 169}}, + {126, 40, BW40PLUS, {149, 157}}, + {127, 40, BW40MINUS, {153, 161}}, + {0, 0, 0, {0}}, + +};/*end global_op_class*/ + +op_class_map_t us_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {2, 20, BW20, {52, 56, 60, 64}}, + {4, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {5, 20, BW20, {149, 153, 157, 161, 165}}, + {22, 40, BW40PLUS, {36, 44}}, + {23, 40, BW40PLUS, {52, 60}}, + {24, 40, BW40PLUS, {100, 108, 116, 124, 132}}, + {26, 40, BW40PLUS, {149, 157}}, + {27, 40, BW40MINUS, {40, 48}}, + {28, 40, BW40MINUS, {56, 64}}, + {29, 40, BW40MINUS, {104, 112, 120, 128, 136}}, + {31, 40, BW40MINUS, {153, 161}}, + {32, 40, BW40PLUS, {1, 2, 3, 4, 5, 6, 7}}, + {33, 40, BW40MINUS, {5, 6, 7, 8, 9, 10, 11}}, + {0, 0, 0, {0}}, +};/*end us_op_class*/ + +op_class_map_t euro_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {2, 20, BW20, {52, 56, 60, 64}}, + {3, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {4, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {5, 40, BW40PLUS, {36, 44}}, + {6, 40, BW40PLUS, {52, 60}}, + {7, 40, BW40PLUS, {100, 108, 116, 124, 132}}, + {8, 40, BW40MINUS, {40, 48}}, + {9, 40, BW40MINUS, {56, 64}}, + {10, 40, BW40MINUS, {104, 112, 120, 128, 136}}, + {11, 40, BW40PLUS, {1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {12, 40, BW40MINUS, {5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {17, 20, BW20, {149, 153, 157, 161, 165, 169}}, + {0, 0, 0, {0}}, +};/*end euro_op_class*/ + +op_class_map_t japan_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {30, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {31, 25, BW20, {14}}, + {32, 20, BW20, {52, 56, 60, 64}}, + {34, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {36, 40, BW40PLUS, {36, 44}}, + {37, 40, BW40PLUS, {52, 60}}, + {39, 40, BW40PLUS, {100, 108, 116, 124, 132}}, + {41, 40, BW40MINUS, {40, 48}}, + {42, 40, BW40MINUS, {56, 64}}, + {44, 40, BW40MINUS, {104, 112, 120, 128, 136}}, + {0, 0, 0, {0}}, +};/*end japan_op_class*/ + /* * TDLS data frames will go out/come in as non-qos data. * so, eth_890d_header will be aligned access.. @@ -4956,7 +5030,7 @@ void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac, tANI_U8 validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; tANI_U8 i; tANI_U8 valid_count = 0; - + tANI_U8 op_class; if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, validChan, &numChans) != eSIR_SUCCESS) { @@ -4985,6 +5059,33 @@ void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac, suppChannels->num_bands = valid_count; suppChannels->present = 1 ; + /*Get present operating class based on current operating channel*/ + op_class = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset); + if (op_class == 0) + { + PELOGE(limLog(pMac, LOGE, FL("Present Operating class is Wrong!!!"));) + } + else + { + PELOGE(limLog(pMac, LOG1, FL("Present Operating channel=%d offset=%d class=%d"), + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset, + op_class);) + } + suppOperClasses->present = 1; + suppOperClasses->classes[0] = op_class; + /*Fill operating classes from static array*/ + suppOperClasses->num_classes = op_classes.num_classes; + for ( i = 0U; i < suppOperClasses->num_classes; i++) + { + suppOperClasses->classes[i+1] = op_classes.classes[i]; + + } + /*increment for present operating class*/ + suppOperClasses->num_classes++; return ; } /* @@ -5637,4 +5738,166 @@ tSirRetStatus limDeleteTDLSPeers(tpAniSirGlobal pMac, tpPESession psessionEntry) return eSIR_SUCCESS; } + + +tANI_U8 limGetOPClassFromChannel(tANI_U8 *country, + tANI_U8 channel, + tANI_U8 offset) +{ + op_class_map_t *class = NULL; + tANI_U16 i = 0; + + if (VOS_TRUE == vos_mem_compare(country,"US", 2)) { + + class = us_op_class; + + } else if (VOS_TRUE == vos_mem_compare(country,"EU", 2)) { + + class = euro_op_class; + + } else if (VOS_TRUE == vos_mem_compare(country,"JP", 2)) { + + class = japan_op_class; + + } else { + + class = global_op_class; + + } + + while (class->op_class) + { + if ((offset == class->offset) || (offset == BWALL)) + { + for (i=0; (i < 15 && class->channels[i]); i++) + { + if (channel == class->channels[i]) + return class->op_class; + } + } + class++; + } + return 0; +} + +tANI_BOOLEAN CheckAndAddOP(tANI_U8 class) +{ + tANI_U8 i; + + for (i=0; i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); i++) + { + /*0 is an invalid class. If class is already present ignore*/ + if (class == op_classes.classes[i]) + return FALSE; + if(op_classes.classes[i] == 0) + { + return TRUE; + } + } + //limLog(pMac, LOGE, FL("No space left for class = %d"), class); + return FALSE; +} + +void limInitOperatingClasses( tHalHandle hHal ) +{ + + tANI_U8 Index = 0; + tANI_U8 class = 0; + tANI_U8 i = 0; + tANI_U8 j = 0; + tANI_U8 swap = 0; + tANI_U8 numChannels = 0; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + limLog(pMac, LOG1, FL("Current Country = %c%c"), + pMac->scan.countryCodeCurrent[0], + pMac->scan.countryCodeCurrent[1]); + + vos_mem_set(op_classes.classes, sizeof(op_classes.classes), 0); + numChannels = pMac->scan.baseChannels.numChannels; + limLog(pMac, LOG1, "Num of base ch =%d", numChannels); + for ( Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) + { + class = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + pMac->scan.baseChannels.channelList[ Index ], + BWALL); + limLog(pMac, LOG4, "ch=%d <=> %d=class", + pMac->scan.baseChannels.channelList[ Index ], + class); + if (CheckAndAddOP(class)) + { + op_classes.classes[i]= class; + i++; + } + } + + numChannels = pMac->scan.base20MHzChannels.numChannels; + limLog(pMac, LOG1, "Num of 20MHz ch =%d", numChannels); + for ( Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) + { + class = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + pMac->scan.base20MHzChannels.channelList[ Index ], + BWALL); + limLog(pMac, LOG4, "ch=%d <=> %d=class", + pMac->scan.base20MHzChannels.channelList[ Index ], + class); + if (CheckAndAddOP(class)) + { + op_classes.classes[i]= class; + i++; + } + } + + numChannels = pMac->scan.base40MHzChannels.numChannels; + limLog(pMac, LOG1, "Num of 40MHz ch =%d", numChannels); + for ( Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) + { + class = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + pMac->scan.base40MHzChannels.channelList[ Index ], + BWALL); + limLog(pMac, LOG4, "ch=%d <=> %d=class", + pMac->scan.base40MHzChannels.channelList[ Index ], + class); + if (CheckAndAddOP(class)) + { + op_classes.classes[i]= class; + i++; + } + } + + op_classes.num_classes = i; + limLog(pMac, LOG1, "Total number of Unique supported classes =%d", + op_classes.num_classes); + /*as per spec the operating classes should be in ascending order*/ + /*Bubble sort is fine as we don't have many classes*/ + for (i = 0 ; i < ( op_classes.num_classes - 1 ); i++) + { + for (j = 0 ; j < op_classes.num_classes - i - 1; j++) + { + /* For decreasing order use < */ + if (op_classes.classes[j] > op_classes.classes[j+1]) + { + swap = op_classes.classes[j]; + op_classes.classes[j] = op_classes.classes[j+1]; + op_classes.classes[j+1] = swap; + } + } + } + for (i=0; i < op_classes.num_classes; i++) + { + + limLog(pMac, LOG1, "supported op_class[%d]=%d", i, + op_classes.classes[i]); + + } +} + #endif diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h index cba5753ec3a0..9efda6fffce5 100644 --- a/CORE/MAC/src/pe/lim/limUtils.h +++ b/CORE/MAC/src/pe/lim/limUtils.h @@ -102,6 +102,19 @@ typedef union uPmfSaQueryTimerId } tPmfSaQueryTimerId, *tpPmfSaQueryTimerId; #endif +typedef enum offset { + BW20, + BW40PLUS, + BW40MINUS, + BWALL +} offset_t; + +typedef struct op_class_map { + tANI_U8 op_class; + tANI_U8 ch_spacing; + offset_t offset; + tANI_U8 channels[15]; +}op_class_map_t; // LIM utility functions void limGetBssidFromPkt(tpAniSirGlobal, tANI_U8 *, tANI_U8 *, tANI_U32 *); char * limMlmStateStr(tLimMlmStates state); @@ -595,4 +608,8 @@ void limSetProtectedBit(tpAniSirGlobal pMac, tANI_U8* lim_get_ie_ptr(tANI_U8 *pIes, int length, tANI_U8 eid); +void limInitOperatingClasses(tHalHandle hHal); +tANI_U8 limGetOPClassFromChannel(tANI_U8 *country, + tANI_U8 channel, + tANI_U8 offset); #endif /* __LIM_UTILS_H */ diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index ac4717621ff4..b4435cc152f0 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -480,6 +480,7 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac) bufLen = sizeof(tSirUpdateChanList) + (sizeof(tSirUpdateChanParam) * (numChan - 1)); + limInitOperatingClasses((tHalHandle)pMac); pChanList = (tSirUpdateChanList *) vos_mem_malloc(bufLen); if (!pChanList) { @@ -2333,7 +2334,6 @@ eHalStatus csrInitGetChannels(tpAniSirGlobal pMac) } return (status); } - eHalStatus csrInitChannelList( tHalHandle hHal ) { tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); @@ -2344,7 +2344,7 @@ eHalStatus csrInitChannelList( tHalHandle hHal ) csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE); // Apply the base channel list, power info, and set the Country code... csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent, eANI_BOOLEAN_TRUE ); - + limInitOperatingClasses(hHal); return (status); } eHalStatus csrChangeConfigParams(tpAniSirGlobal pMac, -- cgit v1.2.3 From 4df8726fa56dd600e3a6d34dbe257da06067645c Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Sat, 26 Jul 2014 18:44:41 -0700 Subject: qcacld: ipa: Queue tx packets when WoW suspended With IPA, there is no way to stop the data transfer when host is suspended. There are cases where in, when WoW resume is on going, host tries to send data packets to firmware resulting in firmware assert. Fix this issue by queuing tx packets coming from IPA while resume is on going. Once resume is completed, schedule an work queue to drain all the packets. Also change the implementation to release the wake lock after a delay. Since kernel would try to suspend as soon as wake lock is released this would lead to ping-pong between suspend-resume while there is some amount of data transfer going over IPA pipes. Adding delay in releasing the wake lock would help for throughput as well. Change-Id: I8144ac7840fb33291e3f47e7381de07a24284dd1 CRs-fixed: 699669 --- CORE/HDD/inc/wlan_hdd_ipa.h | 3 + CORE/HDD/src/wlan_hdd_cfg80211.c | 14 ++ CORE/HDD/src/wlan_hdd_early_suspend.c | 9 + CORE/HDD/src/wlan_hdd_ipa.c | 313 +++++++++++++++++++++++++++++----- 4 files changed, 295 insertions(+), 44 deletions(-) diff --git a/CORE/HDD/inc/wlan_hdd_ipa.h b/CORE/HDD/inc/wlan_hdd_ipa.h index 0b6a04f9e60c..6e448c2acea4 100644 --- a/CORE/HDD/inc/wlan_hdd_ipa.h +++ b/CORE/HDD/inc/wlan_hdd_ipa.h @@ -55,6 +55,9 @@ bool hdd_ipa_is_enabled(hdd_context_t *pHddCtx); int hdd_ipa_set_perf_level(hdd_context_t *hdd_ctx, uint64_t tx_packets, uint64_t rx_packets); +int hdd_ipa_suspend(hdd_context_t *hdd_ctx); +int hdd_ipa_resume(hdd_context_t *hdd_ctx); + #endif #endif diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 2087301f9654..b31dc0b3022b 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -105,6 +105,9 @@ #include "nan_Api.h" #include "wlan_hdd_nan.h" #endif +#ifdef IPA_OFFLOAD +#include +#endif #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -13634,6 +13637,17 @@ int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, pAdapterNode = pNext; } +#ifdef IPA_OFFLOAD + /* + * Suspend IPA early before proceeding to suspend other entities like + * firmware to avoid any race conditions. + */ + if (hdd_ipa_suspend(pHddCtx)) { + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("IPA not ready to suspend!")); + return -EAGAIN; + } +#endif + /* Wait for the target to be ready for suspend */ INIT_COMPLETION(pHddCtx->ready_to_suspend); diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c index ae4fe6a84db2..4b9e0cae5c6d 100644 --- a/CORE/HDD/src/wlan_hdd_early_suspend.c +++ b/CORE/HDD/src/wlan_hdd_early_suspend.c @@ -78,6 +78,9 @@ #include #include #include +#ifdef IPA_OFFLOAD +#include +#endif /**----------------------------------------------------------------------------- * Preprocessor definitions and constants @@ -1327,6 +1330,7 @@ send_suspend_ind: status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); pAdapterNode = pNext; } + pHddCtx->hdd_wlan_suspended = TRUE; #ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP @@ -1580,6 +1584,7 @@ void hdd_resume_wlan(void) } pHddCtx->hdd_wlan_suspended = FALSE; + /*loop through all adapters. Concurrency */ status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); @@ -1647,6 +1652,10 @@ send_resume_ind: pAdapterNode = pNext; } +#ifdef IPA_OFFLOAD + hdd_ipa_resume(pHddCtx); +#endif + #ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY) { diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c index 58c4d705d4a5..033ecf182103 100644 --- a/CORE/HDD/src/wlan_hdd_ipa.c +++ b/CORE/HDD/src/wlan_hdd_ipa.c @@ -155,6 +155,11 @@ struct hdd_ipa_rx_hdr { struct ethhdr eth; } __packed; +struct hdd_ipa_pm_tx_cb { + struct hdd_ipa_iface_context *iface_context; + struct ipa_rx_data *ipa_tx_desc; +}; + #ifdef IPA_UC_OFFLOAD struct hdd_ipa_uc_rx_hdr { struct ethhdr eth; @@ -269,6 +274,9 @@ struct hdd_ipa_stats { uint64_t max_pend_q_cnt; uint64_t num_tx_comp_cnt; + uint64_t num_tx_queued; + uint64_t num_tx_dequeued; + uint64_t num_max_pm_queue; uint64_t num_freeq_empty; uint64_t num_pri_freeq_empty; @@ -286,9 +294,17 @@ struct hdd_ipa_priv { adf_os_spinlock_t rm_lock; struct work_struct rm_work; vos_wake_lock_t wake_lock; + struct delayed_work wake_lock_work; + bool wake_lock_released; + enum ipa_client_type prod_client; atomic_t tx_ref_cnt; + adf_nbuf_queue_t pm_queue_head; + struct work_struct pm_work; + adf_os_spinlock_t pm_lock; + bool suspended; + uint32_t pending_hw_desc_cnt; uint32_t hw_desc_cnt; spinlock_t q_lock; @@ -883,13 +899,34 @@ static int hdd_ipa_rm_request(struct hdd_ipa_priv *hdd_ipa) hdd_ipa->rm_state = HDD_IPA_RM_GRANTED; hdd_ipa->stats.num_rm_grant_imm++; } - adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); - vos_wake_lock_acquire(&hdd_ipa->wake_lock); + cancel_delayed_work(&hdd_ipa->wake_lock_work); + if (hdd_ipa->wake_lock_released) { + vos_wake_lock_acquire(&hdd_ipa->wake_lock); + hdd_ipa->wake_lock_released = false; + } + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); return ret; } +static void hdd_ipa_wake_lock_timer_func(struct work_struct *work) +{ + struct hdd_ipa_priv *hdd_ipa = container_of(to_delayed_work(work), + struct hdd_ipa_priv, wake_lock_work); + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + + if (hdd_ipa->rm_state != HDD_IPA_RM_RELEASED) + goto end; + + hdd_ipa->wake_lock_released = true; + vos_wake_lock_release(&hdd_ipa->wake_lock); + +end: + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); +} + static int hdd_ipa_rm_try_release(struct hdd_ipa_priv *hdd_ipa) { int ret = 0; @@ -907,6 +944,15 @@ static int hdd_ipa_rm_try_release(struct hdd_ipa_priv *hdd_ipa) } spin_unlock_bh(&hdd_ipa->q_lock); + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + + if (!adf_nbuf_is_queue_empty(&hdd_ipa->pm_queue_head)) { + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + return -EAGAIN; + } + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); switch(hdd_ipa->rm_state) { case HDD_IPA_RM_GRANTED: @@ -929,14 +975,22 @@ static int hdd_ipa_rm_try_release(struct hdd_ipa_priv *hdd_ipa) ret = ipa_rm_inactivity_timer_release_resource( IPA_RM_RESOURCE_WLAN_PROD); + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); if (unlikely(ret != 0)) { - adf_os_spin_lock_bh(&hdd_ipa->rm_lock); hdd_ipa->rm_state = HDD_IPA_RM_GRANTED; - adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); WARN_ON(1); } - vos_wake_lock_release(&hdd_ipa->wake_lock); + /* + * If wake_lock is released immediately, kernel would try to suspend + * immediately as well, Just avoid ping-pong between suspend-resume + * while there is healthy amount of data transfer going on by + * releasing the wake_lock after some delay. + */ + schedule_delayed_work(&hdd_ipa->wake_lock_work, + msecs_to_jiffies(HDD_IPA_RX_INACTIVITY_MSEC_DELAY)); + + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); return ret; } @@ -1149,8 +1203,11 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa) } vos_wake_lock_init(&hdd_ipa->wake_lock, "wlan_ipa"); + INIT_DELAYED_WORK(&hdd_ipa->wake_lock_work, + hdd_ipa_wake_lock_timer_func); adf_os_spinlock_init(&hdd_ipa->rm_lock); hdd_ipa->rm_state = HDD_IPA_RM_RELEASED; + hdd_ipa->wake_lock_released = true; atomic_set(&hdd_ipa->tx_ref_cnt, 0); return ret; @@ -1175,8 +1232,12 @@ static void hdd_ipa_destory_rm_resource(struct hdd_ipa_priv *hdd_ipa) if (!hdd_ipa_is_rm_enabled(hdd_ipa)) return; + cancel_delayed_work_sync(&hdd_ipa->wake_lock_work); vos_wake_lock_destroy(&hdd_ipa->wake_lock); + cancel_work_sync(&hdd_ipa->rm_work); + adf_os_spinlock_destroy(&hdd_ipa->rm_lock); + ipa_rm_inactivity_timer_destroy(IPA_RM_RESOURCE_WLAN_PROD); ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WLAN_PROD); @@ -1578,47 +1639,13 @@ static void hdd_ipa_nbuf_cb(adf_nbuf_t skb) hdd_ipa_rm_try_release(hdd_ipa); } -static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, - unsigned long data) +static void hdd_ipa_send_pkt_to_tl(struct hdd_ipa_iface_context *iface_context, + struct ipa_rx_data *ipa_tx_desc) { - struct hdd_ipa_priv *hdd_ipa = NULL; - struct ipa_rx_data *ipa_tx_desc; - struct hdd_ipa_iface_context *iface_context; - adf_nbuf_t skb; + struct hdd_ipa_priv *hdd_ipa = iface_context->hdd_ipa; v_U8_t interface_id; hdd_adapter_t *adapter = NULL; - - if (evt != IPA_RECEIVE) { - skb = (adf_nbuf_t) data; - dev_kfree_skb_any(skb); - iface_context->stats.num_tx_drop++; - return; - } - - iface_context = (struct hdd_ipa_iface_context *) priv; - ipa_tx_desc = (struct ipa_rx_data *)data; - skb = ipa_tx_desc->skb; - - hdd_ipa = iface_context->hdd_ipa; - - /* - * When SSR is going on, just drop the packets. There is no use in - * queueing the packets as STA has to connect back any way - */ - if (hdd_ipa->hdd_ctx->isLogpInProgress) { - ipa_free_skb(ipa_tx_desc); - iface_context->stats.num_tx_drop++; - return; - } - - adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); - NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID; - NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb; - NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dma_addr; - - NBUF_OWNER_PRIV_DATA(skb) = data; - - HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "i2w", skb->data, 8); + adf_nbuf_t skb; adf_os_spin_lock_bh(&iface_context->interface_lock); adapter = iface_context->adapter; @@ -1627,6 +1654,7 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, ipa_free_skb(ipa_tx_desc); iface_context->stats.num_tx_drop++; adf_os_spin_unlock_bh(&iface_context->interface_lock); + hdd_ipa_rm_try_release(hdd_ipa); return; } @@ -1638,6 +1666,7 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, ipa_free_skb(ipa_tx_desc); adf_os_spin_unlock_bh(&iface_context->interface_lock); iface_context->stats.num_tx_cac_drop++; + hdd_ipa_rm_try_release(hdd_ipa); return; } @@ -1647,6 +1676,15 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, adf_os_spin_unlock_bh(&iface_context->interface_lock); + skb = ipa_tx_desc->skb; + + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); + NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID; + NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb; + NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dma_addr; + + NBUF_OWNER_PRIV_DATA(skb) = (unsigned long)ipa_tx_desc; + skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, iface_context->tl_context, ipa_tx_desc->skb, interface_id); @@ -1654,11 +1692,82 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "TLSHIM tx fail"); ipa_free_skb(ipa_tx_desc); iface_context->stats.num_tx_err++; + hdd_ipa_rm_try_release(hdd_ipa); return; } atomic_inc(&hdd_ipa->tx_ref_cnt); + iface_context->stats.num_tx++; + +} + +static void hdd_ipa_pm_send_pkt_to_tl(struct work_struct *work) +{ + struct hdd_ipa_priv *hdd_ipa = container_of(work, + struct hdd_ipa_priv, pm_work); + struct hdd_ipa_pm_tx_cb *pm_tx_cb = NULL; + adf_nbuf_t skb; + uint32_t dequeued = 0; + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + + while (((skb = adf_nbuf_queue_remove(&hdd_ipa->pm_queue_head)) != + NULL)) { + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + pm_tx_cb = (struct hdd_ipa_pm_tx_cb *)skb->cb; + + dequeued++; + + hdd_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, + pm_tx_cb->ipa_tx_desc); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + } + + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + hdd_ipa->stats.num_tx_dequeued += dequeued; + if (dequeued > hdd_ipa->stats.num_max_pm_queue) + hdd_ipa->stats.num_max_pm_queue = dequeued; +} + +static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, + unsigned long data) +{ + struct hdd_ipa_priv *hdd_ipa = NULL; + struct ipa_rx_data *ipa_tx_desc; + struct hdd_ipa_iface_context *iface_context; + adf_nbuf_t skb; + struct hdd_ipa_pm_tx_cb *pm_tx_cb = NULL; + + if (evt != IPA_RECEIVE) { + skb = (adf_nbuf_t) data; + dev_kfree_skb_any(skb); + iface_context->stats.num_tx_drop++; + return; + } + + iface_context = (struct hdd_ipa_iface_context *) priv; + ipa_tx_desc = (struct ipa_rx_data *)data; + + hdd_ipa = iface_context->hdd_ipa; + + /* + * When SSR is going on, just drop the packets. There is no use in + * queueing the packets as STA has to connect back any way + */ + if (hdd_ipa->hdd_ctx->isLogpInProgress) { + ipa_free_skb(ipa_tx_desc); + iface_context->stats.num_tx_drop++; + return; + } + + skb = ipa_tx_desc->skb; + + HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "i2w", skb->data, 8); + /* * If PROD resource is not requested here then there may be cases where * IPA hardware may be clocked down because of not having proper @@ -1668,7 +1777,82 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, */ hdd_ipa_rm_request(hdd_ipa); - iface_context->stats.num_tx++; + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + /* + * If host is still suspended then queue the packets and these will be + * drained later when resume completes. When packet is arrived here and + * host is suspended, this means that there is already resume is in + * progress. + */ + if (hdd_ipa->suspended) { + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); + pm_tx_cb = (struct hdd_ipa_pm_tx_cb *)skb->cb; + pm_tx_cb->iface_context = iface_context; + pm_tx_cb->ipa_tx_desc = ipa_tx_desc; + adf_nbuf_queue_add(&hdd_ipa->pm_queue_head, skb); + hdd_ipa->stats.num_tx_queued++; + + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + return; + } + + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + /* + * If we are here means, host is not suspended, wait for the work queue + * to finish. + */ + flush_work(&hdd_ipa->pm_work); + + return hdd_ipa_send_pkt_to_tl(iface_context, ipa_tx_desc); +} + +int hdd_ipa_suspend(hdd_context_t *hdd_ctx) +{ + struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; + + if (!hdd_ipa_is_enabled(hdd_ctx)) + return 0; + + /* + * Check if IPA is ready for suspend, If we are here means, there is + * high chance that suspend would go through but just to avoid any race + * condition after suspend started, these checks are conducted before + * allowing to suspend. + */ + if (atomic_read(&hdd_ipa->tx_ref_cnt)) + return -EAGAIN; + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + + if (hdd_ipa->rm_state != HDD_IPA_RM_RELEASED) { + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + return -EAGAIN; + } + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + hdd_ipa->suspended = true; + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + return 0; +} + +int hdd_ipa_resume(hdd_context_t *hdd_ctx) +{ + struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; + + if (!hdd_ipa_is_enabled(hdd_ctx)) + return 0; + + schedule_work(&hdd_ipa->pm_work); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + hdd_ipa->suspended = false; + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + return 0; } static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) @@ -2302,6 +2486,15 @@ static void hdd_ipa_rx_pipe_desc_free(void) max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO; spin_lock_bh(&hdd_ipa->q_lock); + + list_for_each_entry_safe(desc, tmp, &hdd_ipa->pend_desc_head, link) { + list_del(&desc->link); + adf_nbuf_free(desc->priv); + spin_unlock_bh(&hdd_ipa->q_lock); + hdd_ipa_free_data_desc(hdd_ipa, desc); + spin_lock_bh(&hdd_ipa->q_lock); + } + list_for_each_entry_safe(desc, tmp, &hdd_ipa->free_desc_head, link) { list_del(&desc->link); spin_unlock_bh(&hdd_ipa->q_lock); @@ -2416,6 +2609,9 @@ static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file, len += scnprintf(buf + len, buf_len - len, "%30s: %s\n", "rm_state", hdd_ipa_rm_state_to_str(hdd_ipa->rm_state)); + len += scnprintf(buf + len, buf_len - len, "%30s: %s\n", "wake_lock", + hdd_ipa->wake_lock_released ? "RELEASED" : "ACQUIRED"); + len += scnprintf(buf + len, buf_len - len, "%30s: %d\n", "tx_ref_cnt", atomic_read(&hdd_ipa->tx_ref_cnt)); @@ -2460,6 +2656,12 @@ skip: len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_tx_comp_cnt); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_tx_queued); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_tx_dequeued); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_max_pm_queue); len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_freeq_empty); @@ -2610,6 +2812,10 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) adf_os_spinlock_init(&iface_context->interface_lock); } + INIT_WORK(&hdd_ipa->pm_work, hdd_ipa_pm_send_pkt_to_tl); + adf_os_spinlock_init(&hdd_ipa->pm_lock); + adf_nbuf_queue_init(&hdd_ipa->pm_queue_head); + ret = hdd_ipa_setup_rm(hdd_ipa); if (ret) goto fail_setup_rm; @@ -2659,10 +2865,29 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx) struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; int i; struct hdd_ipa_iface_context *iface_context = NULL; + adf_nbuf_t skb; + struct hdd_ipa_pm_tx_cb *pm_tx_cb = NULL; if (!hdd_ipa_is_enabled(hdd_ctx)) return VOS_STATUS_SUCCESS; + cancel_work_sync(&hdd_ipa->pm_work); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + + while (((skb = adf_nbuf_queue_remove(&hdd_ipa->pm_queue_head)) != + NULL)) { + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + pm_tx_cb = (struct hdd_ipa_pm_tx_cb *)skb->cb; + ipa_free_skb(pm_tx_cb->ipa_tx_desc); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + } + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + adf_os_spinlock_destroy(&hdd_ipa->pm_lock); + /* destory the interface lock */ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { iface_context = &hdd_ipa->iface_context[i]; -- cgit v1.2.3 From eda491d5a011fccc7f4e74e65e14f1511a399b8a Mon Sep 17 00:00:00 2001 From: Akash Patel Date: Fri, 1 Aug 2014 18:19:41 -0700 Subject: Cafstaging Release 1.0.0.160 Cafstaging Release 1.0.0.160 Change-Id: Icf98b3df54b29b93d0ec7eafea6bad903b097e25 CRs-Fixed: 688141 --- CORE/MAC/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 1b1e13c45599..2c43c23702f3 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 0 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 159 +#define QWLAN_VERSION_BUILD 160 -#define QWLAN_VERSIONSTR "1.0.0.159" +#define QWLAN_VERSIONSTR "1.0.0.160" #ifdef QCA_WIFI_2_0 -- cgit v1.2.3