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");
+
}
/**