summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKiran Kumar Lokere <klokere@qca.qualcomm.com>2015-06-18 13:57:30 -0700
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2015-07-15 17:32:40 +0530
commita39a27df8bf5c94807fc88fe98a6e33ac3f3fd34 (patch)
tree4c7289567efe281cad821c2c1706e6ad48bfdd25
parent1689e26ad6927dd1dcde58e67904af3d899ec504 (diff)
qcacld-2.0: Add support for NSS configurability
Add support for chain mask and NSS configurability per vdev type. - Configure the 2g and 5g chain mask to FW based on INI and FW chain mask value. - Configure the 2g and 5g Nss with the INI value of each vdev type - Program the HT and VHT IE to FW for 1x1 and 2x2 mode, FW will included them in scan probe request frames. Change-Id: I5cbf17a14ab6becad6cf5765ae5039fc284dc309 CRs-Fixed: 869026
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h42
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h6
-rw-r--r--CORE/HDD/inc/wlan_hdd_tgt_cfg.h5
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c85
-rwxr-xr-xCORE/HDD/src/wlan_hdd_main.c132
-rw-r--r--CORE/MAC/inc/aniGlobal.h50
-rw-r--r--CORE/MAC/inc/sirApi.h24
-rw-r--r--CORE/MAC/inc/sirMacProtDef.h8
-rw-r--r--CORE/MAC/inc/wniApi.h1
-rw-r--r--CORE/MAC/src/include/sirParams.h1
-rw-r--r--CORE/MAC/src/pe/include/limSession.h1
-rw-r--r--CORE/MAC/src/pe/lim/limAssocUtils.c44
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMessageQueue.c1
-rw-r--r--CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c293
-rw-r--r--CORE/SERVICES/WMA/wma.c225
-rw-r--r--CORE/SERVICES/WMA/wma.h6
-rw-r--r--CORE/SME/inc/sme_Api.h9
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c73
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c195
-rw-r--r--CORE/SYS/legacy/src/utils/src/parserApi.c36
-rw-r--r--CORE/WDA/inc/legacy/halMsgApi.h25
-rw-r--r--CORE/WDA/inc/wlan_qct_wda.h1
22 files changed, 1114 insertions, 149 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 17da3bcb6582..2172a42bbc1b 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -1244,6 +1244,42 @@ typedef enum
#define CFG_VHT_ENABLE_2x2_CAP_FEATURE_MAX ( 1 )
#define CFG_VHT_ENABLE_2x2_CAP_FEATURE_DEFAULT ( 0 )
+/*
+ * Valid chain mask values.
+ * 01 - enables chain0
+ * 02 - enables chain1
+ * 03 - enables both chain 0 and chain 1
+ */
+#define CFG_CHAIN_MASK_2G "gChainMask_2g"
+#define CFG_CHAIN_MASK_2G_MIN ( 1 )
+#define CFG_CHAIN_MASK_2G_MAX ( 3 )
+#define CFG_CHAIN_MASK_2G_DEFAULT ( 3 )
+
+#define CFG_CHAIN_MASK_5G "gChainMask_5g"
+#define CFG_CHAIN_MASK_5G_MIN ( 1 )
+#define CFG_CHAIN_MASK_5G_MAX ( 3 )
+#define CFG_CHAIN_MASK_5G_DEFAULT ( 3 )
+/*
+ * NSS cfg bit definition.
+ * STA BIT[0:1]
+ * SAP BIT[2:3]
+ * P2P_GO BIT[4:5]
+ * P2P_CLIENT BIT[6:7]
+ * IBSS BIT[8:9]
+ * TDLS BIT[10:11]
+ * P2P_DEVICE BIT[12:13]
+ * OCB BIT[14:15]
+ */
+#define CFG_VDEV_TYPE_NSS_2G "gVdevTypeNss_2g"
+#define CFG_VDEV_TYPE_NSS_2G_MIN ( 0x5555 )
+#define CFG_VDEV_TYPE_NSS_2G_MAX ( 0xAAAA )
+#define CFG_VDEV_TYPE_NSS_2G_DEFAULT ( 0xAAAA )
+
+#define CFG_VDEV_TYPE_NSS_5G "gVdevTypeNss_5g"
+#define CFG_VDEV_TYPE_NSS_5G_MIN ( 0x5555 )
+#define CFG_VDEV_TYPE_NSS_5G_MAX ( 0xAAAA )
+#define CFG_VDEV_TYPE_NSS_5G_DEFAULT ( 0xAAAA )
+
#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE "gEnableMuBformee"
#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MIN ( 0 )
#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MAX ( 1 )
@@ -3325,7 +3361,6 @@ typedef struct
uint32_t bad_peer_tput_ieee80211ac;
uint32_t bad_peer_limit_ieee80211ac;
#endif
-#ifdef WLAN_FEATURE_11AC
v_U8_t vhtChannelWidth;
v_U8_t vhtRxMCS;
v_U8_t vhtTxMCS;
@@ -3334,13 +3369,16 @@ typedef struct
v_U8_t vhtRxMCS2x2;
v_U8_t vhtTxMCS2x2;
v_BOOL_t enable2x2;
+ uint8_t chain_mask_2g;
+ uint8_t chain_mask_5g;
+ uint32_t vdev_type_nss_2g;
+ uint32_t vdev_type_nss_5g;
v_BOOL_t txchainmask1x1;
v_BOOL_t rxchainmask1x1;
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;
v_U8_t htSmps;
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 9304a2d642ec..6988268fa182 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -310,11 +310,6 @@ extern spinlock_t hdd_context_lock;
#define WLAN_HDD_TX_FLOW_CONTROL_MAX_24BAND_CH 14
#endif /* QCA_LL_TX_FLOW_CT */
-#define HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1 390
-#define HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1 390
-#define HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2 780
-#define HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2 780
-
typedef struct hdd_tx_rx_stats_s
{
// start_xmit stats
@@ -1558,6 +1553,7 @@ struct hdd_context_s
#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
struct hdd_offloaded_packets_ctx op_ctx;
#endif
+ bool per_band_chainmask_supp;
};
/*---------------------------------------------------------------------------
diff --git a/CORE/HDD/inc/wlan_hdd_tgt_cfg.h b/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
index a7d626e3abca..7fe2aa6c5e2c 100644
--- a/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -43,6 +43,9 @@ struct hdd_tgt_services {
#endif
v_BOOL_t beacon_offload;
u_int32_t lte_coex_ant_share;
+ uint8_t chain_mask_2g;
+ uint8_t chain_mask_5g;
+ bool per_band_chainmask_supp;
#ifdef FEATURE_WLAN_TDLS
v_BOOL_t en_tdls;
v_BOOL_t en_tdls_offchan;
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index fca06d803347..50d8ba7dd860 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -2174,6 +2174,34 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_VHT_ENABLE_2x2_CAP_FEATURE_MIN,
CFG_VHT_ENABLE_2x2_CAP_FEATURE_MAX ),
+ REG_VARIABLE( CFG_CHAIN_MASK_2G, WLAN_PARAM_Integer,
+ hdd_config_t, chain_mask_2g,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_CHAIN_MASK_2G_DEFAULT,
+ CFG_CHAIN_MASK_2G_MIN,
+ CFG_CHAIN_MASK_2G_MAX ),
+
+ REG_VARIABLE( CFG_CHAIN_MASK_5G, WLAN_PARAM_Integer,
+ hdd_config_t, chain_mask_5g,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_CHAIN_MASK_5G_DEFAULT,
+ CFG_CHAIN_MASK_5G_MIN,
+ CFG_CHAIN_MASK_5G_MAX ),
+
+ REG_VARIABLE( CFG_VDEV_TYPE_NSS_2G, WLAN_PARAM_Integer,
+ hdd_config_t, vdev_type_nss_2g,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_VDEV_TYPE_NSS_2G_DEFAULT,
+ CFG_VDEV_TYPE_NSS_2G_MIN,
+ CFG_VDEV_TYPE_NSS_2G_MAX ),
+
+ REG_VARIABLE( CFG_VDEV_TYPE_NSS_5G, WLAN_PARAM_Integer,
+ hdd_config_t, vdev_type_nss_5g,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_VDEV_TYPE_NSS_5G_DEFAULT,
+ CFG_VDEV_TYPE_NSS_5G_MIN,
+ CFG_VDEV_TYPE_NSS_5G_MAX ),
+
REG_VARIABLE( CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE, WLAN_PARAM_Integer,
hdd_config_t, enableMuBformee,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -5755,51 +5783,6 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
(pConfig->dot11Mode == eHDD_DOT11_MODE_11ac) )
{
{
- tANI_U32 temp = 0;
-
- ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp);
- temp = (temp & 0xFFFC) | pConfig->vhtRxMCS;
-
- if (pConfig->enable2x2)
- temp = (temp & 0xFFF3) | (pConfig->vhtRxMCS2x2 << 2);
-
- if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_BASIC_MCS_SET,
- temp, NULL, eANI_BOOLEAN_FALSE)
- ==eHAL_STATUS_FAILURE)
- {
- fStatus = FALSE;
- hddLog(LOGE, "Could not pass on WNI_CFG_VHT_BASIC_MCS_SET to CCM");
- }
-
- ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp);
- temp = (temp & 0xFFFC) | pConfig->vhtRxMCS;
- if (pConfig->enable2x2)
- temp = (temp & 0xFFF3) | (pConfig->vhtRxMCS2x2 << 2);
-
- if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_RX_MCS_MAP,
- temp, NULL, eANI_BOOLEAN_FALSE)
- ==eHAL_STATUS_FAILURE)
- {
- fStatus = FALSE;
- hddLog(LOGE, "Could not pass on WNI_CFG_VHT_RX_MCS_MAP to CCM");
- }
-
- ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp);
- temp = (temp & 0xFFFC) | pConfig->vhtTxMCS;
- if (pConfig->enable2x2)
- temp = (temp & 0xFFF3) | (pConfig->vhtTxMCS2x2 << 2);
-
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
- "vhtRxMCS2x2 - %x temp - %u enable2x2 %d",
- pConfig->vhtRxMCS2x2, temp, pConfig->enable2x2);
-
- if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP,
- temp, NULL, eANI_BOOLEAN_FALSE)
- ==eHAL_STATUS_FAILURE)
- {
- fStatus = FALSE;
- hddLog(LOGE, "Could not pass on WNI_CFG_VHT_TX_MCS_MAP to CCM");
- }
/* Currently shortGI40Mhz is used for shortGI80Mhz */
if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ,
pConfig->ShortGI40MhzEnable, NULL, eANI_BOOLEAN_FALSE)
@@ -5822,9 +5805,9 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
if (pConfig->enableTxBF)
{
ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
- &temp);
+ &val);
- if(temp != pConfig->enableMuBformee)
+ if(val != pConfig->enableMuBformee)
{
if(ccmCfgSetInt(pHddCtx->hHal,
WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
@@ -6756,12 +6739,12 @@ VOS_STATUS hdd_update_nss(hdd_context_t *hdd_ctx, uint8_t nss)
if (!hdd_config->enable2x2) {
/* 1x1 */
- rx_supp_data_rate = HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
- tx_supp_data_rate = HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+ rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+ tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
} else {
/* 2x2 */
- rx_supp_data_rate = HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
- tx_supp_data_rate = HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
+ rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
+ tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
}
/* Update Rx Highest Long GI data Rate */
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 6792b3b9f44f..a770dc25dc8b 100755
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -6281,7 +6281,6 @@ static void hdd_update_tgt_services(hdd_context_t *hdd_ctx,
struct hdd_tgt_services *cfg)
{
hdd_config_t *cfg_ini = hdd_ctx->cfg_ini;
- tpAniSirGlobal pMac = PMAC_STRUCT(hdd_ctx->hHal);
/* Set up UAPSD */
cfg_ini->apUapsdEnabled &= cfg->uapsd;
@@ -6304,7 +6303,11 @@ static void hdd_update_tgt_services(hdd_context_t *hdd_ctx,
if (cfg->pno_offload)
cfg_ini->PnoOffload = TRUE;
#endif
- pMac->lteCoexAntShare = cfg->lte_coex_ant_share;
+ sme_set_lte_coex_supp(hdd_ctx->hHal,
+ cfg->lte_coex_ant_share);
+ hdd_ctx->per_band_chainmask_supp = cfg->per_band_chainmask_supp;
+ sme_set_per_band_chainmask_supp(hdd_ctx->hHal,
+ cfg->per_band_chainmask_supp);
#ifdef FEATURE_WLAN_TDLS
cfg_ini->fEnableTDLSSupport &= cfg->en_tdls;
cfg_ini->fEnableTDLSOffChannel &= cfg->en_tdls_offchan;
@@ -6318,7 +6321,7 @@ static void hdd_update_tgt_services(hdd_context_t *hdd_ctx,
cfg_ini->fEnableTDLSSleepSta = FALSE;
}
#endif
- pMac->beacon_offload = cfg->beacon_offload;
+ sme_set_bcon_offload_supp(hdd_ctx->hHal, cfg->beacon_offload);
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
cfg_ini->isRoamOffloadEnabled &= cfg->en_roam_offload;
#endif
@@ -6326,7 +6329,81 @@ static void hdd_update_tgt_services(hdd_context_t *hdd_ctx,
#ifdef SAP_AUTH_OFFLOAD
cfg_ini->enable_sap_auth_offload &= cfg->sap_auth_offload_service;
#endif
+}
+
+/**
+ * hdd_update_chain_mask_vdev_nss() - sets the chain mask and vdev nss
+ * @hdd_ctx: HDD context
+ * @cfg: Pointer to target services.
+ *
+ * Sets the chain masks for 2G and 5G bands based on target supported
+ * values and INI values. And sets the Nss per vdev type based on INI
+ * and configured chain mask value.
+ *
+ * Return: None
+ */
+static void hdd_update_chain_mask_vdev_nss(hdd_context_t *hdd_ctx,
+ struct hdd_tgt_services *cfg)
+{
+ hdd_config_t *cfg_ini = hdd_ctx->cfg_ini;
+ uint8_t chain_mask, ret;
+ uint8_t max_supp_nss = 1;
+ cfg_ini->enable2x2 = 0;
+ chain_mask = cfg->chain_mask_2g & cfg_ini->chain_mask_2g;
+ if (!chain_mask)
+ chain_mask = cfg->chain_mask_2g;
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ "%s: set 2G chain mask value %d",
+ __func__, chain_mask);
+ ret = process_wma_set_command(0, WMI_PDEV_PARAM_RX_CHAIN_MASK_2G,
+ chain_mask, PDEV_CMD);
+ if (0 != ret) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: set WMI_PDEV_PARAM_RX_CHAIN_MASK_2G failed %d",
+ __func__, ret);
+ }
+ ret = process_wma_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_2G,
+ chain_mask, PDEV_CMD);
+ if (0 != ret) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: WMI_PDEV_PARAM_TX_CHAIN_MASK_2G set failed %d",
+ __func__, ret);
+ }
+ max_supp_nss += ((chain_mask & 0x3) == 0x3);
+
+ if (max_supp_nss == 2)
+ cfg_ini->enable2x2 = 1;
+ sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
+ cfg_ini->vdev_type_nss_2g, eCSR_BAND_24);
+
+ max_supp_nss = 1;
+ chain_mask = cfg->chain_mask_5g & cfg_ini->chain_mask_5g;
+ if (!chain_mask)
+ chain_mask = cfg->chain_mask_5g;
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ "%s: set 5G chain mask value %d",
+ __func__, chain_mask);
+ ret = process_wma_set_command(0, WMI_PDEV_PARAM_RX_CHAIN_MASK_5G,
+ chain_mask, PDEV_CMD);
+ if (0 != ret) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: set WMI_PDEV_PARAM_RX_CHAIN_MASK_5G failed %d",
+ __func__, ret);
+ }
+ ret = process_wma_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_5G,
+ chain_mask, PDEV_CMD);
+ if (0 != ret) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: WMI_PDEV_PARAM_TX_CHAIN_MASK_5G set failed %d",
+ __func__, ret);
+ }
+ max_supp_nss += ((chain_mask & 0x3) == 0x3);
+
+ if (max_supp_nss == 2)
+ cfg_ini->enable2x2 = 1;
+ sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
+ cfg_ini->vdev_type_nss_5g, eCSR_BAND_5G);
}
static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx,
@@ -6396,7 +6473,8 @@ static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx,
enable_tx_stbc = pconfig->enableTxSTBC;
- if (pconfig->enable2x2 && (cfg->num_rf_chains == 2))
+ if (pconfig->enable2x2 && (hdd_ctx->per_band_chainmask_supp ||
+ (!hdd_ctx->per_band_chainmask_supp && (cfg->num_rf_chains == 2))))
{
pconfig->enable2x2 = 1;
}
@@ -6409,7 +6487,7 @@ static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx,
/* Update Rx Highest Long GI data Rate */
if (ccmCfgSetInt(hdd_ctx->hHal,
WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
- HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1, NULL,
+ VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1, NULL,
eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
{
hddLog(LOGE, "Could not pass on "
@@ -6418,7 +6496,7 @@ static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx,
/* Update Tx Highest Long GI data Rate */
if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
- HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1, NULL,
+ VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1, NULL,
eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
{
hddLog(LOGE, "Could not pass on "
@@ -6446,7 +6524,7 @@ static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx,
if (pconfig->enable2x2)
{
- for (value = 0; value < cfg->num_rf_chains; value++)
+ for (value = 0; value < 2; value++)
mcs_set[value] = WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
status = ccmCfgSetStr(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET,
@@ -6467,6 +6545,7 @@ static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx,
eHalStatus status;
tANI_U32 value = 0;
hdd_config_t *pconfig = hdd_ctx->cfg_ini;
+ tANI_U32 temp = 0;
/* Get the current MPDU length */
status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH, &value);
@@ -6534,6 +6613,40 @@ static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx,
}
}
+ ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp);
+ temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
+
+ if (pconfig->enable2x2)
+ temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
+
+ if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, temp, NULL,
+ eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) {
+ hddLog(LOGE, "Could not pass on WNI_CFG_VHT_BASIC_MCS_SET to CCM");
+ }
+
+ ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp);
+ temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
+ if (pconfig->enable2x2)
+ temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
+
+ if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, temp, NULL,
+ eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) {
+ hddLog(LOGE, "Could not pass on WNI_CFG_VHT_RX_MCS_MAP to CCM");
+ }
+
+ ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp);
+ temp = (temp & VHT_MCS_1x1) | pconfig->vhtTxMCS;
+ if (pconfig->enable2x2)
+ temp = (temp & VHT_MCS_2x2) | (pconfig->vhtTxMCS2x2 << 2);
+
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "vhtRxMCS2x2 - %x temp - %u enable2x2 %d",
+ pconfig->vhtRxMCS2x2, temp, pconfig->enable2x2);
+
+ if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, temp, NULL,
+ eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) {
+ hddLog(LOGE, "Could not pass on WNI_CFG_VHT_TX_MCS_MAP to CCM");
+ }
/* Get the current RX LDPC setting */
status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP, &value);
@@ -6853,6 +6966,10 @@ void hdd_update_tgt_cfg(void *context, void *param)
hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
hdd_update_tgt_services(hdd_ctx, &cfg->services);
+ if (hdd_ctx->per_band_chainmask_supp)
+ hdd_update_chain_mask_vdev_nss(hdd_ctx, &cfg->services);
+ else
+ sme_set_vdev_nss(hdd_ctx->hHal, hdd_ctx->cfg_ini->enable2x2);
hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
@@ -7860,6 +7977,7 @@ VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
INIT_COMPLETION(pAdapter->session_open_comp_var);
sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
+ sme_set_pdev_ht_vht_ies(pHddCtx->hHal, pHddCtx->cfg_ini->enable2x2);
status = vos_get_vdev_types(pAdapter->device_mode, &type, &subType);
if (VOS_STATUS_SUCCESS != status)
{
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index ff945e993fcd..6a2465fc263a 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -142,6 +142,27 @@ typedef struct sAniSirGlobal *tpAniSirGlobal;
#define HIGH_SEQ_NUM_MASK 0x0FF0
#define HIGH_SEQ_NUM_OFFSET 4
+/*
+ * NSS cfg bit definition.
+ * STA BIT[0:1]
+ * SAP BIT[2:3]
+ * P2P_GO BIT[4:5]
+ * P2P_CLIENT BIT[6:7]
+ * IBSS BIT[8:9]
+ * TDLS BIT[10:11]
+ * P2P_DEVICE BIT[12:13]
+ * OCB BIT[14:15]
+ */
+
+#define CFG_STA_NSS(_x) ((((_x) >> 0) & 0x3) ? (((_x) >> 0) & 0x3) : 1)
+#define CFG_SAP_NSS(_x) ((((_x) >> 2) & 0x3) ? (((_x) >> 2) & 0x3) : 1)
+#define CFG_P2P_GO_NSS(_x) ((((_x) >> 4) & 0x3) ? (((_x) >> 4) & 0x3) : 1)
+#define CFG_P2P_CLI_NSS(_x) ((((_x) >> 6) & 0x3) ? (((_x) >> 6) & 0x3) : 1)
+#define CFG_P2P_DEV_NSS(_x) ((((_x) >> 8) & 0x3) ? (((_x) >> 8) & 0x3) : 1)
+#define CFG_IBSS_NSS(_x) ((((_x) >> 10) & 0x3) ? (((_x) >> 10) & 0x3) : 1)
+#define CFG_TDLS_NSS(_x) ((((_x) >> 12) & 0x3) ? (((_x) >> 12) & 0x3) : 1)
+#define CFG_OCB_NSS(_x) ((((_x) >> 14) & 0x3) ? (((_x) >> 14) & 0x3) : 1)
+
/**
* enum log_event_type - Type of event initiating bug report
* @WLAN_LOG_TYPE_NON_FATAL: Non fatal event
@@ -1091,10 +1112,33 @@ typedef struct sHalMacStartParameters
} tHalMacStartParameters;
+/**
+ * struct vdev_type_nss - vdev type nss structure
+ *
+ * @sta: STA Nss value.
+ * @sap: SAP Nss value.
+ * @p2p_go: P2P GO Nss value.
+ * @p2p_cli: P2P CLI Nss value.
+ * @p2p_dev: P2P device Nss value.
+ * @ibss: IBSS Nss value.
+ * @tdls: TDLS Nss value.
+ * @ocb: OCB Nss value.
+ *
+ * Holds the Nss values of different vdev types.
+ */
+struct vdev_type_nss {
+ uint8_t sta;
+ uint8_t sap;
+ uint8_t p2p_go;
+ uint8_t p2p_cli;
+ uint8_t p2p_dev;
+ uint8_t ibss;
+ uint8_t tdls;
+ uint8_t ocb;
+};
// -------------------------------------------------------------------
/// MAC Sirius parameter structure
typedef struct sAniSirGlobal
-
{
tDriverType gDriverType;
@@ -1179,6 +1223,10 @@ typedef struct sAniSirGlobal
uint32_t f_sta_miracast_mcc_rest_time_val;
uint8_t f_prefer_non_dfs_on_radar;
uint32_t fine_time_meas_cap;
+ /* per band chain mask support */
+ bool per_band_chainmask_supp;
+ struct vdev_type_nss vdev_type_nss_2g;
+ struct vdev_type_nss vdev_type_nss_5g;
} tAniSirGlobal;
typedef enum
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 22938e751701..86e43eb74622 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -3417,6 +3417,8 @@ typedef struct sSirSmeAddStaSelfReq
tANI_U32 subType;
tANI_U8 sessionId;
tANI_U16 pkt_err_disconn_th;
+ uint8_t nss_2g;
+ uint8_t nss_5g;
}tSirSmeAddStaSelfReq, *tpSirSmeAddStaSelfReq;
typedef struct sSirSmeDelStaSelfReq
@@ -4340,6 +4342,9 @@ typedef struct sSirUpdateChanParam
typedef struct sSirUpdateChan
{
tANI_U8 numChan;
+ uint8_t ht_en;
+ uint8_t vht_en;
+ uint8_t vht_24_en;
tSirUpdateChanParam chanParam[1];
} tSirUpdateChanList, *tpSirUpdateChanList;
@@ -5431,6 +5436,25 @@ struct sir_ipa_offload_enable_disable
uint32_t enable;
};
+/**
+ * struct sir_set_ht_vht_cfg - ht, vht IE config
+ *
+ * @msg_type: message type
+ * @len: message length
+ * @pdev_id: pdev id
+ * @nss: Nss value
+ * @dot11mode: Dot11 mode.
+ *
+ * Message wrapper structure for set HT/VHT IE req.
+ */
+struct sir_set_ht_vht_cfg {
+ uint16_t msg_type;
+ uint16_t len;
+ uint32_t pdev_id;
+ uint32_t nss;
+ uint32_t dot11mode;
+};
+
/*---------------------------------------------------------------------------
WLAN_HAL_LL_NOTIFY_STATS
---------------------------------------------------------------------------*/
diff --git a/CORE/MAC/inc/sirMacProtDef.h b/CORE/MAC/inc/sirMacProtDef.h
index 42e5373bcd20..2ec4ac5abaf6 100644
--- a/CORE/MAC/inc/sirMacProtDef.h
+++ b/CORE/MAC/inc/sirMacProtDef.h
@@ -384,6 +384,14 @@
#endif
#define SIR_MAC_MAX_SUPPORTED_MCS_SET 16
+#define VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1 390
+#define VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1 390
+#define VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2 780
+#define VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2 780
+
+#define VHT_MCS_1x1 0xFFFC
+#define VHT_MCS_2x2 0xFFF3
+
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
#define SIR_MAC_QCOM_VENDOR_EID 200
#define SIR_MAC_QCOM_VENDOR_OUI "\x00\xA0\xC6"
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index ac9d3e6fa365..d0bbf1cabfcd 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -394,6 +394,7 @@ enum eWniMsgTypes
eWNI_SME_TSF_EVENT,
eWNI_SME_FW_DUMP_IND,
+ eWNI_SME_PDEV_SET_HT_VHT_IE,
eWNI_SME_MSG_TYPES_END
};
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index ae30ba646bdb..6c7d0ddcece6 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -723,6 +723,7 @@ typedef struct sSirMbMsgP2p
#define SIR_HAL_BAD_PEER_TX_CTL_INI_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 332)
#define SIR_HAL_SET_RSSI_MONITOR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 333)
+#define SIR_HAL_SET_PDEV_IE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 334)
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h
index 88a2cf00dc6c..8d946c0357d8 100644
--- a/CORE/MAC/src/pe/include/limSession.h
+++ b/CORE/MAC/src/pe/include/limSession.h
@@ -493,6 +493,7 @@ typedef struct sPESession // Added to Support BT-AMP
#endif
/* flag to indicate country code in beacon */
tANI_U8 countryInfoPresent;
+ uint8_t vdev_nss;
} tPESession, *tpPESession;
/*-------------------------------------------------------------------------
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c
index 56cff5229b58..f853a413c14f 100644
--- a/CORE/MAC/src/pe/lim/limAssocUtils.c
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1561,28 +1561,27 @@ tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac,
pRates->vhtTxHighestDataRate = SIR_MIN(pRates->vhtTxHighestDataRate, pPeerVHTCaps->txSupDataRate);
pRates->vhtRxHighestDataRate = SIR_MIN(pRates->vhtRxHighestDataRate, pPeerVHTCaps->rxHighSupDataRate);
- if (pMac->roam.configParam.enable2x2)
- {
- if (psessionEntry)
- {
- if ((pMac->lteCoexAntShare) &&
- (IS_24G_CH(psessionEntry->currentOperChannel)))
- {
- if(IS_2X2_CHAIN(psessionEntry->chainMask))
+ if (!pMac->per_band_chainmask_supp) {
+ if (pMac->roam.configParam.enable2x2) {
+ if (psessionEntry) {
+ if ((pMac->lteCoexAntShare) && (IS_24G_CH(
+ psessionEntry->currentOperChannel))) {
+ if (IS_2X2_CHAIN(psessionEntry->chainMask))
+ mcsMapMask2x2 = MCSMAPMASK2x2;
+ else
+ limLog(pMac, LOGE,FL(
+ "2x2 not enabled %d"),
+ psessionEntry->chainMask);
+ } else {
mcsMapMask2x2 = MCSMAPMASK2x2;
- else
- PELOGE(limLog(pMac, LOGE, FL("2x2 not enabled %d"),
- psessionEntry->chainMask);)
- }
- else
- {
+ }
+ } else {
mcsMapMask2x2 = MCSMAPMASK2x2;
}
- }
- else
- {
+ }
+ } else {
+ if (psessionEntry->vdev_nss == 2)
mcsMapMask2x2 = MCSMAPMASK2x2;
- }
}
if ((pPeerVHTCaps->txMCSMap & mcsMapMask) < (pRates->vhtRxMCSMap & mcsMapMask)) {
@@ -1790,6 +1789,8 @@ limPopulateOwnRateSet(tpAniSirGlobal pMac,
goto error;
}
+ if (psessionEntry->vdev_nss == 1)
+ pRates->supportedMCSSet[1] = 0;
//if supported MCS Set of the peer is passed in, then do the intersection
//else use the MCS set from local CFG.
@@ -1947,6 +1948,9 @@ limPopulatePeerRateSet(tpAniSirGlobal pMac,
PELOGE(limLog(pMac, LOGE, FL("could not retrieve supportedMCSSet"));)
goto error;
}
+ if (psessionEntry->vdev_nss == 1)
+ pRates->supportedMCSSet[1] = 0;
+
//if supported MCS Set of the peer is passed in, then do the intersection
//else use the MCS set from local CFG.
if(pSupportedMCSSet != NULL)
@@ -2189,6 +2193,8 @@ limPopulateMatchingRateSet(tpAniSirGlobal pMac,
limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet"));
goto error;
}
+ if (psessionEntry->vdev_nss == 1)
+ mcsSet[1] = 0;
for(i=0; i<val; i++)
pStaDs->supportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i];
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index a9e18007fb3f..6e5dfb7f3dcd 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1366,6 +1366,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
}
}
break;
+ case eWNI_SME_PDEV_SET_HT_VHT_IE:
case eWNI_SME_START_REQ:
case eWNI_SME_SYS_READY_IND:
case eWNI_SME_JOIN_REQ:
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index 782815c44ecf..92261c80a17e 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -119,6 +119,11 @@ void __limProcessSmeAssocCnfNew(tpAniSirGlobal, tANI_U32, tANI_U32 *);
extern void peRegisterTLHandle(tpAniSirGlobal pMac);
+static void lim_process_set_pdev_IEs(tpAniSirGlobal pMac, tANI_U32 *msg_buf);
+static void lim_set_pdev_ht_ie(tpAniSirGlobal mac_ctx, tANI_U8 pdev_id,
+ tANI_U8 nss);
+static void lim_set_pdev_vht_ie(tpAniSirGlobal mac_ctx, tANI_U8 pdev_id,
+ tANI_U8 nss);
#ifdef BACKGROUND_SCAN_ENABLED
// start the background scan timers if it hasn't already started
@@ -543,6 +548,7 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
tpPESession psessionEntry = NULL;
tANI_U8 smesessionId;
tANI_U16 smetransactionId;
+ struct vdev_type_nss *vdev_type_nss;
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
//Since the session is not created yet, sending NULL. The response should have the correct state.
@@ -687,6 +693,10 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
(void*)&pSmeStartBssReq->extendedRateSet,
sizeof(tSirMacRateSet));
+ if (IS_5G_CH(psessionEntry->currentOperChannel))
+ vdev_type_nss = &pMac->vdev_type_nss_5g;
+ else
+ vdev_type_nss = &pMac->vdev_type_nss_2g;
switch(pSmeStartBssReq->bssType)
{
case eSIR_INFRA_AP_MODE:
@@ -701,6 +711,7 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
if (psessionEntry->pePersona == VOS_P2P_GO_MODE)
{
psessionEntry->proxyProbeRspEn = 0;
+ psessionEntry->vdev_nss = vdev_type_nss->p2p_go;
}
else
{
@@ -715,6 +726,7 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
psessionEntry->proxyProbeRspEn = 0;
}
+ psessionEntry->vdev_nss = vdev_type_nss->sap;
}
psessionEntry->ssidHidden = pSmeStartBssReq->ssidHidden;
psessionEntry->wps_state = pSmeStartBssReq->wps_state;
@@ -733,7 +745,7 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
// initialize to "OPEN". will be updated upon key installation
psessionEntry->encryptType = eSIR_ED_NONE;
-
+ psessionEntry->vdev_nss = vdev_type_nss->ibss;
break;
case eSIR_BTAMP_AP_MODE:
@@ -753,7 +765,8 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
//not used anywhere...used in scan function
break;
}
-
+ limLog(pMac, LOG1, FL("persona - %d, nss - %d"),
+ psessionEntry->pePersona, psessionEntry->vdev_nss);
// BT-AMP: Allocate memory for the array of parsed (Re)Assoc request structure
if ( (pSmeStartBssReq->bssType == eSIR_BTAMP_AP_MODE)
|| (pSmeStartBssReq->bssType == eSIR_INFRA_AP_MODE)
@@ -1152,26 +1165,29 @@ static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac,
len = sizeof(tSirScanOffloadReq) + (pScanReq->channelList.numChannels - 1) +
pScanReq->uIEFieldLen;
- if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
- limLog(pMac, LOG1,
- FL("Adding HT Caps IE since dot11mode=%d"), pScanReq->dot11mode);
- ht_cap_len = 2 + sizeof(tHtCaps); /* 2 bytes for EID and Length */
- len += ht_cap_len;
- addn_ie_len += ht_cap_len;
- }
+ if (!pMac->per_band_chainmask_supp) {
+ if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
+ limLog(pMac, LOG1,
+ FL("Adding HT Caps IE since dot11mode=%d"),
+ pScanReq->dot11mode);
+ ht_cap_len = 2 + sizeof(tHtCaps); /* 2 bytes for EID and Length */
+ len += ht_cap_len;
+ addn_ie_len += ht_cap_len;
+ }
#ifdef WLAN_FEATURE_11AC
- if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
- limLog(pMac, LOG1,
- FL("Adding VHT Caps IE since dot11mode=%d"),
- pScanReq->dot11mode);
- /* 2 bytes for EID and Length */
- vht_cap_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
- sizeof(tSirVhtMcsInfo);
- len += vht_cap_len;
- addn_ie_len += vht_cap_len;
- }
+ if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
+ limLog(pMac, LOG1,
+ FL("Adding VHT Caps IE since dot11mode=%d"),
+ pScanReq->dot11mode);
+ /* 2 bytes for EID and Length */
+ vht_cap_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
+ sizeof(tSirVhtMcsInfo);
+ len += vht_cap_len;
+ addn_ie_len += vht_cap_len;
+ }
#endif /* WLAN_FEATURE_11AC */
+ }
pScanOffloadReq = vos_mem_malloc(len);
if ( NULL == pScanOffloadReq )
@@ -1244,33 +1260,35 @@ static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac,
(tANI_U8 *) pScanReq + pScanReq->uIEFieldOffset,
pScanReq->uIEFieldLen);
- /* Copy HT Capability info if dot11mode is HT */
- if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
- /* Populate EID and Length field here */
- ht_cap_ie = (tANI_U8 *) pScanOffloadReq +
+ if (!pMac->per_band_chainmask_supp) {
+ /* Copy HT Capability info if dot11mode is HT */
+ if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
+ /* Populate EID and Length field here */
+ ht_cap_ie = (tANI_U8 *) pScanOffloadReq +
pScanOffloadReq->uIEFieldOffset +
pScanOffloadReq->uIEFieldLen;
- vos_mem_set(ht_cap_ie, ht_cap_len, 0);
- *ht_cap_ie = SIR_MAC_HT_CAPABILITIES_EID;
- *(ht_cap_ie + 1) = ht_cap_len - 2;
- lim_set_ht_caps(pMac, NULL, ht_cap_ie, ht_cap_len);
- pScanOffloadReq->uIEFieldLen += ht_cap_len;
- }
+ vos_mem_set(ht_cap_ie, ht_cap_len, 0);
+ *ht_cap_ie = SIR_MAC_HT_CAPABILITIES_EID;
+ *(ht_cap_ie + 1) = ht_cap_len - 2;
+ lim_set_ht_caps(pMac, NULL, ht_cap_ie, ht_cap_len);
+ pScanOffloadReq->uIEFieldLen += ht_cap_len;
+ }
#ifdef WLAN_FEATURE_11AC
- /* Copy VHT Capability info if dot11mode is VHT Capable */
- if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
- /* Populate EID and Length field here */
- vht_cap_ie = (tANI_U8 *) pScanOffloadReq +
+ /* Copy VHT Capability info if dot11mode is VHT Capable */
+ if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
+ /* Populate EID and Length field here */
+ vht_cap_ie = (tANI_U8 *) pScanOffloadReq +
pScanOffloadReq->uIEFieldOffset +
pScanOffloadReq->uIEFieldLen;
- vos_mem_set(vht_cap_ie, vht_cap_len, 0);
- *vht_cap_ie = SIR_MAC_VHT_CAPABILITIES_EID;
- *(vht_cap_ie + 1) = vht_cap_len - 2;
- lim_set_vht_caps(pMac, NULL, vht_cap_ie, vht_cap_len);
- pScanOffloadReq->uIEFieldLen += vht_cap_len;
- }
+ vos_mem_set(vht_cap_ie, vht_cap_len, 0);
+ *vht_cap_ie = SIR_MAC_VHT_CAPABILITIES_EID;
+ *(vht_cap_ie + 1) = vht_cap_len - 2;
+ lim_set_vht_caps(pMac, NULL, vht_cap_ie, vht_cap_len);
+ pScanOffloadReq->uIEFieldLen += vht_cap_len;
+ }
#endif /* WLAN_FEATURE_11AC */
+ }
rc = wdaPostCtrlMsg(pMac, &msg);
if (rc != eSIR_SUCCESS)
@@ -1777,6 +1795,7 @@ __limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
tPowerdBm localPowerConstraint = 0, regMax = 0;
tANI_U16 ieLen;
v_U8_t *vendorIE;
+ struct vdev_type_nss *vdev_type_nss;
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
//Not sending any session, since it is not created yet. The response whould have correct state.
@@ -1942,6 +1961,20 @@ __limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
FL("PE PERSONA=%d cbMode %u"), psessionEntry->pePersona,
pSmeJoinReq->cbMode);
+ /* Copy The channel Id to the session Table */
+ psessionEntry->currentOperChannel =
+ pSmeJoinReq->bssDescription.channelId;
+ if (IS_5G_CH(psessionEntry->currentOperChannel))
+ vdev_type_nss = &pMac->vdev_type_nss_5g;
+ else
+ vdev_type_nss = &pMac->vdev_type_nss_2g;
+ if (psessionEntry->pePersona == VOS_P2P_CLIENT_MODE)
+ psessionEntry->vdev_nss = vdev_type_nss->p2p_cli;
+ else
+ psessionEntry->vdev_nss = vdev_type_nss->sta;
+
+ limLog(pMac, LOG1, FL("persona - %d, nss - %d"),
+ psessionEntry->pePersona, psessionEntry->vdev_nss);
#ifdef WLAN_FEATURE_11AC
psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(psessionEntry->dot11mode);
VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED,
@@ -1994,8 +2027,6 @@ __limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
/*Phy mode*/
psessionEntry->gLimPhyMode = pSmeJoinReq->bssDescription.nwType;
- /* Copy The channel Id to the session Table */
- psessionEntry->currentOperChannel = pSmeJoinReq->bssDescription.channelId;
psessionEntry->htSupportedChannelWidthSet = (pSmeJoinReq->cbMode)?1:0; // This is already merged value of peer and self - done by csr in csrGetCBModeFromIes
psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet;
psessionEntry->htSecondaryChannelOffset = pSmeJoinReq->cbMode;
@@ -5205,6 +5236,8 @@ __limProcessSmeAddStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
pAddStaSelfParams->type = pSmeReq->type;
pAddStaSelfParams->subType = pSmeReq->subType;
pAddStaSelfParams->pkt_err_disconn_th = pSmeReq->pkt_err_disconn_th;
+ pAddStaSelfParams->nss_2g = pSmeReq->nss_2g;
+ pAddStaSelfParams->nss_5g = pSmeReq->nss_5g;
msg.type = SIR_HAL_ADD_STA_SELF_REQ;
msg.reserved = 0;
@@ -5932,6 +5965,9 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
limProcessModifyAddIEs(pMac, pMsgBuf);
break;
+ case eWNI_SME_PDEV_SET_HT_VHT_IE:
+ lim_process_set_pdev_IEs(pMac, pMsgBuf);
+ break;
default:
vos_mem_free((v_VOID_t*)pMsg->bodyptr);
pMsg->bodyptr = NULL;
@@ -6349,6 +6385,181 @@ limProcessModifyAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg)
}
+/**
+ * lim_process_set_pdev_IEs() - process the set pdev IE req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: Pointer to the SME message buffer
+ *
+ * This function is called by limProcessMessageQueue(). This
+ * function sets the PDEV IEs to the FW.
+ *
+ * Return: None
+ */
+static void lim_process_set_pdev_IEs(tpAniSirGlobal mac_ctx, tANI_U32 *msg_buf)
+{
+ struct sir_set_ht_vht_cfg *ht_vht_cfg;
+
+ ht_vht_cfg = (struct sir_set_ht_vht_cfg*)msg_buf;
+
+ if (NULL == ht_vht_cfg) {
+ limLog(mac_ctx, LOGE, FL("NULL ht_vht_cfg"));
+ return;
+ }
+
+ limLog(mac_ctx, LOG1, FL("rcvd set pdev ht vht ie req with nss = %d"),
+ ht_vht_cfg->nss);
+ lim_set_pdev_ht_ie(mac_ctx, ht_vht_cfg->pdev_id, ht_vht_cfg->nss);
+
+ if (IS_DOT11_MODE_VHT(ht_vht_cfg->dot11mode))
+ lim_set_pdev_vht_ie(mac_ctx, ht_vht_cfg->pdev_id,
+ ht_vht_cfg->nss);
+}
+
+/**
+ * lim_set_pdev_ht_ie() - sends the set HT IE req to FW
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @pdev_id: pdev id to set the IE.
+ * @nss: Nss values to prepare the HT IE.
+ *
+ * Prepares the HT IE with self capabilities for different
+ * Nss values and sends the set HT IE req to FW.
+ *
+ * Return: None
+ */
+static void lim_set_pdev_ht_ie(tpAniSirGlobal mac_ctx, tANI_U8 pdev_id,
+ tANI_U8 nss)
+{
+ struct set_ie_param *ie_params;
+ tSirMsgQ msg;
+ tSirRetStatus rc = eSIR_SUCCESS;
+ v_U8_t *p_ie = NULL;
+ tHtCaps *p_ht_cap;
+ int i;
+
+ for (i = nss; i > 0; i--) {
+ ie_params = vos_mem_malloc(sizeof(*ie_params));
+ if (NULL == ie_params) {
+ limLog(mac_ctx, LOGE, FL("mem alloc failed"));
+ return;
+ }
+ ie_params->nss = i;
+ ie_params->pdev_id = pdev_id;
+ ie_params->ie_type = DOT11_HT_IE;
+ /* 2 for IE len and EID */
+ ie_params->ie_len = 2 + sizeof(tHtCaps);
+ ie_params->ie_ptr = vos_mem_malloc(ie_params->ie_len);
+ if (NULL == ie_params->ie_ptr) {
+ vos_mem_free(ie_params);
+ limLog(mac_ctx, LOGE, FL("mem alloc failed"));
+ return;
+ }
+ *ie_params->ie_ptr = SIR_MAC_HT_CAPABILITIES_EID;
+ *(ie_params->ie_ptr + 1) = ie_params->ie_len - 2;
+ lim_set_ht_caps(mac_ctx, NULL, ie_params->ie_ptr,
+ ie_params->ie_len);
+
+ if (1 == i) {
+ p_ie = limGetIEPtr(mac_ctx, ie_params->ie_ptr,
+ ie_params->ie_len,
+ DOT11F_EID_HTCAPS, ONE_BYTE);
+ p_ht_cap = (tHtCaps *)&p_ie[2];
+ p_ht_cap->supportedMCSSet[1] = 0;
+ p_ht_cap->txSTBC = 0;
+ }
+
+ msg.type = WDA_SET_PDEV_IE_REQ;
+ msg.bodyptr = ie_params;
+ msg.bodyval = 0;
+
+ rc = wdaPostCtrlMsg(mac_ctx, &msg);
+ if (rc != eSIR_SUCCESS) {
+ limLog(mac_ctx, LOGE, FL(
+ "wdaPostCtrlMsg() return failure"));
+ vos_mem_free(ie_params->ie_ptr);
+ vos_mem_free(ie_params);
+ return;
+ }
+ }
+}
+
+/**
+ * lim_set_pdev_vht_ie() - sends the set VHT IE to req FW
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @pdev_id: pdev id to set the IE.
+ * @nss: Nss values to prepare the VHT IE.
+ *
+ * Prepares the VHT IE with self capabilities for different
+ * Nss values and sends the set VHT IE req to FW.
+ *
+ * Return: None
+ */
+static void lim_set_pdev_vht_ie(tpAniSirGlobal mac_ctx, tANI_U8 pdev_id,
+ tANI_U8 nss)
+{
+ struct set_ie_param *ie_params;
+ tSirMsgQ msg;
+ tSirRetStatus rc = eSIR_SUCCESS;
+ v_U8_t *p_ie = NULL;
+ tSirMacVHTCapabilityInfo *vht_cap;
+ int i;
+ tSirVhtMcsInfo *vht_mcs;
+
+ for (i = nss; i > 0; i--) {
+ ie_params = vos_mem_malloc(sizeof(*ie_params));
+ if (NULL == ie_params) {
+ limLog(mac_ctx, LOGE, FL("mem alloc failed"));
+ return;
+ }
+ ie_params->nss = i;
+ ie_params->pdev_id = pdev_id;
+ ie_params->ie_type = DOT11_VHT_IE;
+ /* 2 for IE len and EID */
+ ie_params->ie_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
+ sizeof(tSirVhtMcsInfo);
+ ie_params->ie_ptr = vos_mem_malloc(ie_params->ie_len);
+ if (NULL == ie_params->ie_ptr) {
+ vos_mem_free(ie_params);
+ limLog(mac_ctx, LOGE, FL("mem alloc failed"));
+ return;
+ }
+ *ie_params->ie_ptr = SIR_MAC_VHT_CAPABILITIES_EID;
+ *(ie_params->ie_ptr + 1) = ie_params->ie_len - 2;
+ lim_set_vht_caps(mac_ctx, NULL, ie_params->ie_ptr,
+ ie_params->ie_len);
+
+ if (1 == i) {
+ p_ie = limGetIEPtr(mac_ctx, ie_params->ie_ptr,
+ ie_params->ie_len,
+ DOT11F_EID_VHTCAPS, ONE_BYTE);
+ vht_cap = (tSirMacVHTCapabilityInfo *)&p_ie[2];
+ vht_cap->txSTBC = 0;
+ vht_mcs =
+ (tSirVhtMcsInfo *)&p_ie[2 +
+ sizeof(tSirMacVHTCapabilityInfo)];
+ vht_mcs->rxMcsMap |= DISABLE_NSS2_MCS;
+ vht_mcs->rxHighest =
+ VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+ vht_mcs->txMcsMap |= DISABLE_NSS2_MCS;
+ vht_mcs->txHighest =
+ VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+ }
+ msg.type = WDA_SET_PDEV_IE_REQ;
+ msg.bodyptr = ie_params;
+ msg.bodyval = 0;
+
+ rc = wdaPostCtrlMsg(mac_ctx, &msg);
+ if (rc != eSIR_SUCCESS) {
+ limLog(mac_ctx, LOGE, FL(
+ "wdaPostCtrlMsg() return failure"));
+ vos_mem_free(ie_params->ie_ptr);
+ vos_mem_free(ie_params);
+ return;
+ }
+ }
+}
/******************************************************************************
* limProcessUpdateAddIEs()
*
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 62dcbbeb2f19..d0dba75464ec 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -1689,6 +1689,8 @@ static void wma_recreate_ibss_vdev_and_bss_peer(tp_wma_handle wma, u_int8_t vdev
add_sta_self_param.type = WMI_VDEV_TYPE_IBSS;
add_sta_self_param.subType = 0;
add_sta_self_param.status = 0;
+ add_sta_self_param.nss_2g = wma->interfaces[vdev_id].nss_2g;
+ add_sta_self_param.nss_5g = wma->interfaces[vdev_id].nss_5g;
/* delete old ibss vdev */
del_sta_param.sessionId = vdev_id;
@@ -6427,19 +6429,25 @@ enum wlan_op_mode wma_get_txrx_vdev_type(u_int32_t type)
*/
int wma_unified_vdev_create_send(wmi_unified_t wmi_handle, u_int8_t if_id,
u_int32_t type, u_int32_t subtype,
- u_int8_t macaddr[IEEE80211_ADDR_LEN])
+ u_int8_t macaddr[IEEE80211_ADDR_LEN],
+ u_int8_t nss_2g, u_int8_t nss_5g)
{
wmi_vdev_create_cmd_fixed_param* cmd;
wmi_buf_t buf;
int len = sizeof(*cmd);
int ret;
+ int num_bands = 2;
+ u_int8_t *buf_ptr;
+ wmi_vdev_txrx_streams *txrx_streams;
+
+ len += (num_bands * sizeof(wmi_vdev_txrx_streams) + WMI_TLV_HDR_SIZE);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf) {
WMA_LOGP("%s:wmi_buf_alloc failed", __FUNCTION__);
return ENOMEM;
}
- cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf);
+ cmd = (wmi_vdev_create_cmd_fixed_param *)wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
@@ -6447,11 +6455,36 @@ int wma_unified_vdev_create_send(wmi_unified_t wmi_handle, u_int8_t if_id,
cmd->vdev_id = if_id;
cmd->vdev_type = type;
cmd->vdev_subtype = subtype;
+ cmd->num_cfg_txrx_streams = num_bands;
WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr);
WMA_LOGE("%s: ID = %d VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x",
__func__, if_id,
macaddr[0], macaddr[1], macaddr[2],
macaddr[3], macaddr[4], macaddr[5]);
+
+ buf_ptr = (u_int8_t *)cmd + sizeof(*cmd);
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+ (num_bands * sizeof(wmi_vdev_txrx_streams)));
+ buf_ptr += WMI_TLV_HDR_SIZE;
+
+ WMA_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__,
+ type, subtype, nss_2g, nss_5g);
+ txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr;
+ txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G;
+ txrx_streams->supported_tx_streams = nss_2g;
+ txrx_streams->supported_rx_streams = nss_2g;
+ WMITLV_SET_HDR(&txrx_streams->tlv_header,
+ WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
+
+ buf_ptr += sizeof(wmi_vdev_txrx_streams);
+ txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr;
+ txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G;
+ txrx_streams->supported_tx_streams = nss_5g;
+ txrx_streams->supported_rx_streams = nss_5g;
+ WMITLV_SET_HDR(&txrx_streams->tlv_header,
+ WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID);
if (ret != EOK) {
WMA_LOGE("Failed to send WMI_VDEV_CREATE_CMDID");
@@ -7169,7 +7202,9 @@ static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
self_sta_req->sessionId,
self_sta_req->type,
self_sta_req->subType,
- self_sta_req->selfMacAddr))
+ self_sta_req->selfMacAddr,
+ self_sta_req->nss_2g,
+ self_sta_req->nss_5g))
{
WMA_LOGP("%s: Unable to add an interface for ath_dev", __func__);
status = VOS_STATUS_E_RESOURCES;
@@ -7250,6 +7285,10 @@ static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
self_sta_req->type;
wma_handle->interfaces[self_sta_req->sessionId].sub_type =
self_sta_req->subType;
+ wma_handle->interfaces[self_sta_req->sessionId].nss_2g =
+ self_sta_req->nss_2g;
+ wma_handle->interfaces[self_sta_req->sessionId].nss_5g =
+ self_sta_req->nss_5g;
adf_os_atomic_init(&wma_handle->interfaces
[self_sta_req->sessionId].bss_status);
@@ -8375,6 +8414,8 @@ VOS_STATUS wma_update_channel_list(WMA_HANDLE handle,
sizeof(wmi_channel) * chan_list->numChan);
chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
+ WMA_LOGD("ht %d, vht %d, vht_24 %d", chan_list->ht_en,
+ chan_list->vht_en, chan_list->vht_24_en);
for (i = 0; i < chan_list->numChan; ++i) {
WMITLV_SET_HDR(&chan_info->tlv_header,
WMITLV_TAG_STRUC_wmi_channel,
@@ -8400,10 +8441,19 @@ VOS_STATUS wma_update_channel_list(WMA_HANDLE handle,
if (chan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) {
WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
+ if (chan_list->vht_en && chan_list->vht_24_en)
+ WMI_SET_CHANNEL_FLAG(chan_info,
+ WMI_CHAN_FLAG_ALLOW_VHT);
} else {
WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
+ if (chan_list->vht_en)
+ WMI_SET_CHANNEL_FLAG(chan_info,
+ WMI_CHAN_FLAG_ALLOW_VHT);
}
+ if (chan_list->ht_en)
+ WMI_SET_CHANNEL_FLAG(chan_info,
+ WMI_CHAN_FLAG_ALLOW_HT);
WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
chan_list->chanParam[i].pwr);
@@ -11852,7 +11902,8 @@ static int32_t wmi_unified_send_peer_assoc(tp_wma_handle wma,
* Limit nss to max number of rf chain supported by target
* Otherwise Fw will crash
*/
- wma_update_txrx_chainmask(wma->num_rf_chains, &cmd->peer_nss);
+ if (!wma->per_band_chainmask_supp)
+ wma_update_txrx_chainmask(wma->num_rf_chains, &cmd->peer_nss);
intr->nss = cmd->peer_nss;
cmd->peer_phymode = phymode;
@@ -13006,6 +13057,14 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
case WMI_PDEV_PARAM_RX_CHAIN_MASK:
wma->pdevconfig.rxchainmask = privcmd->param_value;
break;
+ case WMI_PDEV_PARAM_TX_CHAIN_MASK_2G:
+ case WMI_PDEV_PARAM_RX_CHAIN_MASK_2G:
+ wma->pdevconfig.chainmask_2g = privcmd->param_value;
+ break;
+ case WMI_PDEV_PARAM_TX_CHAIN_MASK_5G:
+ case WMI_PDEV_PARAM_RX_CHAIN_MASK_5G:
+ wma->pdevconfig.chainmask_5g = privcmd->param_value;
+ break;
case WMI_PDEV_PARAM_BURST_ENABLE:
wma->pdevconfig.burst_enable = privcmd->param_value;
if ((wma->pdevconfig.burst_enable == 1) &&
@@ -13299,6 +13358,139 @@ int wma_cli_get_command(void *wmapvosContext, int vdev_id,
return ret;
}
+/**
+ * wma_process_set_pdev_ht_ie_req() - sends HT IE data to FW
+ *
+ * @wma: Pointer to wma handle
+ * @ie_params: Pointer to IE data.
+ * @nss: Nss values to prepare the HT IE.
+ *
+ * Sends the WMI req to set the HT IE to FW.
+ *
+ * Return: None
+ */
+void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma,
+ struct set_ie_param *ie_params)
+{
+ int ret;
+ wmi_pdev_set_ht_ie_cmd_fixed_param *cmd;
+ wmi_buf_t buf;
+ u_int16_t len;
+ u_int16_t ie_len_pad;
+ u_int8_t *buf_ptr;
+
+ len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+ ie_len_pad = roundup(ie_params->ie_len, sizeof(u_int32_t));
+ len += ie_len_pad;
+
+ buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+ return;
+ }
+ cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *) wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_pdev_set_ht_ie_cmd_fixed_param));
+ cmd->reserved0 = 0;
+ cmd->ie_len = ie_params->ie_len;
+ cmd->tx_streams = ie_params->nss;
+ cmd->rx_streams = ie_params->nss;
+ WMA_LOGD("Setting pdev HT ie with Nss = %u",
+ ie_params->nss);
+ buf_ptr = (u_int8_t *)cmd + sizeof(*cmd);
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad);
+ if (ie_params->ie_len) {
+ vos_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
+ (u_int8_t *)ie_params->ie_ptr,
+ ie_params->ie_len);
+ }
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_PDEV_SET_HT_CAP_IE_CMDID);
+ if (ret != EOK) {
+ WMA_LOGE("Failed to send set param command ret = %d", ret);
+ wmi_buf_free(buf);
+ }
+}
+
+/**
+ * wma_process_set_pdev_vht_ie_req() - sends VHT IE data to FW
+ *
+ * @wma: Pointer to wma handle
+ * @ie_params: Pointer to IE data.
+ * @nss: Nss values to prepare the VHT IE.
+ *
+ * Sends the WMI req to set the VHT IE to FW.
+ *
+ * Return: None
+ */
+void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma,
+ struct set_ie_param *ie_params)
+{
+ int ret;
+ wmi_pdev_set_vht_ie_cmd_fixed_param *cmd;
+ wmi_buf_t buf;
+ u_int16_t len;
+ u_int16_t ie_len_pad;
+ u_int8_t *buf_ptr;
+
+ len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+ ie_len_pad = roundup(ie_params->ie_len, sizeof(u_int32_t));
+ len += ie_len_pad;
+
+ buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+ return;
+ }
+ cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *) wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_pdev_set_vht_ie_cmd_fixed_param));
+ cmd->reserved0 = 0;
+ cmd->ie_len = ie_params->ie_len;
+ cmd->tx_streams = ie_params->nss;
+ cmd->rx_streams = ie_params->nss;
+ WMA_LOGD("Setting pdev VHT ie with Nss = %u",
+ ie_params->nss);
+ buf_ptr = (u_int8_t *)cmd + sizeof(*cmd);
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad);
+ if (ie_params->ie_len) {
+ vos_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
+ (u_int8_t *)ie_params->ie_ptr,
+ ie_params->ie_len);
+ }
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_PDEV_SET_VHT_CAP_IE_CMDID);
+ if (ret != EOK) {
+ WMA_LOGE("Failed to send set param command ret = %d", ret);
+ wmi_buf_free(buf);
+ }
+}
+
+/**
+ * wma_process_set_pdev_ie_req() - process the pdev set IE req
+ *
+ * @wma: Pointer to wma handle
+ * @ie_params: Pointer to IE data.
+ *
+ * Sends the WMI req to set the IE to FW.
+ *
+ * Return: None
+ */
+void wma_process_set_pdev_ie_req(tp_wma_handle wma,
+ struct set_ie_param *ie_params)
+{
+ if (ie_params->ie_type == DOT11_HT_IE)
+ wma_process_set_pdev_ht_ie_req(wma, ie_params);
+ if (ie_params->ie_type == DOT11_VHT_IE)
+ wma_process_set_pdev_vht_ie_req(wma, ie_params);
+
+ vos_mem_free(ie_params->ie_ptr);
+}
+
static void
wma_update_protection_mode(tp_wma_handle wma, u_int8_t vdev_id,
u_int8_t llbcoexist)
@@ -13687,6 +13879,7 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
tDelStaSelfParams del_sta_param;
tAddStaSelfParams add_sta_self_param;
tSetBssKeyParams key_info;
+ u_int8_t nss_2g, nss_5g;
WMA_LOGD("%s: add_bss->sessionId = %d", __func__, add_bss->sessionId);
vdev_id = add_bss->sessionId;
@@ -13696,6 +13889,9 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
WMA_LOGE("%s: Failed to get pdev", __func__);
goto send_fail_resp;
}
+
+ nss_2g = wma->interfaces[vdev_id].nss_2g;
+ nss_5g = wma->interfaces[vdev_id].nss_5g;
wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss);
vdev = wma_find_vdev_by_id(wma, vdev_id);
@@ -13735,6 +13931,8 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
add_sta_self_param.type = WMI_VDEV_TYPE_IBSS;
add_sta_self_param.subType = 0;
add_sta_self_param.status = 0;
+ add_sta_self_param.nss_2g = add_bss->nss_2g;
+ add_sta_self_param.nss_5g = add_bss->nss_5g;
vdev = wma_vdev_attach(wma, &add_sta_self_param, 0);
if (!vdev) {
@@ -20284,7 +20482,10 @@ static void wma_process_update_rx_nss(tp_wma_handle wma_handle,
&wma_handle->interfaces[update_rx_nss->smesessionId];
int rxNss = update_rx_nss->rxNss;
- wma_update_txrx_chainmask(wma_handle->num_rf_chains, &rxNss);
+ if (wma_handle->per_band_chainmask_supp)
+ wma_update_txrx_chainmask(intr->nss, &rxNss);
+ else
+ wma_update_txrx_chainmask(wma_handle->num_rf_chains, &rxNss);
intr->nss = (tANI_U8) rxNss;
update_rx_nss->rxNss = (tANI_U32) rxNss;
@@ -25267,6 +25468,11 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
(wda_cli_set_cmd_t *)msg->bodyptr);
vos_mem_free(msg->bodyptr);
break;
+ case WDA_SET_PDEV_IE_REQ:
+ wma_process_set_pdev_ie_req(wma_handle,
+ (struct set_ie_param *)msg->bodyptr);
+ vos_mem_free(msg->bodyptr);
+ break;
#if !defined(REMOVE_PKT_LOG)
case WDA_PKTLOG_ENABLE_REQ:
wma_pktlog_wmi_send_cmd(wma_handle,
@@ -27687,6 +27893,10 @@ static inline void wma_update_target_services(tp_wma_handle wh,
#endif
cfg->lte_coex_ant_share = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
WMI_SERVICE_LTE_ANT_SHARE_SUPPORT);
+ cfg->per_band_chainmask_supp = WMI_SERVICE_IS_ENABLED(
+ wh->wmi_service_bitmap,
+ WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT);
+ wh->per_band_chainmask_supp = cfg->per_band_chainmask_supp;
#ifdef FEATURE_WLAN_TDLS
/* Enable TDLS */
if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_TDLS)) {
@@ -27725,7 +27935,8 @@ static inline void wma_update_target_services(tp_wma_handle wh,
WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
WMI_SERVICE_SAP_AUTH_OFFLOAD);
#endif
-
+ cfg->chain_mask_2g = wh->txrx_chainmask & 0xFF;
+ cfg->chain_mask_5g = (wh->txrx_chainmask >> 16 ) & 0xFF;
}
static inline void wma_update_target_ht_cap(tp_wma_handle wh,
@@ -28031,7 +28242,7 @@ v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info)
wma_handle->vht_cap_info = ev->vht_cap_info;
wma_handle->vht_supp_mcs = ev->vht_supp_mcs;
#endif
- wma_handle->num_rf_chains = ev->num_rf_chains;
+ wma_handle->txrx_chainmask = ev->txrx_chainmask;
wma_handle->target_fw_version = ev->fw_build_vers;
diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h
index 8ee66f816ee2..4b5294746421 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -388,6 +388,8 @@ typedef struct {
u_int32_t pwrgating;
u_int32_t burst_enable;
u_int32_t burst_dur;
+ u_int32_t chainmask_2g;
+ u_int32_t chainmask_5g;
} pdev_cli_config_t;
typedef struct {
@@ -551,6 +553,8 @@ struct wma_txrx_node {
uint32_t alt_modulated_dtim;
bool alt_modulated_dtim_enabled;
uint8_t wps_state;
+ uint8_t nss_2g;
+ uint8_t nss_5g;
};
#if defined(QCA_WIFI_FTM)
@@ -775,6 +779,8 @@ typedef struct wma_handle {
uint32_t miracast_value;
vos_timer_t log_completion_timer;
+ uint32_t txrx_chainmask;
+ uint8_t per_band_chainmask_supp;
}t_wma_handle, *tp_wma_handle;
struct wma_target_cap {
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 9b82d954f07d..e58da17131fb 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -89,6 +89,7 @@
reg_info_2 |= ((val & 0xff) << 8); \
} while(0)
+#define NUM_OF_BANDS 2
/*--------------------------------------------------------------------------
Type declarations
------------------------------------------------------------------------*/
@@ -4339,4 +4340,12 @@ eHalStatus sme_set_rssi_monitoring(tHalHandle hal,
struct rssi_monitor_req *input);
eHalStatus sme_set_rssi_threshold_breached_cb(tHalHandle hal,
void (*cb)(void *, struct rssi_breach_event *));
+void sme_set_pdev_ht_vht_ies(tHalHandle hHal, bool enable2x2);
+
+void sme_update_vdev_type_nss(tHalHandle hal, uint8_t max_supp_nss,
+ uint32_t vdev_type_nss, eCsrBand band);
+void sme_set_vdev_nss(tHalHandle hal, bool enable2x2);
+void sme_set_per_band_chainmask_supp(tHalHandle hal, bool val);
+void sme_set_lte_coex_supp(tHalHandle hal, bool val);
+void sme_set_bcon_offload_supp(tHalHandle hal, bool val);
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index fbbbcd0d7a11..b89a1c36a905 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -527,6 +527,22 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
}
}
+ if ((pMac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) ||
+ (pMac->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_11AC) ||
+ (pMac->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_11AC_ONLY)) {
+ pChanList->vht_en = true;
+ if (pMac->roam.configParam.enableVhtFor24GHz)
+ pChanList->vht_24_en = true;
+ }
+ if ((pMac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) ||
+ (pMac->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_11N) ||
+ (pMac->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_11N_ONLY)) {
+ pChanList->ht_en = true;
+ }
msg.type = WDA_UPDATE_CHAN_LIST_REQ;
msg.reserved = 0;
msg.bodyptr = pChanList;
@@ -15018,6 +15034,58 @@ eHalStatus csrProcessAddStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg)
} while(0);
return status;
}
+/**
+ * csr_get_vdev_type_nss() - gets the nss value based on vdev type
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @dev_mode: current device operating mode.
+ * @nss2g: Pointer to the 2G Nss parameter.
+ * @nss5g: Pointer to the 5G Nss parameter.
+ *
+ * Fills the 2G and 5G Nss values based on device mode.
+ *
+ * Return: None
+ */
+void csr_get_vdev_type_nss(tpAniSirGlobal mac_ctx, tVOS_CON_MODE dev_mode,
+ uint8_t *nss_2g, uint8_t *nss_5g)
+{
+ switch (dev_mode) {
+ case VOS_STA_MODE:
+ *nss_2g = mac_ctx->vdev_type_nss_2g.sta;
+ *nss_5g = mac_ctx->vdev_type_nss_5g.sta;
+ break;
+ case VOS_STA_SAP_MODE:
+ *nss_2g = mac_ctx->vdev_type_nss_2g.sap;
+ *nss_5g = mac_ctx->vdev_type_nss_5g.sap;
+ break;
+ case VOS_P2P_CLIENT_MODE:
+ *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_cli;
+ *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_cli;
+ break;
+ case VOS_P2P_GO_MODE:
+ *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_go;
+ *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_go;
+ break;
+ case VOS_P2P_DEVICE_MODE:
+ *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_dev;
+ *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_dev;
+ break;
+ case VOS_IBSS_MODE:
+ *nss_2g = mac_ctx->vdev_type_nss_2g.ibss;
+ *nss_5g = mac_ctx->vdev_type_nss_5g.ibss;
+ break;
+ case VOS_OCB_MODE:
+ *nss_2g = mac_ctx->vdev_type_nss_2g.ocb;
+ *nss_5g = mac_ctx->vdev_type_nss_5g.ocb;
+ break;
+ default:
+ *nss_2g = 2;
+ *nss_5g = 2;
+ break;
+ }
+ smsLog(mac_ctx, LOG1, FL("mode - %d: nss_2g - %d, 5g - %d"),
+ dev_mode, *nss_2g, *nss_5g);
+}
eHalStatus csrSendMBAddSelfStaReqMsg( tpAniSirGlobal pMac,
tAddStaForSessionCmd *pAddStaReq,
tANI_U8 sessionId)
@@ -15025,11 +15093,14 @@ eHalStatus csrSendMBAddSelfStaReqMsg( tpAniSirGlobal pMac,
tSirSmeAddStaSelfReq *pMsg;
tANI_U16 msgLen;
eHalStatus status = eHAL_STATUS_FAILURE;
+ uint8_t nss_2g;
+ uint8_t nss_5g;
do {
msgLen = sizeof(tSirSmeAddStaSelfReq);
pMsg = vos_mem_malloc(msgLen);
if ( NULL == pMsg ) break;
vos_mem_set(pMsg, msgLen, 0);
+ csr_get_vdev_type_nss(pMac, pAddStaReq->currDeviceMode, &nss_2g, &nss_5g);
pMsg->mesgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_ADD_STA_SELF_REQ);
pMsg->mesgLen = pal_cpu_to_be16(msgLen);
// self station address
@@ -15041,6 +15112,8 @@ eHalStatus csrSendMBAddSelfStaReqMsg( tpAniSirGlobal pMac,
pMsg->subType = pAddStaReq->subType;
pMsg->sessionId = sessionId;
pMsg->pkt_err_disconn_th = pMac->roam.configParam.pkt_err_disconn_th;
+ pMsg->nss_2g = nss_2g;
+ pMsg->nss_5g = nss_5g;
smsLog( pMac, LOG1, FL("selfMac="MAC_ADDRESS_STR),
MAC_ADDR_ARRAY(pMsg->selfMacAddr));
status = palSendMBMessage(pMac->hHdd, pMsg);
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index effafcfbbd67..639da01e0fa5 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -12174,6 +12174,72 @@ void sme_SetCurrDeviceMode (tHalHandle hHal, tVOS_CON_MODE currDeviceMode)
return;
}
+/**
+ * sme_set_pdev_ht_vht_ies() - sends the set pdev IE req
+ *
+ * @hal: Pointer to HAL
+ * @enable2x2: 1x1 or 2x2 mode.
+ *
+ * Sends the set pdev IE req with Nss value.
+ *
+ * Return: None
+ */
+void sme_set_pdev_ht_vht_ies(tHalHandle hal, bool enable2x2)
+{
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ struct sir_set_ht_vht_cfg *ht_vht_cfg;
+ eHalStatus status = eHAL_STATUS_FAILURE;
+
+ if (!mac_ctx->per_band_chainmask_supp)
+ return;
+
+ if (!((mac_ctx->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_AUTO) ||
+ (mac_ctx->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_11N) ||
+ (mac_ctx->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_11N_ONLY) ||
+ (mac_ctx->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_11AC) ||
+ (mac_ctx->roam.configParam.uCfgDot11Mode ==
+ eCSR_CFG_DOT11_MODE_11AC_ONLY)))
+ return;
+
+ status = sme_AcquireGlobalLock(&mac_ctx->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ ht_vht_cfg = vos_mem_malloc(sizeof(*ht_vht_cfg));
+ if (NULL == ht_vht_cfg) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: mem alloc failed for ht_vht_cfg",
+ __func__);
+ sme_ReleaseGlobalLock(&mac_ctx->sme);
+ return;
+ }
+
+ ht_vht_cfg->pdev_id = 0;
+ if (enable2x2)
+ ht_vht_cfg->nss = 2;
+ else
+ ht_vht_cfg->nss = 1;
+ ht_vht_cfg->dot11mode =
+ (tANI_U8)csrTranslateToWNICfgDot11Mode(mac_ctx,
+ mac_ctx->roam.configParam.uCfgDot11Mode);
+
+ ht_vht_cfg->msg_type = eWNI_SME_PDEV_SET_HT_VHT_IE;
+ ht_vht_cfg->len = sizeof(*ht_vht_cfg);
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ "%s: send PDEV_SET_HT_VHT_IE with nss - %d, dot11mode - %d",
+ __func__, ht_vht_cfg->nss, ht_vht_cfg->dot11mode);
+ status = palSendMBMessage(mac_ctx->hHdd, ht_vht_cfg);
+ if (eHAL_STATUS_SUCCESS != status) {
+ smsLog(mac_ctx, LOGE, FL(
+ "SME_PDEV_SET_HT_VHT_IE msg to PE failed"));
+ vos_mem_free(ht_vht_cfg);
+ }
+ sme_ReleaseGlobalLock(&mac_ctx->sme);
+ }
+ return;
+}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/*--------------------------------------------------------------------------
\brief sme_HandoffRequest() - a wrapper function to Request a handoff
@@ -16698,3 +16764,132 @@ void sme_enable_phy_error_logs(tHalHandle hal, bool enable_log)
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
mac_ctx->sap.enable_dfs_phy_error_logs = enable_log;
}
+/**
+ * sme_set_vdev_nss() - sets the vdev nss based on INI
+ * @hal: Pointer to HAL
+ * @enable2x2: 1x1 or 2x2 mode.
+ *
+ * Sets the per band Nss for each vdev type based on INI.
+ *
+ * Return: None
+ */
+void sme_set_vdev_nss(tHalHandle hal, bool enable2x2)
+{
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ struct vdev_type_nss *vdev_nss;
+ uint8_t i;
+ uint8_t nss_val;
+ uint8_t coex;
+
+ if (enable2x2) {
+ if (mac_ctx->lteCoexAntShare)
+ coex = 1;
+ else
+ coex = 0;
+ nss_val = 2;
+ } else {
+ nss_val = 1;
+ coex = 0;
+ }
+
+ vdev_nss = &mac_ctx->vdev_type_nss_2g;
+
+ for (i = 0; i < NUM_OF_BANDS; i++) {
+ vdev_nss->sta = nss_val;
+ vdev_nss->sap = nss_val - coex;
+ vdev_nss->p2p_go = nss_val - coex;
+ vdev_nss->p2p_cli = nss_val - coex;
+ vdev_nss->p2p_dev = nss_val - coex;
+ vdev_nss->ibss = nss_val - coex;
+ vdev_nss->tdls = nss_val - coex;
+ vdev_nss->ocb = nss_val - coex;
+
+ vdev_nss = &mac_ctx->vdev_type_nss_5g;
+ coex = 0;
+ }
+}
+
+/**
+ * sme_update_vdev_type_nss() - sets the nss per vdev type
+ * @hal: Pointer to HAL
+ * @max_supp_nss: max_supported Nss
+ * @band: 5G or 2.4G band
+ *
+ * Sets the per band Nss for each vdev type based on INI and configured
+ * chain mask value.
+ *
+ * Return: None
+ */
+void sme_update_vdev_type_nss(tHalHandle hal, uint8_t max_supp_nss,
+ uint32_t vdev_type_nss, eCsrBand band)
+{
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ struct vdev_type_nss *vdev_nss;
+
+ if (eCSR_BAND_5G == band) {
+ vdev_nss = &mac_ctx->vdev_type_nss_5g;
+ } else {
+ vdev_nss = &mac_ctx->vdev_type_nss_2g;
+ }
+
+ vdev_nss->sta = VOS_MIN(max_supp_nss, CFG_STA_NSS(vdev_type_nss));
+ vdev_nss->sap = VOS_MIN(max_supp_nss, CFG_SAP_NSS(vdev_type_nss));
+ vdev_nss->p2p_go = VOS_MIN(max_supp_nss,
+ CFG_P2P_GO_NSS(vdev_type_nss));
+ vdev_nss->p2p_cli = VOS_MIN(max_supp_nss,
+ CFG_P2P_CLI_NSS(vdev_type_nss));
+ vdev_nss->p2p_dev = VOS_MIN(max_supp_nss,
+ CFG_P2P_DEV_NSS(vdev_type_nss));
+ vdev_nss->ibss = VOS_MIN(max_supp_nss, CFG_IBSS_NSS(vdev_type_nss));
+ vdev_nss->tdls = VOS_MIN(max_supp_nss, CFG_TDLS_NSS(vdev_type_nss));
+ vdev_nss->ocb = VOS_MIN(max_supp_nss, CFG_OCB_NSS(vdev_type_nss));
+
+ smsLog(mac_ctx, LOG1,
+ "band %d NSS: sta %d sap %d cli %d go %d dev %d ibss %d tdls %d ocb %d",
+ band, vdev_nss->sta, vdev_nss->sap, vdev_nss->p2p_cli,
+ vdev_nss->p2p_go, vdev_nss->p2p_dev, vdev_nss->ibss,
+ vdev_nss->tdls, vdev_nss->ocb);
+}
+
+/**
+ * sme_set_per_band_chainmask_supp() - sets the per band chainmask support
+ * @hal: Pointer to HAL
+ * @val: Value to be set.
+ *
+ * Sets the per band chain mask support to mac context.
+ * Return: None
+ */
+void sme_set_per_band_chainmask_supp(tHalHandle hal, bool val)
+{
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ mac_ctx->per_band_chainmask_supp = val;
+}
+
+/**
+ * sme_set_lte_coex_supp() - sets the lte coex antenna share support
+ * @hal: Pointer to HAL
+ * @val: Value to be set.
+ *
+ * Sets the lte coex antenna share support to mac context.
+ * Return: None
+ */
+void sme_set_lte_coex_supp(tHalHandle hal, bool val)
+{
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ mac_ctx->lteCoexAntShare = val;
+}
+
+/**
+ * sme_set_bcon_offload_supp() - sets the beacon offload support
+ * @hal: Pointer to HAL
+ * @val: Value to be set.
+ *
+ * Sets the beacon offload support to mac context.
+ * Return: None
+ */
+void sme_set_bcon_offload_supp(tHalHandle hal, bool val)
+{
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ mac_ctx->beacon_offload = val;
+}
+
diff --git a/CORE/SYS/legacy/src/utils/src/parserApi.c b/CORE/SYS/legacy/src/utils/src/parserApi.c
index 1290ea8ff091..5a6aff37e15a 100644
--- a/CORE/SYS/legacy/src/utils/src/parserApi.c
+++ b/CORE/SYS/legacy/src/utils/src/parserApi.c
@@ -728,18 +728,19 @@ PopulateDot11fHTCaps(tpAniSirGlobal pMac,
pDot11f->supportedMCSSet, nCfgLen,
SIZE_OF_SUPPORTED_MCS_SET );
- if (psessionEntry)
- {
- if (pMac->lteCoexAntShare && (IS_24G_CH(psessionEntry->currentOperChannel)))
- {
- if(!(IS_2X2_CHAIN(psessionEntry->chainMask)))
- {
+ if (!pMac->per_band_chainmask_supp) {
+ if (psessionEntry && (pMac->lteCoexAntShare &&
+ (IS_24G_CH(psessionEntry->currentOperChannel)))) {
+ if(!(IS_2X2_CHAIN(psessionEntry->chainMask))) {
pDot11f->supportedMCSSet[1] = 0;
if (LIM_IS_STA_ROLE(psessionEntry)) {
pDot11f->mimoPowerSave = psessionEntry->smpsMode;
}
}
}
+ } else {
+ if (psessionEntry && psessionEntry->vdev_nss == 1)
+ pDot11f->supportedMCSSet[1] = 0;
}
CFG_GET_INT( nSirStatus, pMac, WNI_CFG_EXT_HT_CAP_INFO, nCfgValue );
@@ -1029,16 +1030,21 @@ PopulateDot11fVHTCaps(tpAniSirGlobal pMac,
nCfgValue = 0;
CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TX_MCS_MAP, nCfgValue );
pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF);
- if (psessionEntry)
- {
- if (pMac->lteCoexAntShare && (IS_24G_CH(psessionEntry->currentOperChannel)))
- {
- if(!(IS_2X2_CHAIN(psessionEntry->chainMask)))
- {
- pDot11f->txMCSMap |= DISABLE_NSS2_MCS;
- pDot11f->rxMCSMap |= DISABLE_NSS2_MCS;
+ if (!pMac->per_band_chainmask_supp) {
+ if (psessionEntry) {
+ if (pMac->lteCoexAntShare &&
+ (IS_24G_CH(psessionEntry->currentOperChannel))) {
+ if(!(IS_2X2_CHAIN(psessionEntry->chainMask))) {
+ pDot11f->txMCSMap |= DISABLE_NSS2_MCS;
+ pDot11f->rxMCSMap |= DISABLE_NSS2_MCS;
+ }
+ }
+ }
+ } else {
+ if (psessionEntry && psessionEntry->vdev_nss == 1) {
+ pDot11f->txMCSMap |= DISABLE_NSS2_MCS;
+ pDot11f->rxMCSMap |= DISABLE_NSS2_MCS;
}
- }
}
nCfgValue = 0;
diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h
index ffc953f342cf..57a63effc778 100644
--- a/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/CORE/WDA/inc/legacy/halMsgApi.h
@@ -537,6 +537,8 @@ typedef struct
tANI_U8 dot11_mode;
tANI_U8 nonRoamReassoc;
uint8_t wps_state;
+ uint8_t nss_2g;
+ uint8_t nss_5g;
} tAddBssParams, * tpAddBssParams;
typedef struct
@@ -1426,8 +1428,31 @@ typedef struct sAddStaSelfParams
tANI_U8 sessionId;
tANI_U32 status;
tANI_U16 pkt_err_disconn_th;
+ uint8_t nss_2g;
+ uint8_t nss_5g;
}tAddStaSelfParams, *tpAddStaSelfParams;
+/**
+ * struct set_ie_param - set IE params structure
+ * @pdev_id: pdev id
+ * @ie_type: IE type
+ * @nss: Nss value
+ * @ie_len: IE length
+ * @*ie_ptr: Pointer to IE data
+ *
+ * Holds the set pdev IE req data.
+ */
+struct set_ie_param {
+ uint8_t pdev_id;
+ uint8_t ie_type;
+ uint8_t nss;
+ uint8_t ie_len;
+ uint8_t *ie_ptr;
+};
+
+#define DOT11_HT_IE 1
+#define DOT11_VHT_IE 2
+
#ifdef FEATURE_WLAN_TDLS
#define HAL_TDLS_MAX_SUPP_CHANNELS 128
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index ee7845b4a5d9..250271960ee0 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -888,6 +888,7 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#define WDA_CLI_SET_CMD SIR_HAL_CLI_SET_CMD
#define WDA_CLI_GET_CMD SIR_HAL_CLI_GET_CMD
+#define WDA_SET_PDEV_IE_REQ SIR_HAL_SET_PDEV_IE_REQ
#ifdef FEATURE_WLAN_SCAN_PNO
#define WDA_SME_SCAN_CACHE_UPDATED SIR_HAL_SME_SCAN_CACHE_UPDATED
#endif