diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index a79cad3a71..6a6b185ef5 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -237,6 +237,266 @@ while (0) #endif #define DP_HTT_T2H_HP_PIPE 5 +static inline void dp_update_pdev_stats(struct dp_pdev *tgtobj, + struct cdp_vdev_stats *srcobj) +{ + uint8_t i; + uint8_t pream_type; + + for (pream_type = 0; pream_type < DOT11_MAX; pream_type++) { + for (i = 0; i < MAX_MCS; i++) { + tgtobj->stats.tx.pkt_type[pream_type]. + mcs_count[i] += + srcobj->tx.pkt_type[pream_type]. + mcs_count[i]; + tgtobj->stats.rx.pkt_type[pream_type]. + mcs_count[i] += + srcobj->rx.pkt_type[pream_type]. + mcs_count[i]; + } + } + + for (i = 0; i < MAX_BW; i++) { + tgtobj->stats.tx.bw[i] += srcobj->tx.bw[i]; + tgtobj->stats.rx.bw[i] += srcobj->rx.bw[i]; + } + + for (i = 0; i < SS_COUNT; i++) { + tgtobj->stats.tx.nss[i] += srcobj->tx.nss[i]; + tgtobj->stats.rx.nss[i] += srcobj->rx.nss[i]; + } + + for (i = 0; i < WME_AC_MAX; i++) { + tgtobj->stats.tx.wme_ac_type[i] += + srcobj->tx.wme_ac_type[i]; + tgtobj->stats.rx.wme_ac_type[i] += + srcobj->rx.wme_ac_type[i]; + tgtobj->stats.tx.excess_retries_per_ac[i] += + srcobj->tx.excess_retries_per_ac[i]; + } + + for (i = 0; i < MAX_GI; i++) { + tgtobj->stats.tx.sgi_count[i] += + srcobj->tx.sgi_count[i]; + tgtobj->stats.rx.sgi_count[i] += + srcobj->rx.sgi_count[i]; + } + + for (i = 0; i < MAX_RECEPTION_TYPES; i++) + tgtobj->stats.rx.reception_type[i] += + srcobj->rx.reception_type[i]; + + tgtobj->stats.tx.comp_pkt.bytes += srcobj->tx.comp_pkt.bytes; + tgtobj->stats.tx.comp_pkt.num += srcobj->tx.comp_pkt.num; + tgtobj->stats.tx.ucast.num += srcobj->tx.ucast.num; + tgtobj->stats.tx.ucast.bytes += srcobj->tx.ucast.bytes; + tgtobj->stats.tx.mcast.num += srcobj->tx.mcast.num; + tgtobj->stats.tx.mcast.bytes += srcobj->tx.mcast.bytes; + tgtobj->stats.tx.bcast.num += srcobj->tx.bcast.num; + tgtobj->stats.tx.bcast.bytes += srcobj->tx.bcast.bytes; + tgtobj->stats.tx.tx_success.num += srcobj->tx.tx_success.num; + tgtobj->stats.tx.tx_success.bytes += + srcobj->tx.tx_success.bytes; + tgtobj->stats.tx.nawds_mcast.num += + srcobj->tx.nawds_mcast.num; + tgtobj->stats.tx.nawds_mcast.bytes += + srcobj->tx.nawds_mcast.bytes; + tgtobj->stats.tx.tx_failed += srcobj->tx.tx_failed; + tgtobj->stats.tx.ofdma += srcobj->tx.ofdma; + tgtobj->stats.tx.stbc += srcobj->tx.stbc; + tgtobj->stats.tx.ldpc += srcobj->tx.ldpc; + tgtobj->stats.tx.retries += srcobj->tx.retries; + tgtobj->stats.tx.non_amsdu_cnt += srcobj->tx.non_amsdu_cnt; + tgtobj->stats.tx.amsdu_cnt += srcobj->tx.amsdu_cnt; + tgtobj->stats.tx.dropped.fw_rem += srcobj->tx.dropped.fw_rem; + tgtobj->stats.tx.dropped.fw_rem_tx += + srcobj->tx.dropped.fw_rem_tx; + tgtobj->stats.tx.dropped.fw_rem_notx += + srcobj->tx.dropped.fw_rem_notx; + tgtobj->stats.tx.dropped.fw_reason1 += + srcobj->tx.dropped.fw_reason1; + tgtobj->stats.tx.dropped.fw_reason2 += + srcobj->tx.dropped.fw_reason2; + tgtobj->stats.tx.dropped.fw_reason3 += + srcobj->tx.dropped.fw_reason3; + tgtobj->stats.tx.dropped.age_out += srcobj->tx.dropped.age_out; + tgtobj->stats.rx.err.mic_err += srcobj->rx.err.mic_err; + tgtobj->stats.rx.rssi = srcobj->rx.rssi; + tgtobj->stats.rx.rx_rate = srcobj->rx.rx_rate; + tgtobj->stats.rx.err.decrypt_err += srcobj->rx.err.decrypt_err; + tgtobj->stats.rx.non_ampdu_cnt += srcobj->rx.non_ampdu_cnt; + tgtobj->stats.rx.amsdu_cnt += srcobj->rx.ampdu_cnt; + tgtobj->stats.rx.non_amsdu_cnt += srcobj->rx.non_amsdu_cnt; + tgtobj->stats.rx.amsdu_cnt += srcobj->rx.amsdu_cnt; + tgtobj->stats.rx.to_stack.num += srcobj->rx.to_stack.num; + tgtobj->stats.rx.to_stack.bytes += srcobj->rx.to_stack.bytes; + + for (i = 0; i < CDP_MAX_RX_RINGS; i++) { + tgtobj->stats.rx.rcvd_reo[i].num += + srcobj->rx.rcvd_reo[i].num; + tgtobj->stats.rx.rcvd_reo[i].bytes += + srcobj->rx.rcvd_reo[i].bytes; + } + + srcobj->rx.unicast.num = + srcobj->rx.to_stack.num - + (srcobj->rx.multicast.num + + srcobj->rx.bcast.num); + srcobj->rx.unicast.bytes = + srcobj->rx.to_stack.bytes - + (srcobj->rx.multicast.bytes + + srcobj->rx.bcast.bytes); + + tgtobj->stats.rx.unicast.num += srcobj->rx.unicast.num; + tgtobj->stats.rx.unicast.bytes += srcobj->rx.unicast.bytes; + tgtobj->stats.rx.multicast.num += srcobj->rx.multicast.num; + tgtobj->stats.rx.multicast.bytes += srcobj->rx.multicast.bytes; + tgtobj->stats.rx.bcast.num += srcobj->rx.bcast.num; + tgtobj->stats.rx.bcast.bytes += srcobj->rx.bcast.bytes; + tgtobj->stats.rx.raw.num += srcobj->rx.raw.num; + tgtobj->stats.rx.raw.bytes += srcobj->rx.raw.bytes; + tgtobj->stats.rx.intra_bss.pkts.num += + srcobj->rx.intra_bss.pkts.num; + tgtobj->stats.rx.intra_bss.pkts.bytes += + srcobj->rx.intra_bss.pkts.bytes; + tgtobj->stats.rx.intra_bss.fail.num += + srcobj->rx.intra_bss.fail.num; + tgtobj->stats.rx.intra_bss.fail.bytes += + srcobj->rx.intra_bss.fail.bytes; + + tgtobj->stats.tx.last_ack_rssi = + srcobj->tx.last_ack_rssi; +} + +static inline void dp_update_vdev_stats(struct cdp_vdev_stats *tgtobj, + struct dp_peer *srcobj) +{ + uint8_t i; + uint8_t pream_type; + + for (pream_type = 0; pream_type < DOT11_MAX; pream_type++) { + for (i = 0; i < MAX_MCS; i++) { + tgtobj->tx.pkt_type[pream_type]. + mcs_count[i] += + srcobj->stats.tx.pkt_type[pream_type]. + mcs_count[i]; + tgtobj->rx.pkt_type[pream_type]. + mcs_count[i] += + srcobj->stats.rx.pkt_type[pream_type]. + mcs_count[i]; + } + } + + for (i = 0; i < MAX_BW; i++) { + tgtobj->tx.bw[i] += srcobj->stats.tx.bw[i]; + tgtobj->rx.bw[i] += srcobj->stats.rx.bw[i]; + } + + for (i = 0; i < SS_COUNT; i++) { + tgtobj->tx.nss[i] += srcobj->stats.tx.nss[i]; + tgtobj->rx.nss[i] += srcobj->stats.rx.nss[i]; + } + + for (i = 0; i < WME_AC_MAX; i++) { + tgtobj->tx.wme_ac_type[i] += + srcobj->stats.tx.wme_ac_type[i]; + tgtobj->rx.wme_ac_type[i] += + srcobj->stats.rx.wme_ac_type[i]; + tgtobj->tx.excess_retries_per_ac[i] += + srcobj->stats.tx.excess_retries_per_ac[i]; + } + + for (i = 0; i < MAX_GI; i++) { + tgtobj->tx.sgi_count[i] += + srcobj->stats.tx.sgi_count[i]; + tgtobj->rx.sgi_count[i] += + srcobj->stats.rx.sgi_count[i]; + } + + for (i = 0; i < MAX_RECEPTION_TYPES; i++) + tgtobj->rx.reception_type[i] += + srcobj->stats.rx.reception_type[i]; + + tgtobj->tx.comp_pkt.bytes += srcobj->stats.tx.comp_pkt.bytes; + tgtobj->tx.comp_pkt.num += srcobj->stats.tx.comp_pkt.num; + tgtobj->tx.ucast.num += srcobj->stats.tx.ucast.num; + tgtobj->tx.ucast.bytes += srcobj->stats.tx.ucast.bytes; + tgtobj->tx.mcast.num += srcobj->stats.tx.mcast.num; + tgtobj->tx.mcast.bytes += srcobj->stats.tx.mcast.bytes; + tgtobj->tx.bcast.num += srcobj->stats.tx.bcast.num; + tgtobj->tx.bcast.bytes += srcobj->stats.tx.bcast.bytes; + tgtobj->tx.tx_success.num += srcobj->stats.tx.tx_success.num; + tgtobj->tx.tx_success.bytes += + srcobj->stats.tx.tx_success.bytes; + tgtobj->tx.nawds_mcast.num += + srcobj->stats.tx.nawds_mcast.num; + tgtobj->tx.nawds_mcast.bytes += + srcobj->stats.tx.nawds_mcast.bytes; + tgtobj->tx.tx_failed += srcobj->stats.tx.tx_failed; + tgtobj->tx.ofdma += srcobj->stats.tx.ofdma; + tgtobj->tx.stbc += srcobj->stats.tx.stbc; + tgtobj->tx.ldpc += srcobj->stats.tx.ldpc; + tgtobj->tx.retries += srcobj->stats.tx.retries; + tgtobj->tx.non_amsdu_cnt += srcobj->stats.tx.non_amsdu_cnt; + tgtobj->tx.amsdu_cnt += srcobj->stats.tx.amsdu_cnt; + tgtobj->tx.dropped.fw_rem += srcobj->stats.tx.dropped.fw_rem; + tgtobj->tx.dropped.fw_rem_tx += + srcobj->stats.tx.dropped.fw_rem_tx; + tgtobj->tx.dropped.fw_rem_notx += + srcobj->stats.tx.dropped.fw_rem_notx; + tgtobj->tx.dropped.fw_reason1 += + srcobj->stats.tx.dropped.fw_reason1; + tgtobj->tx.dropped.fw_reason2 += + srcobj->stats.tx.dropped.fw_reason2; + tgtobj->tx.dropped.fw_reason3 += + srcobj->stats.tx.dropped.fw_reason3; + tgtobj->tx.dropped.age_out += srcobj->stats.tx.dropped.age_out; + tgtobj->rx.err.mic_err += srcobj->stats.rx.err.mic_err; + tgtobj->rx.rssi = srcobj->stats.rx.rssi; + tgtobj->rx.rx_rate = srcobj->stats.rx.rx_rate; + tgtobj->rx.err.decrypt_err += srcobj->stats.rx.err.decrypt_err; + tgtobj->rx.non_ampdu_cnt += srcobj->stats.rx.non_ampdu_cnt; + tgtobj->rx.amsdu_cnt += srcobj->stats.rx.ampdu_cnt; + tgtobj->rx.non_amsdu_cnt += srcobj->stats.rx.non_amsdu_cnt; + tgtobj->rx.amsdu_cnt += srcobj->stats.rx.amsdu_cnt; + tgtobj->rx.to_stack.num += srcobj->stats.rx.to_stack.num; + tgtobj->rx.to_stack.bytes += srcobj->stats.rx.to_stack.bytes; + + for (i = 0; i < CDP_MAX_RX_RINGS; i++) { + tgtobj->rx.rcvd_reo[i].num += + srcobj->stats.rx.rcvd_reo[i].num; + tgtobj->rx.rcvd_reo[i].bytes += + srcobj->stats.rx.rcvd_reo[i].bytes; + } + + srcobj->stats.rx.unicast.num = + srcobj->stats.rx.to_stack.num - + (srcobj->stats.rx.multicast.num + + srcobj->stats.rx.bcast.num); + srcobj->stats.rx.unicast.bytes = + srcobj->stats.rx.to_stack.bytes - + (srcobj->stats.rx.multicast.bytes + + srcobj->stats.rx.bcast.bytes); + + tgtobj->rx.unicast.num += srcobj->stats.rx.unicast.num; + tgtobj->rx.unicast.bytes += srcobj->stats.rx.unicast.bytes; + tgtobj->rx.multicast.num += srcobj->stats.rx.multicast.num; + tgtobj->rx.multicast.bytes += srcobj->stats.rx.multicast.bytes; + tgtobj->rx.bcast.num += srcobj->stats.rx.bcast.num; + tgtobj->rx.bcast.bytes += srcobj->stats.rx.bcast.bytes; + tgtobj->rx.raw.num += srcobj->stats.rx.raw.num; + tgtobj->rx.raw.bytes += srcobj->stats.rx.raw.bytes; + tgtobj->rx.intra_bss.pkts.num += + srcobj->stats.rx.intra_bss.pkts.num; + tgtobj->rx.intra_bss.pkts.bytes += + srcobj->stats.rx.intra_bss.pkts.bytes; + tgtobj->rx.intra_bss.fail.num += + srcobj->stats.rx.intra_bss.fail.num; + tgtobj->rx.intra_bss.fail.bytes += + srcobj->stats.rx.intra_bss.fail.bytes; + tgtobj->tx.last_ack_rssi = + srcobj->stats.tx.last_ack_rssi; +} #define DP_UPDATE_STATS(_tgtobj, _srcobj) \ do { \ @@ -406,7 +666,8 @@ extern QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc, extern void dp_reo_cmdlist_destroy(struct dp_soc *soc); extern void dp_reo_status_ring_handler(struct dp_soc *soc); -void dp_aggregate_vdev_stats(struct dp_vdev *vdev); +void dp_aggregate_vdev_stats(struct dp_vdev *vdev, + struct cdp_vdev_stats *vdev_stats); void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status); void dp_rx_bar_stats_cb(struct dp_soc *soc, void *cb_ctxt, diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 1dbb70c145..16cf4d46fd 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4588,7 +4588,7 @@ void dp_peer_unref_delete(void *peer_handle) qdf_mempool_free(soc->osdev, soc->mempool_ol_ath_peer, peer); #else bss_peer = vdev->vap_bss_peer; - DP_UPDATE_STATS(bss_peer, peer); + DP_UPDATE_STATS(vdev, peer); free_peer: qdf_mem_free(peer); @@ -5221,16 +5221,16 @@ void dp_rx_bar_stats_cb(struct dp_soc *soc, void *cb_ctxt, * * return: void */ -void dp_aggregate_vdev_stats(struct dp_vdev *vdev) +void dp_aggregate_vdev_stats(struct dp_vdev *vdev, + struct cdp_vdev_stats *vdev_stats) { struct dp_peer *peer = NULL; struct dp_soc *soc = vdev->pdev->soc; - qdf_mem_set(&(vdev->stats.tx), sizeof(vdev->stats.tx), 0x0); - qdf_mem_set(&(vdev->stats.rx), sizeof(vdev->stats.rx), 0x0); + qdf_mem_copy(vdev_stats, &vdev->stats, sizeof(vdev->stats)); TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) - DP_UPDATE_STATS(vdev, peer); + dp_update_vdev_stats(vdev_stats, peer); if (soc->cdp_soc.ol_ops->update_dp_stats) soc->cdp_soc.ol_ops->update_dp_stats(vdev->pdev->ctrl_pdev, @@ -5249,6 +5249,14 @@ static inline void dp_aggregate_pdev_stats(struct dp_pdev *pdev) { struct dp_vdev *vdev = NULL; struct dp_soc *soc = pdev->soc; + struct cdp_vdev_stats *vdev_stats = + qdf_mem_malloc(sizeof(struct cdp_vdev_stats)); + + if (!vdev_stats) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "DP alloc failure - unable to get alloc vdev stats"); + return; + } qdf_mem_set(&(pdev->stats.tx), sizeof(pdev->stats.tx), 0x0); qdf_mem_set(&(pdev->stats.rx), sizeof(pdev->stats.rx), 0x0); @@ -5257,8 +5265,8 @@ static inline void dp_aggregate_pdev_stats(struct dp_pdev *pdev) qdf_spin_lock_bh(&pdev->vdev_list_lock); TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { - dp_aggregate_vdev_stats(vdev); - DP_UPDATE_STATS(pdev, vdev); + dp_aggregate_vdev_stats(vdev, vdev_stats); + dp_update_pdev_stats(pdev, vdev_stats); DP_STATS_AGGR_PKT(pdev, vdev, tx_i.nawds_mcast); @@ -5305,6 +5313,8 @@ static inline void dp_aggregate_pdev_stats(struct dp_pdev *pdev) vdev->stats.tx_i.tso.num_seg; } qdf_spin_unlock_bh(&pdev->vdev_list_lock); + qdf_mem_free(vdev_stats); + if (soc->cdp_soc.ol_ops->update_dp_stats) soc->cdp_soc.ol_ops->update_dp_stats(pdev->ctrl_pdev, &pdev->stats, pdev->pdev_id, UPDATE_PDEV_STATS); @@ -5322,8 +5332,31 @@ static void dp_vdev_getstats(void *vdev_handle, struct cdp_dev_stats *stats) { struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct cdp_vdev_stats *vdev_stats = + qdf_mem_malloc(sizeof(struct cdp_vdev_stats)); + + if (!vdev_stats) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "DP alloc failure - unable to get alloc vdev stats"); + return; + } + + dp_aggregate_vdev_stats(vdev, vdev_stats); + + stats->tx_packets = vdev_stats->tx_i.rcvd.num; + stats->tx_bytes = vdev_stats->tx_i.rcvd.bytes; + + stats->tx_errors = vdev_stats->tx.tx_failed + + vdev_stats->tx_i.dropped.dropped_pkt.num; + stats->tx_dropped = stats->tx_errors; + + stats->rx_packets = vdev_stats->rx.unicast.num + + vdev_stats->rx.multicast.num + + vdev_stats->rx.bcast.num; + stats->rx_bytes = vdev_stats->rx.unicast.bytes + + vdev_stats->rx.multicast.bytes + + vdev_stats->rx.bcast.bytes; - dp_aggregate_vdev_stats(vdev); } @@ -6713,6 +6746,55 @@ static void dp_set_vdev_dscp_tid_map_wifi3(struct cdp_vdev *vdev_handle, return; } +/* dp_txrx_get_peer_stats - will return cdp_peer_stats + * @peer_handle: DP_PEER handle + * + * return : cdp_peer_stats pointer + */ +static struct cdp_peer_stats* + dp_txrx_get_peer_stats(struct cdp_peer *peer_handle) +{ + struct dp_peer *peer = (struct dp_peer *)peer_handle; + + qdf_assert(peer); + + return &peer->stats; +} + +/* dp_txrx_reset_peer_stats - reset cdp_peer_stats for particular peer + * @peer_handle: DP_PEER handle + * + * return : void + */ +static void dp_txrx_reset_peer_stats(struct cdp_peer *peer_handle) +{ + struct dp_peer *peer = (struct dp_peer *)peer_handle; + + qdf_assert(peer); + + qdf_mem_set(&peer->stats, sizeof(peer->stats), 0); +} + +/* dp_txrx_get_vdev_stats - Update buffer with cdp_vdev_stats + * @vdev_handle: DP_VDEV handle + * @buf: buffer for vdev stats + * + * return : int + */ +static int dp_txrx_get_vdev_stats(struct cdp_vdev *vdev_handle, void *buf, + bool is_aggregate) +{ + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct cdp_vdev_stats *vdev_stats = (struct cdp_vdev_stats *)buf; + + if (is_aggregate) + dp_aggregate_vdev_stats(vdev, buf); + else + qdf_mem_copy(vdev_stats, &vdev->stats, sizeof(vdev->stats)); + + return 0; +} + /* * dp_txrx_stats_publish(): publish pdev stats into a buffer * @pdev_handle: DP_PDEV handle @@ -7562,6 +7644,9 @@ static struct cdp_host_stats_ops dp_ops_host_stats = { .txrx_enable_enhanced_stats = dp_enable_enhanced_stats, .txrx_disable_enhanced_stats = dp_disable_enhanced_stats, .txrx_stats_publish = dp_txrx_stats_publish, + .txrx_get_vdev_stats = dp_txrx_get_vdev_stats, + .txrx_get_peer_stats = dp_txrx_get_peer_stats, + .txrx_reset_peer_stats = dp_txrx_reset_peer_stats, /* TODO */ };