diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index e1be4f2db48a..c29231bd70ed 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -111,9 +111,14 @@ #ifdef CONFIG_MCL #define CDP_WDI_NUM_EVENTS WDI_NUM_EVENTS #else -#define CDP_WDI_NUM_EVENTS 22 +#define CDP_WDI_NUM_EVENTS 26 #endif +#define CDP_FC_RETRY_OFFSET 0x4 +#define CDP_FC_RETRY_MASK (CDP_FC_RETRY_OFFSET << 1) +#define CDP_FC_IS_RETRY_SET(_fc) \ + ((_fc) && CDP_FC_RETRY_MASK) + /* Different Packet Types */ enum cdp_packet_type { DOT11_A = 0, diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 643200b11939..3b729edaea1f 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -148,6 +148,7 @@ dp_tx_rate_stats_update(struct dp_peer *peer, if (!ratekbps) return; + ppdu->rix = rix; peer->stats.tx.avg_tx_rate = dp_ath_rate_lpf(peer->stats.tx.avg_tx_rate, ratekbps); ppdu_tx_rate = dp_ath_rate_out(peer->stats.tx.avg_tx_rate); @@ -2613,6 +2614,7 @@ void dp_ppdu_desc_deliver(struct dp_pdev *pdev, ppdu_desc->ack_rssi); } + ppdu_desc->user[i].cookie = (void *)peer->wlanstats_ctx; dp_tx_rate_stats_update(peer, &ppdu_desc->user[i]); dp_peer_unref_del_find_by_id(peer); tlv_bitmap_expected = tlv_bitmap_default; diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 74a630e8c486..ea01811ed527 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4777,6 +4777,7 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev; struct dp_soc *soc; + struct cdp_peer_cookie peer_cookie; enum cdp_txrx_ast_entry_type ast_type = CDP_TXRX_AST_TYPE_STATIC; /* preconditions */ @@ -4915,6 +4916,24 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, dp_local_peer_id_alloc(pdev, peer); DP_STATS_INIT(peer); + + qdf_mem_copy(peer_cookie.mac_addr, peer->mac_addr.raw, + CDP_MAC_ADDR_LEN); + peer_cookie.ctx = NULL; + peer_cookie.cookie = pdev->next_peer_cookie++; +#if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE + dp_wdi_event_handler(WDI_EVENT_PEER_CREATE, pdev->soc, + (void *)&peer_cookie, + peer->peer_ids[0], WDI_NO_VAL, pdev->pdev_id); +#endif + if (soc->wlanstats_enabled) { + if (!peer_cookie.ctx) { + pdev->next_peer_cookie--; + qdf_err("Failed to initialize peer rate stats"); + } else { + peer->wlanstats_ctx = (void *)peer_cookie.ctx; + } + } return (void *)peer; } @@ -5393,6 +5412,7 @@ void dp_peer_unref_delete(void *peer_handle) uint16_t peer_id; uint16_t vdev_id; bool delete_vdev; + struct cdp_peer_cookie peer_cookie; /* * Hold the lock all the way from checking if the peer ref count @@ -5446,6 +5466,21 @@ void dp_peer_unref_delete(void *peer_handle) peer, vdev, &peer->vdev->peer_list); } + /* send peer destroy event to upper layer */ + qdf_mem_copy(peer_cookie.mac_addr, peer->mac_addr.raw, + CDP_MAC_ADDR_LEN); + peer_cookie.ctx = NULL; + peer_cookie.ctx = (void *)peer->wlanstats_ctx; +#if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE + dp_wdi_event_handler(WDI_EVENT_PEER_DESTROY, + pdev->soc, + (void *)&peer_cookie, + peer->peer_ids[0], + WDI_NO_VAL, + pdev->pdev_id); +#endif + peer->wlanstats_ctx = NULL; + /* cleanup the peer data */ dp_peer_cleanup(vdev, peer); @@ -9297,6 +9332,81 @@ static void dp_pdev_set_ctrl_pdev(struct cdp_pdev *dp_pdev, pdev->ctrl_pdev = ctrl_pdev; } +static void dp_set_rate_stats_cap(struct cdp_soc_t *soc_hdl, + uint8_t val) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + + soc->wlanstats_enabled = val; +} + +static void dp_soc_set_rate_stats_ctx(struct cdp_soc_t *soc_handle, + void *stats_ctx) +{ + struct dp_soc *soc = (struct dp_soc *)soc_handle; + + soc->rate_stats_ctx = stats_ctx; +} + +#if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE +static void dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl, + struct cdp_pdev *pdev_hdl) +{ + struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl; + struct dp_soc *soc = (struct dp_soc *)pdev->soc; + struct dp_vdev *vdev = NULL; + struct dp_peer *peer = NULL; + + qdf_spin_lock_bh(&soc->peer_ref_mutex); + qdf_spin_lock_bh(&pdev->vdev_list_lock); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + if (peer) + dp_wdi_event_handler( + WDI_EVENT_FLUSH_RATE_STATS_REQ, + pdev->soc, peer->wlanstats_ctx, + peer->peer_ids[0], + WDI_NO_VAL, pdev->pdev_id); + } + } + qdf_spin_unlock_bh(&pdev->vdev_list_lock); + qdf_spin_unlock_bh(&soc->peer_ref_mutex); +} +#else +static inline void +dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl, + struct cdp_pdev *pdev_hdl) +{ +} +#endif + +#if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE +static void dp_peer_flush_rate_stats(struct cdp_soc_t *soc, + struct cdp_pdev *pdev_handle, + void *buf) +{ + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + + dp_wdi_event_handler(WDI_EVENT_PEER_FLUSH_RATE_STATS, + pdev->soc, buf, HTT_INVALID_PEER, + WDI_NO_VAL, pdev->pdev_id); +} +#else +static inline void +dp_peer_flush_rate_stats(struct cdp_soc_t *soc, + struct cdp_pdev *pdev_handle, + void *buf) +{ +} +#endif + +static void *dp_soc_get_rate_stats_ctx(struct cdp_soc_t *soc_handle) +{ + struct dp_soc *soc = (struct dp_soc *)soc_handle; + + return soc->rate_stats_ctx; +} + /* * dp_get_cfg() - get dp cfg * @soc: cdp soc handle @@ -9497,6 +9607,10 @@ static struct cdp_cmn_ops dp_ops_cmn = { .delba_tx_completion = dp_delba_tx_completion_wifi3, .get_dp_capabilities = dp_get_cfg_capabilities, .txrx_get_cfg = dp_get_cfg, + .set_rate_stats_ctx = dp_soc_set_rate_stats_ctx, + .get_rate_stats_ctx = dp_soc_get_rate_stats_ctx, + .txrx_peer_flush_rate_stats = dp_peer_flush_rate_stats, + .txrx_flush_rate_stats_request = dp_flush_rate_stats_req, }; static struct cdp_ctrl_ops dp_ops_ctrl = { @@ -9564,6 +9678,7 @@ static struct cdp_host_stats_ops dp_ops_host_stats = { .txrx_reset_peer_stats = dp_txrx_reset_peer_stats, .txrx_get_pdev_stats = dp_txrx_get_pdev_stats, .txrx_get_ratekbps = dp_txrx_get_ratekbps, + .configure_rate_stats = dp_set_rate_stats_cap, /* TODO */ }; diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index b9b3e1ce091a..60f8c3a67020 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -85,6 +85,9 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count + cdp_rx_ppdu->udp_msdu_count + cdp_rx_ppdu->other_msdu_count); + cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len; + if (CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl)) + cdp_rx_ppdu->retries += ppdu_info->com_info.mpdu_cnt_fcs_ok; if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1) cdp_rx_ppdu->is_ampdu = 1; @@ -159,6 +162,7 @@ static inline void dp_rx_rate_stats_update(struct dp_peer *peer, if (!ratekbps) return; + ppdu->rix = rix; DP_STATS_UPD(peer, rx.last_rx_rate, ratekbps); dp_ath_rate_lpf(peer->stats.rx.avg_rx_rate, ratekbps); ppdu_rx_rate = dp_ath_rate_out(peer->stats.rx.avg_rx_rate); @@ -439,6 +443,7 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev, cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data; peer = dp_peer_find_by_id(soc, cdp_rx_ppdu->peer_id); if (peer) { + cdp_rx_ppdu->cookie = (void *)peer->wlanstats_ctx; dp_rx_stats_update(pdev, peer, cdp_rx_ppdu); dp_peer_unref_del_find_by_id(peer); } diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 35661ac5f20d..942eb45fee6f 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -2969,12 +2969,14 @@ static inline void dp_tx_notify_completion(struct dp_soc *soc, */ #ifdef FEATURE_PERPKT_INFO static inline void dp_tx_sojourn_stats_process(struct dp_pdev *pdev, + struct dp_peer *peer, uint8_t tid, uint64_t txdesc_ts, uint32_t ppdu_id) { uint64_t delta_ms; struct cdp_tx_sojourn_stats *sojourn_stats; + uint8_t tidno; if (pdev->enhanced_stats_en == 0) return; @@ -2992,8 +2994,12 @@ static inline void dp_tx_sojourn_stats_process(struct dp_pdev *pdev, 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)); + sojourn_stats->cookie = (void *)peer->wlanstats_ctx; + + for (tidno = 0; tidno < CDP_DATA_TID_MAX; tidno++) { + pdev->sojourn_stats.sum_sojourn_msdu[tidno] = 0; + pdev->sojourn_stats.num_msdus[tidno] = 0; + } dp_wdi_event_handler(WDI_EVENT_TX_SOJOURN_STAT, pdev->soc, pdev->sojourn_buf, HTT_INVALID_PEER, @@ -3160,6 +3166,13 @@ void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc, dp_tx_update_peer_stats(tx_desc, ts, peer); +#ifdef QCA_SUPPORT_RDK_STATS + if (soc->wlanstats_enabled) + dp_tx_sojourn_stats_process(vdev->pdev, peer, ts->tid, + tx_desc->timestamp, + ts->ppdu_id); +#endif + out: return; } diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index c748266c17a3..c52936237075 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -107,6 +107,8 @@ struct dp_vdev; struct dp_tx_desc_s; struct dp_soc; union dp_rx_desc_list_elem_t; +struct cdp_peer_rate_stats_ctx; +struct cdp_soc_rate_stats_ctx; #define DP_PDEV_ITERATE_VDEV_LIST(_pdev, _vdev) \ TAILQ_FOREACH((_vdev), &(_pdev)->vdev_list, vdev_list_elem) @@ -1018,6 +1020,10 @@ struct dp_soc { uint8_t da_war_enabled; /* number of active ast entries */ uint32_t num_ast_entries; + /* rdk rate statistics context at soc level*/ + struct cdp_soc_rate_stats_ctx *rate_stats_ctx; + /* rdk rate statistics control flag */ + bool wlanstats_enabled; }; #ifdef IPA_OFFLOAD @@ -1396,6 +1402,9 @@ struct dp_pdev { /* User configured max number of tx buffers */ uint32_t num_tx_allowed; + + /* unique cookie required for peer session */ + uint32_t next_peer_cookie; }; struct dp_peer; @@ -1668,6 +1677,9 @@ struct dp_peer { * disabled */ uint8_t peer_based_pktlog_filter; + + /* rdk statistics context */ + struct cdp_peer_rate_stats_ctx *wlanstats_ctx; }; #ifdef CONFIG_WIN