summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2014-08-03 18:07:36 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2014-08-03 18:07:36 -0700
commitba67e6419efd7298ec71bfcdbecde8ed2fb43fc1 (patch)
tree7bbe4a63354b4cd65888823068d187f164c8a732
parenteb9913565b6c155033afadbaf152ef0fb3297a67 (diff)
parent30257a0adb9749ac18e28eea8e60345070f62570 (diff)
Merge "Release 1.0.0.160 QCACLD WLAN Driver"
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c14
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h6
-rw-r--r--CORE/HDD/inc/wlan_hdd_ipa.h3
-rw-r--r--CORE/HDD/src/bap_hdd_main.c6
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c79
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c15
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c29
-rw-r--r--CORE/HDD/src/wlan_hdd_early_suspend.c9
-rw-r--r--CORE/HDD/src/wlan_hdd_ipa.c318
-rwxr-xr-xCORE/HDD/src/wlan_hdd_main.c52
-rw-r--r--CORE/HDD/src/wlan_hdd_tdls.c43
-rw-r--r--CORE/HDD/src/wlan_hdd_wmm.c6
-rw-r--r--CORE/MAC/inc/qwlan_version.h4
-rw-r--r--CORE/MAC/inc/wniApi.h10
-rw-r--r--CORE/MAC/inc/wniCfgAp.h15
-rw-r--r--CORE/MAC/inc/wniCfgSta.h9
-rw-r--r--CORE/MAC/src/cfg/cfgParamName.c1
-rw-r--r--CORE/MAC/src/cfg/cfgUtil/cfg.txt8
-rw-r--r--CORE/MAC/src/pe/lim/limAssocUtils.c8
-rw-r--r--CORE/MAC/src/pe/lim/limProcessTdls.c283
-rw-r--r--CORE/MAC/src/pe/lim/limPropExtsUtils.c15
-rw-r--r--CORE/MAC/src/pe/lim/limUtils.h17
-rw-r--r--CORE/SAP/src/sapChSelect.c5
-rw-r--r--CORE/SERVICES/BMI/ol_fw.c23
-rw-r--r--CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h12
-rw-r--r--CORE/SERVICES/COMMON/dbglog_id.h4
-rw-r--r--CORE/SERVICES/COMMON/wmi_unified_api.h6
-rw-r--r--CORE/SERVICES/WMA/wma.c68
-rw-r--r--CORE/SERVICES/WMA/wma.h4
-rw-r--r--CORE/SERVICES/WMI/wmi_unified.c9
-rw-r--r--CORE/SERVICES/WMI/wmi_unified_priv.h1
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c4
-rw-r--r--CORE/SME/src/csr/csrTdlsProcess.c3
-rw-r--r--[-rwxr-xr-x]firmware_bin/WCNSS_cfg.datbin10842 -> 10874 bytes
-rwxr-xr-xfirmware_bin/WCNSS_qcom_cfg.ini15
35 files changed, 989 insertions, 115 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/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/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/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_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 0e0cdaba3f2e..78e66fbb1d25 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,
@@ -2584,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,
@@ -2694,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) &&
@@ -2726,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);
@@ -2792,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)
{
@@ -2835,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);
}
@@ -2852,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)
{
@@ -2865,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;
}
@@ -2885,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)
{
@@ -2898,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;
}
@@ -3304,10 +3339,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");
@@ -3316,6 +3352,7 @@ eHalStatus hdd_smeRoamCallback( void *pContext, tCsrRoamInfo *pRoamInfo, tANI_U3
break;
}
#endif
+#endif
default:
break;
}
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/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index b85b584e6cb8..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 <wlan_hdd_ipa.h>
+#endif
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -3716,6 +3719,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;
@@ -3732,6 +3737,7 @@ int wlan_hdd_cfg80211_init(struct device *dev,
__func__,wiphy->key_mgmt_offload_support);
}
#endif
+#endif
EXIT();
return 0;
@@ -7246,6 +7252,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 +7289,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 +9755,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);
@@ -9769,6 +9778,7 @@ static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
}
}
#endif
+#endif
pHddCtx->isAmpAllowed = VOS_FALSE;
EXIT();
return status;
@@ -12379,7 +12389,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)
{
@@ -12426,11 +12436,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;
@@ -13627,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);
@@ -14836,7 +14857,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
};
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 <wlan_hdd_cfg.h>
#include <wlan_hdd_cfg80211.h>
#include <net/addrconf.h>
+#ifdef IPA_OFFLOAD
+#include <wlan_hdd_ipa.h>
+#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 ad77e11536b0..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;
}
@@ -1096,8 +1150,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;
@@ -1146,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;
@@ -1172,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);
@@ -1575,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;
@@ -1624,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;
}
@@ -1635,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;
}
@@ -1644,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);
@@ -1651,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
@@ -1665,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)
@@ -2299,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);
@@ -2413,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));
@@ -2457,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);
@@ -2607,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;
@@ -2656,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];
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 661bb685e9f2..ba11a3ded6ee 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:
@@ -11274,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();
@@ -11646,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);
@@ -13261,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/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 43875a95af4a..6d2551035c66 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
@@ -1769,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);
}
@@ -2078,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)
{
@@ -2103,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
@@ -2157,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)
{
@@ -2174,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);
@@ -2190,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;
}
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/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
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/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/limProcessTdls.c b/CORE/MAC/src/pe/lim/limProcessTdls.c
index 210c69292bbd..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..
@@ -4955,6 +5029,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;
+ tANI_U8 op_class;
if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
validChan, &numChans) != eSIR_SUCCESS)
{
@@ -4965,14 +5041,51 @@ 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 ;
+ /*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 ;
}
/*
@@ -5625,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/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/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/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++)
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) {
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 <linux/version.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
-
+#ifdef CONFIG_CNSS
+#include <net/cnss.h>
+#endif
#include <adf_os_types.h>
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/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
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 2025bc3d5802..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,
@@ -4681,6 +4708,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 +4762,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 +4914,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 +16365,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 +16388,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,
@@ -16356,6 +16408,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;
}
@@ -18092,8 +18145,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 +21595,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;
@@ -22869,6 +22932,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..de908f578488 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -77,10 +77,11 @@
/** 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
+#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 e2d48f27f7ea..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);
@@ -961,11 +961,16 @@ 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
+ wmi_handle->wma_wow_tx_complete_cbk = func;
return wmi_handle;
}
@@ -1009,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
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,
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",
diff --git a/firmware_bin/WCNSS_cfg.dat b/firmware_bin/WCNSS_cfg.dat
index 066840f1dee7..f9b4fd875c4a 100755..100644
--- a/firmware_bin/WCNSS_cfg.dat
+++ b/firmware_bin/WCNSS_cfg.dat
Binary files differ
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