diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index da174ee2e0..68bfeaf656 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -2194,7 +2194,10 @@ struct htt_soc *htt_soc_attach(struct dp_soc *soc, HTC_HANDLE htc_handle) { int i; int j; - int alloc_size = HTT_SW_UMAC_RING_IDX_MAX * sizeof(unsigned long); + int umac_alloc_size = HTT_SW_UMAC_RING_IDX_MAX * + sizeof(struct bp_handler); + int lmac_alloc_size = HTT_SW_LMAC_RING_IDX_MAX * + sizeof(struct bp_handler); struct htt_soc *htt_soc = NULL; htt_soc = qdf_mem_malloc(sizeof(*htt_soc)); @@ -2204,21 +2207,26 @@ struct htt_soc *htt_soc_attach(struct dp_soc *soc, HTC_HANDLE htc_handle) } for (i = 0; i < MAX_PDEV_CNT; i++) { - htt_soc->pdevid_tt[i].umac_ttt = qdf_mem_malloc(alloc_size); - if (!htt_soc->pdevid_tt[i].umac_ttt) + htt_soc->pdevid_tt[i].umac_path = + qdf_mem_malloc(umac_alloc_size); + if (!htt_soc->pdevid_tt[i].umac_path) break; - qdf_mem_set(htt_soc->pdevid_tt[i].umac_ttt, alloc_size, -1); - htt_soc->pdevid_tt[i].lmac_ttt = qdf_mem_malloc(alloc_size); - if (!htt_soc->pdevid_tt[i].lmac_ttt) { - qdf_mem_free(htt_soc->pdevid_tt[i].umac_ttt); + for (j = 0; j < HTT_SW_UMAC_RING_IDX_MAX; j++) + htt_soc->pdevid_tt[i].umac_path[j].bp_start_tt = -1; + htt_soc->pdevid_tt[i].lmac_path = + qdf_mem_malloc(lmac_alloc_size); + if (!htt_soc->pdevid_tt[i].lmac_path) { + qdf_mem_free(htt_soc->pdevid_tt[i].umac_path); break; } - qdf_mem_set(htt_soc->pdevid_tt[i].lmac_ttt, alloc_size, -1); + for (j = 0; j < HTT_SW_LMAC_RING_IDX_MAX ; j++) + htt_soc->pdevid_tt[i].lmac_path[j].bp_start_tt = -1; } + if (i != MAX_PDEV_CNT) { for (j = 0; j < i; j++) { - qdf_mem_free(htt_soc->pdevid_tt[j].umac_ttt); - qdf_mem_free(htt_soc->pdevid_tt[j].lmac_ttt); + qdf_mem_free(htt_soc->pdevid_tt[j].umac_path); + qdf_mem_free(htt_soc->pdevid_tt[j].lmac_path); } qdf_mem_free(htt_soc); return NULL; @@ -2506,23 +2514,31 @@ static void dp_sawf_mpdu_stats_handler(struct htt_soc *soc, * Return: 1 for successfully saving timestamp in array * and 0 for timestamp falling within 2 seconds after last one */ -static bool time_allow_print(unsigned long *htt_ring_tt, u_int8_t ring_id) +static bool time_allow_print(struct bp_handler *htt_bp_handler, + u_int8_t ring_id, u_int32_t th_time) { unsigned long tstamp; - unsigned long delta; + struct bp_handler *path = &htt_bp_handler[ring_id]; tstamp = qdf_get_system_timestamp(); - if (!htt_ring_tt) + if (!path) return 0; //unable to print backpressure messages - if (htt_ring_tt[ring_id] == -1) { - htt_ring_tt[ring_id] = tstamp; + if (path->bp_start_tt == -1) { + path->bp_start_tt = tstamp; + path->bp_duration = 0; + path->bp_last_tt = tstamp; + path->bp_counter = 1; return 1; } - delta = tstamp - htt_ring_tt[ring_id]; - if (delta >= 2000) { - htt_ring_tt[ring_id] = tstamp; + + path->bp_duration = tstamp - path->bp_start_tt; + path->bp_last_tt = tstamp; + path->bp_counter++; + + if (path->bp_duration >= th_time) { + path->bp_start_tt = -1; return 1; } @@ -2532,12 +2548,18 @@ static bool time_allow_print(unsigned long *htt_ring_tt, u_int8_t ring_id) static void dp_htt_alert_print(enum htt_t2h_msg_type msg_type, struct dp_pdev *pdev, u_int8_t ring_id, u_int16_t hp_idx, u_int16_t tp_idx, - u_int32_t bkp_time, char *ring_stype) + u_int32_t bkp_time, + struct bp_handler *htt_bp_handler, + char *ring_stype) { dp_alert("seq_num %u msg_type: %d pdev_id: %d ring_type: %s ", pdev->bkp_stats.seq_num, msg_type, pdev->pdev_id, ring_stype); dp_alert("ring_id: %d hp_idx: %d tp_idx: %d bkpressure_time_ms: %d ", ring_id, hp_idx, tp_idx, bkp_time); + dp_alert("last_bp_event: %ld, total_bp_duration: %ld, bp_counter: %ld", + htt_bp_handler[ring_id].bp_last_tt, + htt_bp_handler[ring_id].bp_duration, + htt_bp_handler[ring_id].bp_counter); } /** @@ -2881,15 +2903,19 @@ static void dp_htt_bkp_event_alert(u_int32_t *msg_word, struct htt_soc *soc) u_int16_t hp_idx; u_int16_t tp_idx; u_int32_t bkp_time; + u_int32_t th_time; enum htt_t2h_msg_type msg_type; struct dp_soc *dpsoc; struct dp_pdev *pdev; struct dp_htt_timestamp *radio_tt; + struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; + if (!soc) return; dpsoc = (struct dp_soc *)soc->dp_soc; + soc_cfg_ctx = dpsoc->wlan_cfg_ctx; msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word); ring_type = HTT_T2H_RX_BKPRESSURE_RING_TYPE_GET(*msg_word); target_pdev_id = HTT_T2H_RX_BKPRESSURE_PDEV_ID_GET(*msg_word); @@ -2900,6 +2926,7 @@ static void dp_htt_bkp_event_alert(u_int32_t *msg_word, struct htt_soc *soc) return; } + th_time = wlan_cfg_time_control_bp(soc_cfg_ctx); pdev = (struct dp_pdev *)dpsoc->pdev_list[pdev_id]; ring_id = HTT_T2H_RX_BKPRESSURE_RINGID_GET(*msg_word); hp_idx = HTT_T2H_RX_BKPRESSURE_HEAD_IDX_GET(*(msg_word + 1)); @@ -2909,20 +2936,21 @@ static void dp_htt_bkp_event_alert(u_int32_t *msg_word, struct htt_soc *soc) switch (ring_type) { case HTT_SW_RING_TYPE_UMAC: - if (!time_allow_print(radio_tt->umac_ttt, ring_id)) + if (!time_allow_print(radio_tt->umac_path, ring_id, th_time)) return; dp_htt_alert_print(msg_type, pdev, ring_id, hp_idx, tp_idx, - bkp_time, "HTT_SW_RING_TYPE_UMAC"); + bkp_time, radio_tt->umac_path, + "HTT_SW_RING_TYPE_UMAC"); break; case HTT_SW_RING_TYPE_LMAC: - if (!time_allow_print(radio_tt->lmac_ttt, ring_id)) + if (!time_allow_print(radio_tt->lmac_path, ring_id, th_time)) return; dp_htt_alert_print(msg_type, pdev, ring_id, hp_idx, tp_idx, - bkp_time, "HTT_SW_RING_TYPE_LMAC"); + bkp_time, radio_tt->lmac_path, + "HTT_SW_RING_TYPE_LMAC"); break; default: - dp_htt_alert_print(msg_type, pdev, ring_id, hp_idx, tp_idx, - bkp_time, "UNKNOWN"); + dp_alert("Invalid ring type: %d", ring_type); break; } @@ -3849,8 +3877,8 @@ void htt_soc_detach(struct htt_soc *htt_hdl) struct htt_soc *htt_handle = (struct htt_soc *)htt_hdl; for (i = 0; i < MAX_PDEV_CNT; i++) { - qdf_mem_free(htt_handle->pdevid_tt[i].umac_ttt); - qdf_mem_free(htt_handle->pdevid_tt[i].lmac_ttt); + qdf_mem_free(htt_handle->pdevid_tt[i].umac_path); + qdf_mem_free(htt_handle->pdevid_tt[i].lmac_path); } HTT_TX_MUTEX_DESTROY(&htt_handle->htt_tx_mutex); diff --git a/dp/wifi3.0/dp_htt.h b/dp/wifi3.0/dp_htt.h index 62e12ba49f..4949350d4b 100644 --- a/dp/wifi3.0/dp_htt.h +++ b/dp/wifi3.0/dp_htt.h @@ -219,9 +219,16 @@ struct dp_htt_htc_pkt_union { } u; }; +struct bp_handler { + unsigned long bp_start_tt; + unsigned long bp_last_tt; + unsigned long bp_duration; + unsigned long bp_counter; +}; + struct dp_htt_timestamp { - long *umac_ttt; - long *lmac_ttt; + struct bp_handler *umac_path; + struct bp_handler *lmac_path; }; struct htt_soc { diff --git a/wlan_cfg/cfg_dp.h b/wlan_cfg/cfg_dp.h index ecc8704790..6e9f78d16d 100644 --- a/wlan_cfg/cfg_dp.h +++ b/wlan_cfg/cfg_dp.h @@ -90,6 +90,8 @@ #define WLAN_CFG_IPA_UC_RX_IND_RING_COUNT 0 #endif /* IPA_OFFLOAD */ +#define WLAN_CFG_TIME_CONTROL_BP 3000 + #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) #define WLAN_CFG_PER_PDEV_RX_RING 0 #define WLAN_CFG_PER_PDEV_LMAC_RING 0 @@ -162,6 +164,9 @@ #define WLAN_CFG_TX_RING_SIZE_MIN 512 #define WLAN_CFG_TX_RING_SIZE_MAX 0x80000 +#define WLAN_CFG_TIME_CONTROL_BP_MIN 3000 +#define WLAN_CFG_TIME_CONTROL_BP_MAX 1800000 + #define WLAN_CFG_TX_COMP_RING_SIZE_MIN 512 #define WLAN_CFG_TX_COMP_RING_SIZE_MAX 0x80000 @@ -679,6 +684,13 @@ WLAN_CFG_PER_PDEV_LMAC_RING_MAX, \ WLAN_CFG_PER_PDEV_LMAC_RING, \ CFG_VALUE_OR_DEFAULT, "DP pdev LMAC ring") + +#define CFG_DP_TIME_CONTROL_BP \ + CFG_INI_UINT("dp_time_control_bp", \ + WLAN_CFG_TIME_CONTROL_BP_MIN,\ + WLAN_CFG_TIME_CONTROL_BP_MAX,\ + WLAN_CFG_TIME_CONTROL_BP,\ + CFG_VALUE_OR_DEFAULT, "DP time control back pressure") /* * * dp_rx_pending_hl_threshold - High threshold of frame number to start @@ -1719,6 +1731,7 @@ CFG(CFG_DP_TX_RING_SIZE) \ CFG(CFG_DP_NSS_COMP_RING_SIZE) \ CFG(CFG_DP_PDEV_LMAC_RING) \ + CFG(CFG_DP_TIME_CONTROL_BP) \ CFG(CFG_DP_BASE_HW_MAC_ID) \ CFG(CFG_DP_RX_HASH) \ CFG(CFG_DP_TSO) \ diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index c842167273..f7fe0b9d74 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -2667,6 +2667,7 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc) wlan_cfg_ctx->max_peer_id = cfg_get(psoc, CFG_DP_MAX_PEER_ID); wlan_cfg_ctx->tx_ring_size = cfg_get(psoc, CFG_DP_TX_RING_SIZE); + wlan_cfg_ctx->time_control_bp = cfg_get(psoc, CFG_DP_TIME_CONTROL_BP); wlan_cfg_ctx->tx_comp_ring_size = cfg_get(psoc, CFG_DP_TX_COMPL_RING_SIZE); @@ -3231,6 +3232,11 @@ int wlan_cfg_tx_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg) return cfg->tx_ring_size; } +int wlan_cfg_time_control_bp(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->time_control_bp; +} + int wlan_cfg_tx_comp_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg) { return cfg->tx_comp_ring_size; diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index 957a0b6331..78b696c448 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -296,6 +296,7 @@ struct wlan_cfg_dp_soc_ctxt { int int_timer_threshold_other; int int_timer_threshold_mon; int tx_ring_size; + int time_control_bp; int tx_comp_ring_size; int tx_comp_ring_size_nss; uint8_t int_tx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; @@ -1358,6 +1359,14 @@ int wlan_cfg_get_p2p_checksum_offload(struct wlan_cfg_dp_soc_ctxt *cfg); */ int wlan_cfg_tx_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg); +/* + * wlan_cfg_time_control_bp - Get time for interval in bp prints + * @wlan_cfg_soc_ctx + * + * Return: interval time + */ +int wlan_cfg_time_control_bp(struct wlan_cfg_dp_soc_ctxt *cfg); + /* * wlan_cfg_tx_comp_ring_size - Get Tx completion ring size (WBM Ring) * @wlan_cfg_soc_ctx