From 666bf8591bef38e2930236766b5e0042bb2f82a5 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Mon, 2 May 2016 12:23:02 -0700 Subject: [PATCH] qcacld-3.0: Add support for NSS configurability qcacld-2.0 to qcacld-3.0 propagation Add support for NSS configurability per vdev type - 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 include them in scan probe request frames Change-Id: I5cbf17a14ab6becad6cf5765ae5039fc284dc309 CRs-Fixed: 869026 --- core/hdd/inc/wlan_hdd_cfg.h | 23 ++ core/hdd/inc/wlan_hdd_main.h | 6 - core/hdd/src/wlan_hdd_cfg.c | 68 ++-- core/hdd/src/wlan_hdd_main.c | 70 +++- core/mac/inc/ani_global.h | 48 +++ core/mac/inc/sir_api.h | 21 ++ core/mac/inc/sir_mac_prot_def.h | 6 + core/mac/inc/wni_api.h | 1 + core/mac/src/include/parser_api.h | 3 + core/mac/src/include/sir_params.h | 1 + core/mac/src/pe/include/lim_session.h | 1 + core/mac/src/pe/lim/lim_assoc_utils.c | 17 +- .../src/pe/lim/lim_process_message_queue.c | 1 + .../src/pe/lim/lim_process_sme_req_messages.c | 314 ++++++++++++++---- core/sme/inc/sme_api.h | 5 + core/sme/inc/sme_inside.h | 3 + core/sme/src/common/sme_api.c | 109 +++++- core/sme/src/csr/csr_api_roam.c | 77 +++++ core/wma/inc/wma.h | 8 + core/wma/inc/wma_if.h | 27 ++ core/wma/inc/wma_tgt_cfg.h | 2 + core/wma/inc/wma_types.h | 5 +- core/wma/src/wma_dev_if.c | 2 + core/wma/src/wma_main.c | 8 + core/wma/src/wma_scan_roam.c | 147 +++++++- 25 files changed, 846 insertions(+), 127 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index f0212b7476..367d702cd8 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -1119,6 +1119,27 @@ typedef enum { #define CFG_VHT_ENABLE_2x2_CAP_FEATURE_MAX (1) #define CFG_VHT_ENABLE_2x2_CAP_FEATURE_DEFAULT (0) +/* + * 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) @@ -3681,6 +3702,8 @@ struct hdd_config { uint8_t vhtRxMCS2x2; uint8_t vhtTxMCS2x2; bool enable2x2; + uint32_t vdev_type_nss_2g; + uint32_t vdev_type_nss_5g; bool txchainmask1x1; bool rxchainmask1x1; bool enableMuBformee; diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 5403a4b4cf..c4df74ab4d 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -319,12 +319,6 @@ extern spinlock_t hdd_context_lock; #define WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME 100 #define WLAN_HDD_TX_FLOW_CONTROL_MAX_24BAND_CH 14 -#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 - - #define NUM_TX_RX_HISTOGRAM 1024 #define NUM_TX_RX_HISTOGRAM_MASK (NUM_TX_RX_HISTOGRAM - 1) diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 137a719c15..af43bf1f7d 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -2094,6 +2094,20 @@ REG_TABLE_ENTRY g_registry_table[] = { CFG_VHT_ENABLE_2x2_CAP_FEATURE_MIN, CFG_VHT_ENABLE_2x2_CAP_FEATURE_MAX), + REG_VARIABLE(CFG_VDEV_TYPE_NSS_2G, WLAN_PARAM_Integer, + struct hdd_config, 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, + struct hdd_config, 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, struct hdd_config, enableMuBformee, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -6478,48 +6492,6 @@ bool hdd_update_config_dat(hdd_context_t *pHddCtx) if ((pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO) || (pConfig->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) || (pConfig->dot11Mode == eHDD_DOT11_MODE_11ac)) { - uint32_t temp = 0; - - sme_cfg_get_int(pHddCtx->hHal, - WNI_CFG_VHT_BASIC_MCS_SET, &temp); - temp = (temp & 0xFFFC) | pConfig->vhtRxMCS; - if (pConfig->enable2x2) - temp = (temp & 0xFFF3) | (pConfig->vhtRxMCS2x2 << 2); - if (sme_cfg_set_int(pHddCtx->hHal, - WNI_CFG_VHT_BASIC_MCS_SET, temp) == - QDF_STATUS_E_FAILURE) { - fStatus = false; - hddLog(LOGE, - "Could not pass on WNI_CFG_VHT_BASIC_MCS_SET to CFG"); - } - - sme_cfg_get_int(pHddCtx->hHal, WNI_CFG_VHT_RX_MCS_MAP, - &temp); - temp = (temp & 0xFFFC) | pConfig->vhtRxMCS; - if (pConfig->enable2x2) - temp = (temp & 0xFFF3) | (pConfig->vhtRxMCS2x2 << 2); - if (sme_cfg_set_int(pHddCtx->hHal, - WNI_CFG_VHT_RX_MCS_MAP, temp) - == QDF_STATUS_E_FAILURE) { - fStatus = false; - hddLog(LOGE, - "Could not pass on WNI_CFG_VHT_RX_MCS_MAP to CFG"); - } - sme_cfg_get_int(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp); - temp = (temp & 0xFFFC) | pConfig->vhtTxMCS; - if (pConfig->enable2x2) - temp = (temp & 0xFFF3) | (pConfig->vhtTxMCS2x2 << 2); - QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_HIGH, - "vhtRxMCS2x2 - %x temp - %u enable2x2 %d", - pConfig->vhtRxMCS2x2, temp, - pConfig->enable2x2); - - if (sme_cfg_set_int(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP, - temp) == QDF_STATUS_E_FAILURE) { - fStatus = false; - hddLog(LOGE, - "Could not pass on WNI_CFG_VHT_TX_MCS_MAP to CFG"); - } /* Currently shortGI40Mhz is used for shortGI80Mhz */ if (sme_cfg_set_int (pHddCtx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ, @@ -6542,9 +6514,9 @@ bool hdd_update_config_dat(hdd_context_t *pHddCtx) /* Change MU Bformee only when TxBF is enabled */ if (pConfig->enableTxBF) { sme_cfg_get_int(pHddCtx->hHal, - WNI_CFG_VHT_MU_BEAMFORMEE_CAP, &temp); + WNI_CFG_VHT_MU_BEAMFORMEE_CAP, &val); - if (temp != pConfig->enableMuBformee) { + if (val != pConfig->enableMuBformee) { if (sme_cfg_set_int(pHddCtx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP, pConfig->enableMuBformee @@ -7299,12 +7271,12 @@ QDF_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 1f8f8545bd..a9245e0069 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -816,6 +816,29 @@ static void hdd_update_tgt_services(hdd_context_t *hdd_ctx, } +/** + * hdd_update_vdev_nss() - sets the vdev nss + * @hdd_ctx: HDD context + * + * Sets the Nss per vdev type based on INI + * + * Return: None + */ +static void hdd_update_vdev_nss(hdd_context_t *hdd_ctx) +{ + struct hdd_config *cfg_ini = hdd_ctx->config; + uint8_t max_supp_nss = 1; + + if (cfg_ini->enable2x2) + max_supp_nss = 2; + + sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss, + cfg_ini->vdev_type_nss_2g, eCSR_BAND_24); + + 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, struct wma_tgt_ht_cap *cfg) { @@ -888,7 +911,7 @@ static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx, /* Update Rx Highest Long GI data Rate */ if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE, - HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1) + VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1) == QDF_STATUS_E_FAILURE) { hddLog(LOGE, FL( @@ -900,12 +923,11 @@ static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx, if (sme_cfg_set_int (hdd_ctx->hHal, WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE, - HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1) == + VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1) == QDF_STATUS_E_FAILURE) { hddLog(LOGE, FL( - "Could not pass on HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1 to CCM" - )); + "VHT_TX_HIGHEST_SUPP_RATE_1_1 to CCM fail")); } } if (!(cfg->ht_tx_stbc && pconfig->enable2x2)) @@ -950,6 +972,7 @@ static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx, struct wiphy *wiphy = hdd_ctx->wiphy; struct ieee80211_supported_band *band_5g = wiphy->bands[IEEE80211_BAND_5GHZ]; + uint32_t temp = 0; /* Get the current MPDU length */ status = @@ -988,9 +1011,41 @@ static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx, value = 0; } + sme_cfg_get_int(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 (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, temp) == + QDF_STATUS_E_FAILURE) { + hdd_err("Could not pass VHT_BASIC_MCS_SET to CCM"); + } + + sme_cfg_get_int(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 (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, temp) == + QDF_STATUS_E_FAILURE) { + hdd_err("Could not pass WNI_CFG_VHT_RX_MCS_MAP to CCM"); + } + + sme_cfg_get_int(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); + + hdd_info("vhtRxMCS2x2 - %x temp - %u enable2x2 %d", + pconfig->vhtRxMCS2x2, temp, pconfig->enable2x2); + + if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, temp) == + QDF_STATUS_E_FAILURE) { + hdd_err("Could not pass WNI_CFG_VHT_TX_MCS_MAP to CCM"); + } /* Get the current RX LDPC setting */ - status = - sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP, + status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP, &value); if (status != QDF_STATUS_SUCCESS) { @@ -1319,6 +1374,8 @@ 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); + hdd_update_vdev_nss(hdd_ctx); + hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap); hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap); @@ -2164,6 +2221,7 @@ QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter) INIT_COMPLETION(adapter->session_open_comp_var); sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode); + sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2); status = cds_get_vdev_types(adapter->device_mode, &type, &subType); if (QDF_STATUS_SUCCESS != status) { hddLog(LOGE, FL("failed to get vdev type")); diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index 1e70972a16..ec52065e6b 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -113,6 +113,27 @@ typedef struct sAniSirGlobal *tpAniSirGlobal; /* Minimum size of vendor IE = 3 bytes of oui_data + 1 byte of data */ #define IE_VENDOR_OUI_SIZE (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_IBSS_NSS(_x) ((((_x) >> 8) & 0x3) ? (((_x) >> 8) & 0x3) : 1) +#define CFG_TDLS_NSS(_x) ((((_x) >> 10) & 0x3) ? (((_x) >> 10) & 0x3) : 1) +#define CFG_P2P_DEV_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 @@ -966,6 +987,29 @@ enum auth_tx_ack_status { LIM_AUTH_ACK_RCD_SUCCESS, LIM_AUTH_ACK_RCD_FAILURE, }; +/** + * 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 */ @@ -1027,6 +1071,10 @@ typedef struct sAniSirGlobal { hdd_ftm_msg_processor ftm_msg_processor_callback; bool policy_manager_enabled; 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; /* 802.11p enable */ bool enable_dot11p; diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index c0b33c94f2..c24ec17fcb 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -3657,6 +3657,9 @@ typedef struct sSirUpdateChanParam { typedef struct sSirUpdateChan { uint8_t numChan; + uint8_t ht_en; + uint8_t vht_en; + uint8_t vht_24_en; tSirUpdateChanParam chanParam[1]; } tSirUpdateChanList, *tpSirUpdateChanList; @@ -4712,6 +4715,24 @@ 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/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index 596f558896..4aaac56796 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -390,7 +390,13 @@ #define SIR_MAC_VHT_OPMODE_EID 199 #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 diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index e6dfb2dda6..160ada158e 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -250,6 +250,7 @@ enum eWniMsgTypes { eWNI_SME_SET_ANTENNA_MODE_RESP, eWNI_SME_TSF_EVENT, eWNI_SME_MON_INIT_SESSION, + eWNI_SME_PDEV_SET_HT_VHT_IE, eWNI_SME_MSG_TYPES_END }; diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h index 2156676733..7019d99d31 100644 --- a/core/mac/src/include/parser_api.h +++ b/core/mac/src/include/parser_api.h @@ -55,6 +55,9 @@ #define IS_2X2_CHAIN(__chain) ((__chain & 0x3) == 0x3) #define DISABLE_NSS2_MCS 0xC +#define NSS_1x1_MODE 1 +#define NSS_2x2_MODE 2 + #ifdef FEATURE_AP_MCC_CH_AVOIDANCE #define QCOM_VENDOR_IE_MCC_AVOID_CH 0x01 diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 476e4a68b7..26910c801f 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -611,6 +611,7 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_SET_WISA_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 343) #define SIR_HAL_SET_ADAPT_DWELLTIME_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 344) +#define SIR_HAL_SET_PDEV_IE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 345) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) /* CFG message types */ diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index a5bf8f77f0..8f3f118cd4 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -475,6 +475,7 @@ typedef struct sPESession /* Added to Support BT-AMP */ bool add_bss_failed; /* To hold OBSS Scan IE Parameters */ struct obss_scanparam obss_ht40_scanparam; + uint8_t vdev_nss; /* Supported NSS is intersection of self and peer NSS */ bool supported_nss_1x1; bool is_ext_caps_present; diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index 7144f945af..2a1dfec655 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -1409,8 +1409,8 @@ tSirRetStatus lim_populate_vht_mcs_set(tpAniSirGlobal mac_ctx, QDF_MIN(rates->vhtRxHighestDataRate, peer_vht_caps->rxHighSupDataRate); - if (mac_ctx->roam.configParam.enable2x2) { - if (session_entry && mac_ctx->lteCoexAntShare && + if (session_entry && session_entry->vdev_nss == 2) { + if (mac_ctx->lteCoexAntShare && IS_24G_CH(session_entry->currentOperChannel)) { if (IS_2X2_CHAIN(session_entry->chainMask)) mcs_map_mask2x2 = MCSMAPMASK2x2; @@ -1627,6 +1627,8 @@ lim_populate_own_rate_set(tpAniSirGlobal mac_ctx, return eSIR_FAILURE; } + if (session_entry->vdev_nss == 1) + rates->supportedMCSSet[1] = 0; /* * if supported MCS Set of the peer is passed in, * then do the intersection @@ -1766,8 +1768,12 @@ lim_populate_peer_rate_set(tpAniSirGlobal pMac, ) return eSIR_FAILURE; } - /* if supported MCS Set of the peer is passed in, then do the intersection */ - /* else use the MCS set from local CFG. */ + 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) { for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) pRates->supportedMCSSet[i] &= @@ -1991,6 +1997,9 @@ tSirRetStatus lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx, return eSIR_FAILURE; } + if (session_entry->vdev_nss == 1) + mcs_set[1] = 0; + for (i = 0; i < val; i++) sta_ds->supportedRates.supportedMCSSet[i] = mcs_set[i] & supported_mcs_set[i]; diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index bebe8120da..d8031c2c5b 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1414,6 +1414,7 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) msg->bodyptr = NULL; } break; + case eWNI_SME_PDEV_SET_HT_VHT_IE: case eWNI_SME_SYS_READY_IND: case eWNI_SME_JOIN_REQ: case eWNI_SME_REASSOC_REQ: diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index e58f600201..f2d1d99ad9 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -116,7 +116,6 @@ static void lim_process_update_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg); extern void pe_register_wma_handle(tpAniSirGlobal pMac, tSirSmeReadyReq *ready_req); - static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx, uint32_t *msg); @@ -224,7 +223,7 @@ static QDF_STATUS lim_process_set_dual_mac_cfg_req(tpAniSirGlobal mac, req_msg = qdf_mem_malloc(len); if (!req_msg) { - lim_log(mac, LOGE, FL("vos_mem_malloc failed")); + lim_log(mac, LOGE, FL("qdf_mem_malloc failed")); /* Free the active command list * Probably the malloc is going to fail there as well?! */ @@ -631,6 +630,7 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) uint8_t sme_session_id = 0; uint16_t sme_transaction_id = 0; uint32_t chanwidth; + struct vdev_type_nss *vdev_type_nss; tSirRetStatus cfg_get_wmi_dfs_master_param = eSIR_SUCCESS; /* FEATURE_WLAN_DIAG_SUPPORT */ @@ -779,10 +779,6 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) session->vhtCapability); session->txLdpcIniFeatureEnabled = sme_start_bss_req->txLdpcIniFeatureEnabled; - if (mac_ctx->roam.configParam.enable2x2) - session->nss = 2; - else - session->nss = 1; #ifdef WLAN_FEATURE_11W session->limRmfEnabled = sme_start_bss_req->pmfCapable ? 1 : 0; @@ -797,6 +793,11 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) (void *)&sme_start_bss_req->extendedRateSet, sizeof(tSirMacRateSet)); + if (IS_5G_CH(session->currentOperChannel)) + vdev_type_nss = &mac_ctx->vdev_type_nss_5g; + else + vdev_type_nss = &mac_ctx->vdev_type_nss_2g; + switch (sme_start_bss_req->bssType) { case eSIR_INFRA_AP_MODE: lim_configure_ap_start_bss_session(mac_ctx, session, @@ -806,6 +807,9 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) sme_start_bss_req->txbf_ini_enabled; session->txbf_csn_value = sme_start_bss_req->txbf_csn_val; + session->vdev_nss = vdev_type_nss->sap; + } else { + session->vdev_nss = vdev_type_nss->p2p_go; } break; case eSIR_IBSS_MODE: @@ -819,6 +823,7 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) * will be updated upon key installation */ session->encryptType = eSIR_ED_NONE; + session->vdev_nss = vdev_type_nss->ibss; break; @@ -834,6 +839,9 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) break; } + lim_log(mac_ctx, LOG1, FL("persona - %d, nss - %d"), + session->pePersona, session->vdev_nss); + session->nss = session->vdev_nss; /* * Allocate memory for the array of * parsed (Re)Assoc request structure @@ -1202,7 +1210,8 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac, uint8_t *ht_cap_ie; tSirMsgQ msg; uint16_t i, len; - uint16_t ht_cap_len = 0, addn_ie_len = 0; + uint16_t ht_cap_len = 0; + uint16_t addn_ie_len = 0; uint8_t *vht_cap_ie; uint16_t vht_cap_len = 0; tSirRetStatus status, rc = eSIR_SUCCESS; @@ -1236,29 +1245,30 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac, * so allocate the memory for (numChannels - 1) and uIEFieldLen */ len = sizeof(tSirScanOffloadReq) + - (pScanReq->channelList.numChannels - 1) + pScanReq->uIEFieldLen; + (pScanReq->channelList.numChannels - 1) + + pScanReq->uIEFieldLen; + if (!pMac->per_band_chainmask_supp) { + if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) { + lim_log(pMac, LOG1, FL( + "Adding HT Caps IE since dot11mode=%d"), + pScanReq->dot11mode); + /* 2 bytes for EID and Length */ + ht_cap_len = 2 + sizeof(tHtCaps); + len += ht_cap_len; + addn_ie_len += ht_cap_len; + } - if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) { - lim_log(pMac, LOG1, - FL("Adding HT Caps IE since dot11mode=%d"), - pScanReq->dot11mode); - /* 2 bytes for EID and Length */ - ht_cap_len = 2 + sizeof(tHtCaps); - len += ht_cap_len; - addn_ie_len += ht_cap_len; + if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) { + lim_log(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)) { - lim_log(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; - } - pScanOffloadReq = qdf_mem_malloc(len); if (NULL == pScanOffloadReq) { lim_log(pMac, LOGE, @@ -1331,33 +1341,33 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac, pScanOffloadReq->uIEFieldOffset, (uint8_t *) pScanReq + pScanReq->uIEFieldOffset, pScanReq->uIEFieldLen); + 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 = (uint8_t *) pScanOffloadReq + + pScanOffloadReq->uIEFieldOffset + + pScanOffloadReq->uIEFieldLen; + qdf_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; + } - /* Copy HT Capability info if dot11mode is HT */ - if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) { - /* Populate EID and Length field here */ - ht_cap_ie = (uint8_t *) pScanOffloadReq + - pScanOffloadReq->uIEFieldOffset + - pScanOffloadReq->uIEFieldLen; - qdf_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; + /* 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 = (uint8_t *) pScanOffloadReq + + pScanOffloadReq->uIEFieldOffset + + pScanOffloadReq->uIEFieldLen; + qdf_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; + } } - - /* 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 = (uint8_t *) pScanOffloadReq + - pScanOffloadReq->uIEFieldOffset + - pScanOffloadReq->uIEFieldLen; - qdf_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; - } - rc = wma_post_ctrl_msg(pMac, &msg); if (rc != eSIR_SUCCESS) { lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure")); @@ -1570,6 +1580,7 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) uint16_t ie_len; uint8_t *vendor_ie; tSirBssDescription *bss_desc; + struct vdev_type_nss *vdev_type_nss; /* FEATURE_WLAN_DIAG_SUPPORT */ #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM @@ -1750,10 +1761,23 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) session->supported_nss_1x1, session->pePersona, sme_join_req->cbMode); - if (mac_ctx->roam.configParam.enable2x2) - session->nss = 2; + + /*Store Persona */ + session->pePersona = sme_join_req->staPersona; + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, + FL("PE PERSONA=%d cbMode %u"), + session->pePersona, sme_join_req->cbMode); + /* Copy The channel Id to the session Table */ + session->currentOperChannel = bss_desc->channelId; + if (IS_5G_CH(session->currentOperChannel)) + vdev_type_nss = &mac_ctx->vdev_type_nss_5g; else - session->nss = 1; + vdev_type_nss = &mac_ctx->vdev_type_nss_2g; + if (session->pePersona == QDF_P2P_CLIENT_MODE) + session->vdev_nss = vdev_type_nss->p2p_cli; + else + session->vdev_nss = vdev_type_nss->sta; + session->nss = session->vdev_nss; session->vhtCapability = IS_DOT11_MODE_VHT(session->dot11mode); if (session->vhtCapability) { @@ -1801,8 +1825,6 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) /*Phy mode */ session->gLimPhyMode = bss_desc->nwType; handle_ht_capabilityand_ht_info(mac_ctx, session); - /* Copy The channel Id to the session Table */ - session->currentOperChannel = bss_desc->channelId; /* cbMode is already merged value of peer and self - * done by csr in csr_get_cb_mode_from_ies */ session->htSupportedChannelWidthSet = @@ -4697,6 +4719,179 @@ static void lim_register_mgmt_frame_ind_cb(tpAniSirGlobal mac_ctx, lim_log(mac_ctx, LOGE, FL("sme_req->callback is null")); } +/** + * 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, uint8_t pdev_id, + uint8_t nss) +{ + struct set_ie_param *ie_params; + tSirMsgQ msg; + tSirRetStatus rc = eSIR_SUCCESS; + uint8_t *p_ie = NULL; + tHtCaps *p_ht_cap; + int i; + + for (i = nss; i > 0; i--) { + ie_params = qdf_mem_malloc(sizeof(*ie_params)); + if (NULL == ie_params) { + lim_log(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 = qdf_mem_malloc(ie_params->ie_len); + if (NULL == ie_params->ie_ptr) { + qdf_mem_free(ie_params); + lim_log(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 (NSS_1x1_MODE == i) { + p_ie = lim_get_ie_ptr_new(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 = WMA_SET_PDEV_IE_REQ; + msg.bodyptr = ie_params; + msg.bodyval = 0; + + rc = wma_post_ctrl_msg(mac_ctx, &msg); + if (rc != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("wma_post_ctrl_msg() return failure")); + qdf_mem_free(ie_params->ie_ptr); + qdf_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, uint8_t pdev_id, + uint8_t nss) +{ + struct set_ie_param *ie_params; + tSirMsgQ msg; + tSirRetStatus rc = eSIR_SUCCESS; + uint8_t *p_ie = NULL; + tSirMacVHTCapabilityInfo *vht_cap; + int i; + tSirVhtMcsInfo *vht_mcs; + + for (i = nss; i > 0; i--) { + ie_params = qdf_mem_malloc(sizeof(*ie_params)); + if (NULL == ie_params) { + lim_log(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 = qdf_mem_malloc(ie_params->ie_len); + if (NULL == ie_params->ie_ptr) { + qdf_mem_free(ie_params); + lim_log(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 (NSS_1x1_MODE == i) { + p_ie = lim_get_ie_ptr_new(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 = WMA_SET_PDEV_IE_REQ; + msg.bodyptr = ie_params; + msg.bodyval = 0; + + rc = wma_post_ctrl_msg(mac_ctx, &msg); + if (rc != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("wma_post_ctrl_msg failure")); + qdf_mem_free(ie_params->ie_ptr); + qdf_mem_free(ie_params); + return; + } + } +} + +/** + * 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, uint32_t *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) { + lim_log(mac_ctx, LOGE, FL("NULL ht_vht_cfg")); + return; + } + + lim_log(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_process_sme_req_messages() * @@ -4938,6 +5133,9 @@ bool lim_process_sme_req_messages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) case eWNI_SME_SET_ANTENNA_MODE_REQ: lim_process_set_antenna_mode_req(pMac, pMsgBuf); break; + case eWNI_SME_PDEV_SET_HT_VHT_IE: + lim_process_set_pdev_IEs(pMac, pMsgBuf); + break; default: qdf_mem_free((void *)pMsg->bodyptr); pMsg->bodyptr = NULL; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 6cebcff387..11557c7b23 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -82,6 +82,7 @@ #define SME_CONFIG_TO_ROAM_CONFIG 1 #define ROAM_CONFIG_TO_SME_CONFIG 2 +#define NUM_OF_BANDS 2 /*-------------------------------------------------------------------------- Type declarations ------------------------------------------------------------------------*/ @@ -1123,4 +1124,8 @@ uint32_t sme_get_wni_dot11_mode(tHalHandle hal); QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, uint8_t *bssid); QDF_STATUS sme_set_adaptive_dwelltime_config(tHalHandle hal, struct adaptive_dwelltime_params *dwelltime_params); +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); #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/inc/sme_inside.h b/core/sme/inc/sme_inside.h index cf5614ded5..5a6600a7d9 100644 --- a/core/sme/inc/sme_inside.h +++ b/core/sme/inc/sme_inside.h @@ -230,6 +230,9 @@ QDF_STATUS oem_data_process_oem_data_req_command(tpAniSirGlobal pMac, tSmeCmd *pCommand); #endif +void csr_get_vdev_type_nss(tpAniSirGlobal mac_ctx, + enum tQDF_ADAPTER_MODE dev_mode, + uint8_t *nss_2g, uint8_t *nss_5g); QDF_STATUS csr_process_add_sta_session_command(tpAniSirGlobal pMac, tSmeCmd *pCommand); QDF_STATUS csr_process_add_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 011227bd8b..e8abaa9ed3 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -15112,6 +15112,7 @@ void sme_update_tgt_services(tHalHandle hal, struct wma_tgt_services *cfg) tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); mac_ctx->lteCoexAntShare = cfg->lte_coex_ant_share; + mac_ctx->per_band_chainmask_supp = cfg->per_band_chainmask_supp; mac_ctx->beacon_offload = cfg->beacon_offload; mac_ctx->pmf_offload = cfg->pmf_offload; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, @@ -15576,7 +15577,6 @@ QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id) return status; } - /** * sme_set_adaptive_dwelltime_config() - Update Adaptive dwelltime configuration * @hal: The handle returned by macOpen @@ -15616,3 +15616,110 @@ QDF_STATUS sme_set_adaptive_dwelltime_config(tHalHandle hal, } return status; } +/** + * 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; + QDF_STATUS status = QDF_STATUS_E_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_acquire_global_lock(&mac_ctx->sme); + if (QDF_STATUS_SUCCESS == status) { + ht_vht_cfg = qdf_mem_malloc(sizeof(*ht_vht_cfg)); + if (NULL == ht_vht_cfg) { + sms_log(mac_ctx, LOGE, + "%s: mem alloc failed for ht_vht_cfg", + __func__); + sme_release_global_lock(&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 = + (uint8_t)csr_translate_to_wni_cfg_dot11_mode(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); + sms_log(mac_ctx, LOG1, + FL("SET_HT_VHT_IE with nss %d, dot11mode %d"), + ht_vht_cfg->nss, + ht_vht_cfg->dot11mode); + status = cds_send_mb_message_to_mac(ht_vht_cfg); + if (QDF_STATUS_SUCCESS != status) { + sms_log(mac_ctx, LOGE, FL( + "Send SME_PDEV_SET_HT_VHT_IE fail")); + qdf_mem_free(ht_vht_cfg); + } + sme_release_global_lock(&mac_ctx->sme); + } + return; +} + +/** + * 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 = QDF_MIN(max_supp_nss, CFG_STA_NSS(vdev_type_nss)); + vdev_nss->sap = QDF_MIN(max_supp_nss, CFG_SAP_NSS(vdev_type_nss)); + vdev_nss->p2p_go = QDF_MIN(max_supp_nss, + CFG_P2P_GO_NSS(vdev_type_nss)); + vdev_nss->p2p_cli = QDF_MIN(max_supp_nss, + CFG_P2P_CLI_NSS(vdev_type_nss)); + vdev_nss->p2p_dev = QDF_MIN(max_supp_nss, + CFG_P2P_DEV_NSS(vdev_type_nss)); + vdev_nss->ibss = QDF_MIN(max_supp_nss, CFG_IBSS_NSS(vdev_type_nss)); + vdev_nss->tdls = QDF_MIN(max_supp_nss, CFG_TDLS_NSS(vdev_type_nss)); + vdev_nss->ocb = QDF_MIN(max_supp_nss, CFG_OCB_NSS(vdev_type_nss)); + + sms_log(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); +} diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index e2a35a7ca3..4de79eb91d 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -754,6 +754,24 @@ QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac) QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, FL("Early Stop Scan Feature not supported")); + 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 = WMA_UPDATE_CHAN_LIST_REQ; msg.reserved = 0; msg.bodyptr = pChanList; @@ -14853,6 +14871,59 @@ QDF_STATUS csr_process_add_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg) return QDF_STATUS_SUCCESS; } +/** + * 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, + enum tQDF_ADAPTER_MODE dev_mode, + uint8_t *nss_2g, uint8_t *nss_5g) +{ + switch (dev_mode) { + case QDF_STA_MODE: + *nss_2g = mac_ctx->vdev_type_nss_2g.sta; + *nss_5g = mac_ctx->vdev_type_nss_5g.sta; + break; + case QDF_SAP_MODE: + *nss_2g = mac_ctx->vdev_type_nss_2g.sap; + *nss_5g = mac_ctx->vdev_type_nss_5g.sap; + break; + case QDF_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 QDF_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 QDF_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 QDF_IBSS_MODE: + *nss_2g = mac_ctx->vdev_type_nss_2g.ibss; + *nss_5g = mac_ctx->vdev_type_nss_5g.ibss; + break; + case QDF_OCB_MODE: + *nss_2g = mac_ctx->vdev_type_nss_2g.ocb; + *nss_5g = mac_ctx->vdev_type_nss_5g.ocb; + break; + default: + *nss_2g = 1; + *nss_5g = 1; + sms_log(mac_ctx, LOGE, FL("Unknown device mode")); + break; + } + sms_log(mac_ctx, LOG1, FL("mode - %d: nss_2g - %d, 5g - %d"), + dev_mode, *nss_2g, *nss_5g); +} QDF_STATUS csr_issue_add_sta_for_session_req(tpAniSirGlobal pMac, uint32_t sessionId, tSirMacAddr sessionMacAddr, uint32_t type, uint32_t subType) @@ -14888,6 +14959,8 @@ QDF_STATUS csr_process_add_sta_session_command(tpAniSirGlobal pMac, &pCommand->u.addStaSessionCmd; uint8_t sessionId = pCommand->sessionId; struct add_sta_self_params *add_sta_self_req; + uint8_t nss_2g; + uint8_t nss_5g; QDF_STATUS status = QDF_STATUS_E_NOMEM; tSirMsgQ msg; @@ -14899,12 +14972,16 @@ QDF_STATUS csr_process_add_sta_session_command(tpAniSirGlobal pMac, return status; } + csr_get_vdev_type_nss(pMac, pAddStaReq->currDeviceMode, + &nss_2g, &nss_5g); qdf_mem_copy(add_sta_self_req->self_mac_addr, pAddStaReq->selfMacAddr, sizeof(tSirMacAddr)); add_sta_self_req->curr_device_mode = pAddStaReq->currDeviceMode; add_sta_self_req->session_id = sessionId; add_sta_self_req->type = pAddStaReq->type; add_sta_self_req->sub_type = pAddStaReq->subType; + add_sta_self_req->nss_2g = nss_2g; + add_sta_self_req->nss_5g = nss_5g; msg.type = WMA_ADD_STA_SELF_REQ; msg.reserved = 0; diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 5a46225529..0850c946a6 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -935,6 +935,8 @@ struct wma_txrx_node { uint32_t mac_id; bool roaming_in_progress; int32_t roam_synch_delay; + uint8_t nss_2g; + uint8_t nss_5g; }; #if defined(QCA_WIFI_FTM) @@ -2111,6 +2113,12 @@ uint32_t wma_get_num_of_setbits_from_bitmask(uint32_t mask); QDF_STATUS wma_get_bpf_capabilities(tp_wma_handle wma); QDF_STATUS wma_set_bpf_instructions(tp_wma_handle wma, struct sir_bpf_set_offload *bpf_set_offload); +void wma_process_set_pdev_ie_req(tp_wma_handle wma, + struct set_ie_param *ie_params); +void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma, + struct set_ie_param *ie_params); +void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma, + struct set_ie_param *ie_params); #endif struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma_handle); WLAN_PHY_MODE wma_chan_phy_mode(u8 chan, enum phy_ch_width chan_width, diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h index ea7be4ba6d..1d3cb68d44 100644 --- a/core/wma/inc/wma_if.h +++ b/core/wma/inc/wma_if.h @@ -509,6 +509,8 @@ typedef struct { uint8_t nonRoamReassoc; uint8_t wps_state; uint8_t nss; + uint8_t nss_2g; + uint8_t nss_5g; } tAddBssParams, *tpAddBssParams; /** @@ -1144,6 +1146,8 @@ typedef struct sMaxTxPowerPerBandParams { * @type: Vdev Type * @sub_type: Vdev Sub Type * @session_id: SME Session ID + * @nss_2g: vdev nss in 2.4G + * @nss_5g: vdev nss in 5G * @status: response status code */ struct add_sta_self_params { @@ -1152,9 +1156,32 @@ struct add_sta_self_params { uint32_t type; uint32_t sub_type; uint8_t session_id; + uint8_t nss_2g; + uint8_t nss_5g; uint32_t status; }; +/** + * 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/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h index e6a8c86a9f..0afcf52de2 100644 --- a/core/wma/inc/wma_tgt_cfg.h +++ b/core/wma/inc/wma_tgt_cfg.h @@ -67,6 +67,8 @@ struct wma_tgt_services { #ifdef WLAN_FEATURE_ROAM_OFFLOAD bool en_roam_offload; #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ + /* per band chain mask support */ + bool per_band_chainmask_supp; }; /** diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index 53af2d267a..3b2120ed9e 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -472,9 +472,10 @@ #define WMA_REMOVE_BCN_FILTER_CMDID SIR_HAL_REMOVE_BCN_FILTER_CMDID #define WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS SIR_HAL_SET_ADAPT_DWELLTIME_PARAMS -#define WDA_BPF_GET_CAPABILITIES_REQ SIR_HAL_BPF_GET_CAPABILITIES_REQ -#define WDA_BPF_SET_INSTRUCTIONS_REQ SIR_HAL_BPF_SET_INSTRUCTIONS_REQ +#define WDA_BPF_GET_CAPABILITIES_REQ SIR_HAL_BPF_GET_CAPABILITIES_REQ +#define WDA_BPF_SET_INSTRUCTIONS_REQ SIR_HAL_BPF_SET_INSTRUCTIONS_REQ +#define WMA_SET_PDEV_IE_REQ SIR_HAL_SET_PDEV_IE_REQ /* Bit 6 will be used to control BD rate for Management frames */ #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index d7040f577f..e5fb871525 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1485,6 +1485,8 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle, params.if_id = self_sta_req->session_id; params.type = self_sta_req->type; params.subtype = self_sta_req->sub_type; + params.nss_2g = self_sta_req->nss_2g; + params.nss_5g = self_sta_req->nss_5g; /* Create a vdev in target */ status = wmi_unified_vdev_create_send(wma_handle->wmi_handle, diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index c10e3ce0c7..a62af7827a 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3437,6 +3437,9 @@ static inline void wma_update_target_services(tp_wma_handle wh, cfg->en_tdls_uapsd_sleep_sta = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_TDLS_UAPSD_SLEEP_STA); + cfg->per_band_chainmask_supp = + WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT); #endif /* FEATURE_WLAN_TDLS */ if (WMI_SERVICE_IS_ENABLED (wh->wmi_service_bitmap, WMI_SERVICE_BEACON_OFFLOAD)) @@ -5271,6 +5274,11 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) (wma_cli_set_cmd_t *) msg->bodyptr); qdf_mem_free(msg->bodyptr); break; + case WMA_SET_PDEV_IE_REQ: + wma_process_set_pdev_ie_req(wma_handle, + (struct set_ie_param *)msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; #if !defined(REMOVE_PKT_LOG) case WMA_PKTLOG_ENABLE_REQ: wma_pktlog_wmi_send_cmd(wma_handle, diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 88e62cd194..b581f2fd8c 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -649,6 +649,8 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, tchan_info = scan_ch_param.chan_info; scan_ch_param.num_scan_chans = chan_list->numChan; wma_handle->saved_chan.num_channels = chan_list->numChan; + 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) { tchan_info->mhz = @@ -668,10 +670,21 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, chan_list->chanParam[i].dfsSet); } - if (tchan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) + if (tchan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) { WMI_SET_CHANNEL_MODE(tchan_info, MODE_11G); - else + if (chan_list->vht_en && chan_list->vht_24_en) + WMI_SET_CHANNEL_FLAG(tchan_info, + WMI_CHAN_FLAG_ALLOW_VHT); + } else { WMI_SET_CHANNEL_MODE(tchan_info, MODE_11A); + if (chan_list->vht_en) + WMI_SET_CHANNEL_FLAG(tchan_info, + WMI_CHAN_FLAG_ALLOW_VHT); + } + + if (chan_list->ht_en) + WMI_SET_CHANNEL_FLAG(tchan_info, + WMI_CHAN_FLAG_ALLOW_HT); if (chan_list->chanParam[i].half_rate) WMI_SET_CHANNEL_FLAG(tchan_info, @@ -1155,6 +1168,136 @@ void wma_roam_scan_fill_ap_profile(tp_wma_handle wma_handle, } } +/** + * 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); + + qdf_mem_free(ie_params->ie_ptr); +} + +/** + * 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; + uint16_t len; + uint16_t ie_len_pad; + uint8_t *buf_ptr; + + len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; + ie_len_pad = roundup(ie_params->ie_len, sizeof(uint32_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 = (uint8_t *)cmd + sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad); + if (ie_params->ie_len) { + qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, + (uint8_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; + uint16_t len; + uint16_t ie_len_pad; + uint8_t *buf_ptr; + + len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; + ie_len_pad = roundup(ie_params->ie_len, sizeof(uint32_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 = (uint8_t *)cmd + sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad); + if (ie_params->ie_len) { + qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, + (uint8_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_roam_scan_scan_params() - fill roam scan params * @wma_handle: wma handle