diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index a4fd2bc4d368..b1c36b54fa7b 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -5668,6 +5668,48 @@ enum hdd_link_speed_rpt_type { #define CFG_RATE_FOR_TX_MGMT_MAX (WNI_CFG_RATE_FOR_TX_MGMT_STAMAX) #define CFG_RATE_FOR_TX_MGMT_DEFAULT (WNI_CFG_RATE_FOR_TX_MGMT_STADEF) +/* + * + * gRateForTxMgmt2G - rate for tx mgmt frame on 2G + * @Min: 0x0 + * @Max: 0xFF + * @Default: 0xFF + * + * This ini is used to configure the rate for tx + * mgmt frame on 2G Band. Default 0xFF means disable. + * It has higher priority and will overwrite gRateForTxMgmt + * setting. + * + * Usage: External + * + * + */ +#define CFG_RATE_FOR_TX_MGMT_2G "gRateForTxMgmt2G" +#define CFG_RATE_FOR_TX_MGMT_2G_MIN (WNI_CFG_RATE_FOR_TX_MGMT_2G_STAMIN) +#define CFG_RATE_FOR_TX_MGMT_2G_MAX (WNI_CFG_RATE_FOR_TX_MGMT_2G_STAMAX) +#define CFG_RATE_FOR_TX_MGMT_2G_DEFAULT (WNI_CFG_RATE_FOR_TX_MGMT_2G_STADEF) + +/* + * + * gRateForTxMgmt5G - rate for tx mgmt frame on 5G + * @Min: 0x0 + * @Max: 0xFF + * @Default: 0xFF + * + * This ini is used to configure the rate for tx + * mgmt frame on 5G Band. Default 0xFF means disable. + * It has higher priority and will overwrite gRateForTxMgmt + * setting. + * + * Usage: External + * + * + */ +#define CFG_RATE_FOR_TX_MGMT_5G "gRateForTxMgmt5G" +#define CFG_RATE_FOR_TX_MGMT_5G_MIN (WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMIN) +#define CFG_RATE_FOR_TX_MGMT_5G_MAX (WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMAX) +#define CFG_RATE_FOR_TX_MGMT_5G_DEFAULT (WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF) + #ifdef FEATURE_WLAN_TDLS /* * @@ -10617,6 +10659,8 @@ struct hdd_config { uint16_t max_ht_mcs_txdata; bool disable_abg_rate_txdata; uint8_t rate_for_tx_mgmt; + uint8_t rate_for_tx_mgmt_2g; + uint8_t rate_for_tx_mgmt_5g; #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL uint32_t TxFlowLowWaterMark; uint32_t TxFlowHighWaterMarkOffset; diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index d4e3f6d6222e..de9e5fbe084b 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -2130,6 +2130,20 @@ struct reg_table_entry g_registry_table[] = { CFG_RATE_FOR_TX_MGMT_MIN, CFG_RATE_FOR_TX_MGMT_MAX), + REG_VARIABLE(CFG_RATE_FOR_TX_MGMT_2G, WLAN_PARAM_HexInteger, + struct hdd_config, rate_for_tx_mgmt_2g, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RATE_FOR_TX_MGMT_2G_DEFAULT, + CFG_RATE_FOR_TX_MGMT_2G_MIN, + CFG_RATE_FOR_TX_MGMT_2G_MAX), + + REG_VARIABLE(CFG_RATE_FOR_TX_MGMT_5G, WLAN_PARAM_HexInteger, + struct hdd_config, rate_for_tx_mgmt_5g, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RATE_FOR_TX_MGMT_5G_DEFAULT, + CFG_RATE_FOR_TX_MGMT_5G_MIN, + CFG_RATE_FOR_TX_MGMT_5G_MAX), + REG_VARIABLE(CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME, WLAN_PARAM_Integer, struct hdd_config, enableFirstScan2GOnly, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -7044,6 +7058,20 @@ bool hdd_update_config_cfg(hdd_context_t *hdd_ctx) hdd_err("Could not pass on WNI_CFG_SAP_MAX_MCS_DATA to CCM"); } + if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_RATE_FOR_TX_MGMT_2G, + config->rate_for_tx_mgmt_2g) == + QDF_STATUS_E_FAILURE) { + status = false; + hdd_err("Couldn't pass on WNI_CFG_RATE_FOR_TX_MGMT_2G to CCM"); + } + + if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_RATE_FOR_TX_MGMT_5G, + config->rate_for_tx_mgmt_5g) == + QDF_STATUS_E_FAILURE) { + status = false; + hdd_err("Couldn't pass on WNI_CFG_RATE_FOR_TX_MGMT_5G to CCM"); + } + return status; } diff --git a/core/mac/inc/wni_cfg.h b/core/mac/inc/wni_cfg.h index 4a0c2694c3d1..bd43b8a1c6b9 100644 --- a/core/mac/inc/wni_cfg.h +++ b/core/mac/inc/wni_cfg.h @@ -318,6 +318,8 @@ enum { WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT, WNI_CFG_HE_STA_OBSSPD, WNI_CFG_SAP_MAX_MCS_DATA, + WNI_CFG_RATE_FOR_TX_MGMT_2G, + WNI_CFG_RATE_FOR_TX_MGMT_5G, /* Any new items to be added should be above this strictly */ CFG_PARAM_MAX_NUM }; @@ -1603,6 +1605,14 @@ enum { #define WNI_CFG_SAP_MAX_MCS_DATA_STAMAX 0x17f #define WNI_CFG_SAP_MAX_MCS_DATA_STADEF 0x0 +#define WNI_CFG_RATE_FOR_TX_MGMT_2G_STAMIN 0x0 +#define WNI_CFG_RATE_FOR_TX_MGMT_2G_STAMAX 0xFF +#define WNI_CFG_RATE_FOR_TX_MGMT_2G_STADEF 0xFF + +#define WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMIN 0x0 +#define WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMAX 0xFF +#define WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF 0xFF + #define CFG_STA_MAGIC_DWORD 0xbeefbeef #endif diff --git a/core/mac/src/cfg/cfg_param_name.c b/core/mac/src/cfg/cfg_param_name.c index 670ae07611d0..2e88b4d755e7 100644 --- a/core/mac/src/cfg/cfg_param_name.c +++ b/core/mac/src/cfg/cfg_param_name.c @@ -330,4 +330,6 @@ unsigned char *g_cfg_param_name[] = { (unsigned char *)"ASSOC_STA_LIMIT_GO", (unsigned char *)"ASSOC_STA_LIMIT_AP", (unsigned char *)"SAP_MAX_MCS_DATA", + (unsigned char *)"RATE_FOR_TX_MGMT_2G", + (unsigned char *)"RATE_FOR_TX_MGMT_5G", }; diff --git a/core/mac/src/cfg/cfg_proc_msg.c b/core/mac/src/cfg/cfg_proc_msg.c index 037ff09d2bf2..2e79a85a647d 100644 --- a/core/mac/src/cfg/cfg_proc_msg.c +++ b/core/mac/src/cfg/cfg_proc_msg.c @@ -1454,6 +1454,16 @@ cgstatic cfg_static[CFG_PARAM_MAX_NUM] = { WNI_CFG_SAP_MAX_MCS_DATA_STAMIN, WNI_CFG_SAP_MAX_MCS_DATA_STAMAX, WNI_CFG_SAP_MAX_MCS_DATA_STADEF}, + {WNI_CFG_RATE_FOR_TX_MGMT_2G, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_RATE_FOR_TX_MGMT_2G_STAMIN, + WNI_CFG_RATE_FOR_TX_MGMT_2G_STAMAX, + WNI_CFG_RATE_FOR_TX_MGMT_2G_STADEF}, + {WNI_CFG_RATE_FOR_TX_MGMT_5G, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMIN, + WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMAX, + WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF} }; diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 553fb5f10081..0f66309a3732 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -583,6 +583,49 @@ static inline void wma_get_link_probe_timeout(struct sAniSirGlobal *mac, *max_unresponsive_time = *max_inactive_time + keep_alive; } +/** + * wma_verify_rate_code() - verify if rate code is valid. + * @rate_code: rate code + * + * Return: verify result + */ +static bool wma_verify_rate_code(u_int32_t rate_code) +{ + uint8_t preamble, nss, rate; + bool valid = true; + + preamble = (rate_code & 0xc0) >> 6; + nss = (rate_code & 0x30) >> 4; + rate = rate_code & 0xf; + + switch (preamble) { + case WMI_RATE_PREAMBLE_CCK: + if (nss != 0 || rate > 3) + valid = false; + break; + case WMI_RATE_PREAMBLE_OFDM: + if (nss != 0 || rate > 7) + valid = false; + break; + case WMI_RATE_PREAMBLE_HT: + if (nss > 1 || rate > 7) + valid = false; + break; + case WMI_RATE_PREAMBLE_VHT: + if (nss > 1 || rate > 9) + valid = false; + break; + default: + break; + } + return valid; +} + +#define TX_MGMT_RATE_2G_ENABLE_OFFSET 30 +#define TX_MGMT_RATE_5G_ENABLE_OFFSET 31 +#define TX_MGMT_RATE_2G_OFFSET 0 +#define TX_MGMT_RATE_5G_OFFSET 12 + /** * wma_set_mgmt_rate() - set vdev mgmt rate. * @wma: wma handle @@ -594,6 +637,7 @@ void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id) { uint32_t cfg_val; int ret; + uint32_t per_band_mgmt_tx_rate = 0; struct sAniSirGlobal *mac = cds_get_context(QDF_MODULE_ID_PE); if (NULL == mac) { @@ -603,7 +647,8 @@ void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id) if (wlan_cfg_get_int(mac, WNI_CFG_RATE_FOR_TX_MGMT, &cfg_val) == eSIR_SUCCESS) { - if (cfg_val == WNI_CFG_RATE_FOR_TX_MGMT_STADEF) { + if ((cfg_val == WNI_CFG_RATE_FOR_TX_MGMT_STADEF) || + !wma_verify_rate_code(cfg_val)) { WMA_LOGD("default WNI_CFG_RATE_FOR_TX_MGMT, ignore"); } else { ret = wma_vdev_set_param( @@ -619,6 +664,47 @@ void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id) } else { WMA_LOGE("Failed to get value of WNI_CFG_RATE_FOR_TX_MGMT"); } + + if (wlan_cfg_get_int(mac, WNI_CFG_RATE_FOR_TX_MGMT_2G, + &cfg_val) == eSIR_SUCCESS) { + if ((cfg_val == WNI_CFG_RATE_FOR_TX_MGMT_2G_STADEF) || + !wma_verify_rate_code(cfg_val)) { + per_band_mgmt_tx_rate &= + ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET); + } else { + per_band_mgmt_tx_rate |= + (1 << TX_MGMT_RATE_2G_ENABLE_OFFSET); + per_band_mgmt_tx_rate |= + ((cfg_val & 0x7FF) << TX_MGMT_RATE_2G_OFFSET); + } + } else { + WMA_LOGE("Failed to get value of WNI_CFG_RATE_FOR_TX_MGMT_2G"); + } + + if (wlan_cfg_get_int(mac, WNI_CFG_RATE_FOR_TX_MGMT_5G, + &cfg_val) == eSIR_SUCCESS) { + if ((cfg_val == WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF) || + !wma_verify_rate_code(cfg_val)) { + per_band_mgmt_tx_rate &= + ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET); + } else { + per_band_mgmt_tx_rate |= + (1 << TX_MGMT_RATE_5G_ENABLE_OFFSET); + per_band_mgmt_tx_rate |= + ((cfg_val & 0x7FF) << TX_MGMT_RATE_5G_OFFSET); + } + } else { + WMA_LOGE("Failed to get value of WNI_CFG_RATE_FOR_TX_MGMT_5G"); + } + + ret = wma_vdev_set_param( + wma->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE, + per_band_mgmt_tx_rate); + if (ret) + WMA_LOGE("Failed to set WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE"); + } /**