diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 75de3c4ee4..e1e8982cc6 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -136,6 +136,8 @@ #define FILTER_DATA_DATA 0x0001 #define FILTER_DATA_NULL 0x0008 +QDF_DECLARE_EWMA(tx_lag, 1024, 8) + /* * DP configuration parameters */ @@ -897,7 +899,7 @@ enum cdp_stat_update_type { */ struct cdp_tx_sojourn_stats { uint32_t ppdu_seq_id; - uint32_t avg_sojourn_msdu[CDP_DATA_TID_MAX]; + qdf_ewma_tx_lag avg_sojourn_msdu[CDP_DATA_TID_MAX]; uint32_t sum_sojourn_msdu[CDP_DATA_TID_MAX]; uint32_t num_msdus[CDP_DATA_TID_MAX]; }; diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 5f18d8102f..97330fc711 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3033,6 +3033,12 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, pdev->tlv_count = 0; pdev->list_depth = 0; + qdf_mem_zero(&pdev->sojourn_stats, sizeof(struct cdp_tx_sojourn_stats)); + + pdev->sojourn_buf = qdf_nbuf_alloc(pdev->soc->osdev, + sizeof(struct cdp_tx_sojourn_stats), 0, 4, + TRUE); + /* initlialize cal client timer */ dp_cal_client_attach(&pdev->cal_client_ctx, pdev, pdev->soc->osdev, &dp_iterate_update_peer_list); @@ -3204,6 +3210,8 @@ static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force) dp_htt_ppdu_stats_detach(pdev); + qdf_nbuf_free(pdev->sojourn_buf); + dp_cal_client_detach(&pdev->cal_client_ctx); soc->pdev_list[pdev->pdev_id] = NULL; soc->pdev_count--; diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 82f0fe4940..8cede3e484 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -2779,6 +2779,68 @@ static inline void dp_tx_notify_completion(struct dp_soc *soc, tx_compl_cbk(netbuf, osif_dev); } +/** dp_tx_sojourn_stats_process() - Collect sojourn stats + * @pdev: pdev handle + * @tid: tid value + * @txdesc_ts: timestamp from txdesc + * @ppdu_id: ppdu id + * + * Return: none + */ +#ifdef FEATURE_PERPKT_INFO +static inline void dp_tx_sojourn_stats_process(struct dp_pdev *pdev, + uint8_t tid, + uint64_t txdesc_ts, + uint32_t ppdu_id) +{ + uint64_t delta_ms; + struct cdp_tx_sojourn_stats *sojourn_stats; + + if (pdev->enhanced_stats_en == 0) + return; + + if (pdev->sojourn_stats.ppdu_seq_id == 0) + pdev->sojourn_stats.ppdu_seq_id = ppdu_id; + + if (ppdu_id != pdev->sojourn_stats.ppdu_seq_id) { + if (!pdev->sojourn_buf) + return; + + sojourn_stats = (struct cdp_tx_sojourn_stats *) + qdf_nbuf_data(pdev->sojourn_buf); + + qdf_mem_copy(sojourn_stats, &pdev->sojourn_stats, + sizeof(struct cdp_tx_sojourn_stats)); + + qdf_mem_zero(&pdev->sojourn_stats, + sizeof(struct cdp_tx_sojourn_stats)); + + dp_wdi_event_handler(WDI_EVENT_TX_SOJOURN_STAT, pdev->soc, + pdev->sojourn_buf, HTT_INVALID_PEER, + WDI_NO_VAL, pdev->pdev_id); + + pdev->sojourn_stats.ppdu_seq_id = ppdu_id; + } + + if (tid == HTT_INVALID_TID) + return; + + delta_ms = qdf_ktime_to_ms(qdf_ktime_get()) - + txdesc_ts; + qdf_ewma_tx_lag_add(&pdev->sojourn_stats.avg_sojourn_msdu[tid], + delta_ms); + pdev->sojourn_stats.sum_sojourn_msdu[tid] += delta_ms; + pdev->sojourn_stats.num_msdus[tid]++; +} +#else +static inline void dp_tx_sojourn_stats_process(struct dp_pdev *pdev, + uint8_t tid, + uint64_t txdesc_ts, + uint32_t ppdu_id) +{ +} +#endif + /** * dp_tx_comp_process_tx_status() - Parse and Dump Tx completion status info * @tx_desc: software descriptor head pointer @@ -2859,12 +2921,15 @@ static inline void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc, DP_STATS_INC_PKT(peer, tx.bcast, 1, length); } + dp_tx_sojourn_stats_process(vdev->pdev, ts.tid, + tx_desc->timestamp, + ts.ppdu_id); + dp_tx_update_peer_stats(peer, &ts, length); out: return; } - /** * dp_tx_comp_process_desc() - Tx complete software descriptor handler * @soc: core txrx main context @@ -2924,9 +2989,11 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc, DP_HIST_PACKET_COUNT_INC(desc->pdev->pdev_id); next = desc->next; + dp_tx_desc_release(desc, desc->pool_id); desc = next; } + DP_TX_HIST_STATS_PER_PDEV(); } diff --git a/dp/wifi3.0/dp_tx_desc.h b/dp/wifi3.0/dp_tx_desc.h index 79ca247240..48ca397b19 100644 --- a/dp/wifi3.0/dp_tx_desc.h +++ b/dp/wifi3.0/dp_tx_desc.h @@ -310,6 +310,8 @@ static inline struct dp_tx_desc_s *dp_tx_desc_alloc(struct dp_soc *soc, soc->tx_desc[desc_pool_id].num_allocated++; soc->tx_desc[desc_pool_id].num_free--; + tx_desc->timestamp = qdf_ktime_to_ms(qdf_ktime_get()); + tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED; TX_DESC_LOCK_UNLOCK(&soc->tx_desc[desc_pool_id].lock); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 23bcd56c06..2b7893271d 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -299,6 +299,7 @@ struct dp_tx_desc_s { void *me_buffer; void *tso_desc; void *tso_num_desc; + uint64_t timestamp; }; /** @@ -1235,6 +1236,9 @@ struct dp_pdev { uint8_t is_primary; /* Context of cal client timer */ void *cal_client_ctx; + struct cdp_tx_sojourn_stats sojourn_stats; + qdf_nbuf_t sojourn_buf; + }; struct dp_peer; diff --git a/qdf/inc/qdf_util.h b/qdf/inc/qdf_util.h index ccd47b9cd6..1901644804 100644 --- a/qdf/inc/qdf_util.h +++ b/qdf/inc/qdf_util.h @@ -108,6 +108,20 @@ typedef __qdf_wait_queue_head_t qdf_wait_queue_head_t; (_a)[4] == 0xff && \ (_a)[5] == 0xff) +#define QDF_DECLARE_EWMA(name, factor, weight) \ + _QDF_DECLARE_EWMA(name, factor, weight) + +#define qdf_ewma_tx_lag _qdf_ewma_tx_lag + +#define qdf_ewma_tx_lag_init(tx_lag) \ + _qdf_ewma_tx_lag_init(tx_lag) + +#define qdf_ewma_tx_lag_add(tx_lag, value) \ + _qdf_ewma_tx_lag_add(tx_lag, value) + +#define qdf_ewma_tx_lag_read(tx_lag) \ + _qdf_ewma_tx_lag_read(tx_lag) + /** * qdf_status_to_os_return - returns the status to OS. * @status: enum QDF_STATUS diff --git a/qdf/linux/src/i_qdf_util.h b/qdf/linux/src/i_qdf_util.h index 8682530e91..abc2300722 100644 --- a/qdf/linux/src/i_qdf_util.h +++ b/qdf/linux/src/i_qdf_util.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -280,6 +281,10 @@ static inline bool __qdf_is_macaddr_equal(struct qdf_mac_addr *mac_addr1, #define __qdf_min(_a, _b) min(_a, _b) #define __qdf_max(_a, _b) max(_a, _b) +#define _QDF_DECLARE_EWMA(name, _factor, _weight) \ + DECLARE_EWMA(name, _factor, _weight) + +#define _qdf_ewma_tx_lag struct ewma_tx_lag #define __qdf_ffz(mask) (~(mask) == 0 ? -1 : ffz(mask)) @@ -350,6 +355,15 @@ static inline bool __qdf_is_macaddr_equal(struct qdf_mac_addr *mac_addr1, #define __qdf_roundup(x, y) roundup(x, y) +#define _qdf_ewma_tx_lag_init(tx_lag) \ + ewma_tx_lag_init(tx_lag) + +#define _qdf_ewma_tx_lag_add(tx_lag, value) \ + ewma_tx_lag_add(tx_lag, value) + +#define _qdf_ewma_tx_lag_read(tx_lag) \ + ewma_tx_lag_read(tx_lag) + #ifdef QCA_CONFIG_SMP /** * __qdf_get_cpu() - get cpu_index