diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c
index 87ff8650f8..16b1c44b42 100644
--- a/components/mlme/core/src/wlan_mlme_main.c
+++ b/components/mlme/core/src/wlan_mlme_main.c
@@ -353,6 +353,49 @@ static void mlme_init_wds_config_cfg(struct wlan_objmgr_psoc *psoc,
}
#endif
+/**
+ * mlme_init_mgmt_hw_tx_retry_count_cfg() - initialize mgmt hw tx retry count
+ * @psoc: Pointer to PSOC
+ * @gen: pointer to generic CFG items
+ *
+ * Return: None
+ */
+static void mlme_init_mgmt_hw_tx_retry_count_cfg(
+ struct wlan_objmgr_psoc *psoc,
+ struct wlan_mlme_generic *gen)
+{
+ uint32_t i;
+ qdf_size_t out_size = 0;
+ uint8_t count_array[MGMT_FRM_HW_TX_RETRY_COUNT_STR_LEN];
+
+ qdf_uint8_array_parse(cfg_get(psoc, CFG_MGMT_FRAME_HW_TX_RETRY_COUNT),
+ count_array,
+ MGMT_FRM_HW_TX_RETRY_COUNT_STR_LEN,
+ &out_size);
+
+ for (i = 0; i + 1 < out_size; i += 2) {
+ if (count_array[i] >= CFG_FRAME_TYPE_MAX) {
+ mlme_legacy_debug("invalid frm type %d",
+ count_array[i]);
+ continue;
+ }
+ if (count_array[i + 1] >= MAX_MGMT_HW_TX_RETRY_COUNT) {
+ mlme_legacy_debug("mgmt hw tx retry count %d for frm %d, limit to %d",
+ count_array[i + 1],
+ count_array[i],
+ MAX_MGMT_HW_TX_RETRY_COUNT);
+ gen->mgmt_hw_tx_retry_count[count_array[i]] =
+ MAX_MGMT_HW_TX_RETRY_COUNT;
+ } else {
+ mlme_legacy_debug("mgmt hw tx retry count %d for frm %d",
+ count_array[i + 1],
+ count_array[i]);
+ gen->mgmt_hw_tx_retry_count[count_array[i]] =
+ count_array[i + 1];
+ }
+ }
+}
+
static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc,
struct wlan_mlme_generic *gen)
{
@@ -416,6 +459,7 @@ static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc,
cfg_get(psoc, CFG_MONITOR_MODE_CONCURRENCY);
gen->tx_retry_multiplier = cfg_get(psoc, CFG_TX_RETRY_MULTIPLIER);
mlme_init_wds_config_cfg(psoc, gen);
+ mlme_init_mgmt_hw_tx_retry_count_cfg(psoc, gen);
}
static void mlme_init_edca_ani_cfg(struct wlan_objmgr_psoc *psoc,
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_generic.h b/components/mlme/dispatcher/inc/cfg_mlme_generic.h
index d1ead6f62b..8d7725ec2b 100644
--- a/components/mlme/dispatcher/inc/cfg_mlme_generic.h
+++ b/components/mlme/dispatcher/inc/cfg_mlme_generic.h
@@ -901,6 +901,40 @@ enum wlan_wds_mode {
CFG_VALUE_OR_DEFAULT, \
"percentage of max retry limit")
+/*
+ *
+ * mgmt_frame_hw_tx_retry_count - Set hw tx retry count for mgmt action
+ * frame
+ * @Min: N/A
+ * @Max: N/A
+ * @Default: N/A
+ *
+ * Set mgmt action frame hw tx retry count, string format looks like below:
+ * frame_hw_tx_retry_count=",,..."
+ * frame type is enum value of mlme_cfg_frame_type.
+ * Retry count max value is 127.
+ * For example:
+ * frame_hw_tx_retry_count="0,64,2,32"
+ * The above input string means:
+ * For p2p go negotiation request fame, hw retry count 64
+ * For p2p provision discovery request, hw retry count 32
+ *
+ * Related: None.
+ *
+ * Supported Feature: STA/P2P
+ *
+ * Usage: External
+ *
+ *
+ */
+#define MGMT_FRM_HW_TX_RETRY_COUNT_STR_LEN (64)
+#define CFG_MGMT_FRAME_HW_TX_RETRY_COUNT CFG_INI_STRING( \
+ "mgmt_frame_hw_tx_retry_count", \
+ 0, \
+ MGMT_FRM_HW_TX_RETRY_COUNT_STR_LEN, \
+ "", \
+ "Set mgmt action frame hw tx retry count")
+
#define CFG_GENERIC_ALL \
CFG(CFG_ENABLE_DEBUG_PACKET_LOG) \
CFG(CFG_PMF_SA_QUERY_MAX_RETRIES) \
@@ -936,5 +970,6 @@ enum wlan_wds_mode {
CFG(CFG_MONITOR_MODE_CONCURRENCY) \
CFG(CFG_RF_TEST_MODE_SUPP_ENABLED) \
CFG_WDS_MODE_ALL \
- CFG(CFG_TX_RETRY_MULTIPLIER)
+ CFG(CFG_TX_RETRY_MULTIPLIER) \
+ CFG(CFG_MGMT_FRAME_HW_TX_RETRY_COUNT)
#endif /* __CFG_MLME_GENERIC_H */
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h
index 3a1088fe74..3a923b41db 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_api.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h
@@ -3397,6 +3397,18 @@ wlan_mlme_get_p2p_p2p_conc_support(struct wlan_objmgr_psoc *psoc)
*/
enum phy_ch_width mlme_get_vht_ch_width(void);
+/**
+ * wlan_mlme_get_mgmt_hw_tx_retry_count() - Get mgmt frame hw tx retry count
+ *
+ * @psoc: pointer to psoc object
+ * @frm_type: frame type of the query
+ *
+ * Return: hw tx retry count
+ */
+uint8_t
+wlan_mlme_get_mgmt_hw_tx_retry_count(struct wlan_objmgr_psoc *psoc,
+ enum mlme_cfg_frame_type frm_type);
+
/**
* wlan_mlme_get_tx_retry_multiplier() - Get the tx retry multiplier percentage
*
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
index df268f96a8..89bec0735b 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
@@ -1275,6 +1275,21 @@ struct dual_sta_policy {
uint8_t primary_vdev_id;
};
+/**
+ * enum mlme_cfg_frame_type - frame type to configure mgmt hw tx retry count
+ * @CFG_GO_NEGOTIATION_REQ_FRAME_TYPE: p2p go negotiation request fame
+ * @CFG_P2P_INVITATION_REQ_FRAME_TYPE: p2p invitation request frame
+ * @CFG_PROVISION_DISCOVERY_REQ_FRAME_TYPE: p2p provision discovery request
+ */
+enum mlme_cfg_frame_type {
+ CFG_GO_NEGOTIATION_REQ_FRAME_TYPE = 0,
+ CFG_P2P_INVITATION_REQ_FRAME_TYPE = 1,
+ CFG_PROVISION_DISCOVERY_REQ_FRAME_TYPE = 2,
+ CFG_FRAME_TYPE_MAX,
+};
+
+#define MAX_MGMT_HW_TX_RETRY_COUNT 127
+
/* struct wlan_mlme_generic - Generic CFG config items
*
* @band_capability: HW Band Capability - Both or 2.4G only or 5G only
@@ -1324,6 +1339,7 @@ struct dual_sta_policy {
* @wds_mode: wds mode supported
* @dual_sta_policy_cfg: Dual STA policies configuration
* @tx_retry_multiplier: TX xretry extension parameter
+ * @mgmt_hw_tx_retry_count: MGMT HW tx retry count for frames
*/
struct wlan_mlme_generic {
uint32_t band_capability;
@@ -1370,6 +1386,7 @@ struct wlan_mlme_generic {
enum wlan_wds_mode wds_mode;
struct dual_sta_policy dual_sta_policy;
uint32_t tx_retry_multiplier;
+ uint8_t mgmt_hw_tx_retry_count[CFG_FRAME_TYPE_MAX];
};
/*
diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c
index 68b31bb8fc..6e567b997f 100644
--- a/components/mlme/dispatcher/src/wlan_mlme_api.c
+++ b/components/mlme/dispatcher/src/wlan_mlme_api.c
@@ -5291,6 +5291,23 @@ enum phy_ch_width mlme_get_vht_ch_width(void)
return bandwidth;
}
+uint8_t
+wlan_mlme_get_mgmt_hw_tx_retry_count(struct wlan_objmgr_psoc *psoc,
+ enum mlme_cfg_frame_type frm_type)
+{
+ struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+ mlme_obj = mlme_get_psoc_ext_obj(psoc);
+
+ if (!mlme_obj)
+ return 0;
+
+ if (frm_type >= CFG_FRAME_TYPE_MAX)
+ return 0;
+
+ return mlme_obj->cfg.gen.mgmt_hw_tx_retry_count[frm_type];
+}
+
QDF_STATUS
wlan_mlme_get_tx_retry_multiplier(struct wlan_objmgr_psoc *psoc,
uint32_t *tx_retry_multiplier)
diff --git a/components/p2p/core/src/wlan_p2p_off_chan_tx.c b/components/p2p/core/src/wlan_p2p_off_chan_tx.c
index 73c1b072f3..1fc707e32f 100644
--- a/components/p2p/core/src/wlan_p2p_off_chan_tx.c
+++ b/components/p2p/core/src/wlan_p2p_off_chan_tx.c
@@ -35,6 +35,7 @@
#include "wlan_p2p_off_chan_tx.h"
#include "wlan_osif_request_manager.h"
#include
+#include "wlan_mlme_api.h"
/**
* p2p_psoc_get_tx_ops() - get p2p tx ops
@@ -1051,6 +1052,71 @@ static QDF_STATUS p2p_send_tx_conf(struct tx_action_context *tx_ctx,
return QDF_STATUS_SUCCESS;
}
+/**
+ * p2p_get_hw_retry_count() - Get hw tx retry count from config store
+ * @psoc: psoc object
+ * @tx_ctx: tx context
+ *
+ * This function return the hw tx retry count for p2p action frame.
+ * 0 value means target will use fw default mgmt tx retry count 15.
+ *
+ * Return: frame hw tx retry count
+ */
+static uint8_t p2p_get_hw_retry_count(struct wlan_objmgr_psoc *psoc,
+ struct tx_action_context *tx_ctx)
+{
+ if (tx_ctx->frame_info.type != P2P_FRAME_MGMT)
+ return 0;
+
+ if (tx_ctx->frame_info.sub_type != P2P_MGMT_ACTION)
+ return 0;
+
+ switch (tx_ctx->frame_info.public_action_type) {
+ case P2P_PUBLIC_ACTION_NEG_REQ:
+ return wlan_mlme_get_mgmt_hw_tx_retry_count(
+ psoc,
+ CFG_GO_NEGOTIATION_REQ_FRAME_TYPE);
+ case P2P_PUBLIC_ACTION_INVIT_REQ:
+ return wlan_mlme_get_mgmt_hw_tx_retry_count(
+ psoc,
+ CFG_P2P_INVITATION_REQ_FRAME_TYPE);
+ case P2P_PUBLIC_ACTION_PROV_DIS_REQ:
+ return wlan_mlme_get_mgmt_hw_tx_retry_count(
+ psoc,
+ CFG_PROVISION_DISCOVERY_REQ_FRAME_TYPE);
+ default:
+ return 0;
+ }
+}
+
+#define GET_HW_RETRY_LIMIT(count) QDF_GET_BITS(count, 0, 4)
+#define GET_HW_RETRY_LIMIT_EXT(count) QDF_GET_BITS(count, 4, 3)
+
+/**
+ * p2p_mgmt_set_hw_retry_count() - Set mgmt hw tx retry count
+ * @psoc: psoc object
+ * @tx_ctx: tx context
+ * @mgmt_param: mgmt frame tx parameter
+ *
+ * This function will set mgmt frame hw tx retry count to tx parameter
+ *
+ * Return: void
+ */
+static void
+p2p_mgmt_set_hw_retry_count(struct wlan_objmgr_psoc *psoc,
+ struct tx_action_context *tx_ctx,
+ struct wmi_mgmt_params *mgmt_param)
+{
+ uint8_t retry_count = p2p_get_hw_retry_count(psoc, tx_ctx);
+
+ mgmt_param->tx_param.retry_limit = GET_HW_RETRY_LIMIT(retry_count);
+ mgmt_param->tx_param.retry_limit_ext =
+ GET_HW_RETRY_LIMIT_EXT(retry_count);
+ if (mgmt_param->tx_param.retry_limit ||
+ mgmt_param->tx_param.retry_limit_ext)
+ mgmt_param->tx_params_valid = true;
+}
+
/**
* p2p_mgmt_tx() - call mgmt tx api
* @tx_ctx: tx context
@@ -1102,6 +1168,7 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx,
wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
return QDF_STATUS_E_INVAL;
}
+ p2p_mgmt_set_hw_retry_count(psoc, tx_ctx, &mgmt_param);
wh = (struct wlan_frame_hdr *)frame;
mac_addr = wh->i_addr1;
@@ -1135,8 +1202,12 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx,
tx_ota_comp_cb = tgt_p2p_mgmt_ota_comp_cb;
}
- p2p_debug("length:%d, chanfreq:%d", mgmt_param.frm_len,
- mgmt_param.chanfreq);
+ p2p_debug("length:%d, chanfreq:%d retry count:%d(%d, %d)",
+ mgmt_param.frm_len, mgmt_param.chanfreq,
+ (mgmt_param.tx_param.retry_limit_ext << 4) |
+ mgmt_param.tx_param.retry_limit,
+ mgmt_param.tx_param.retry_limit,
+ mgmt_param.tx_param.retry_limit_ext);
tx_ctx->nbuf = packet;