From 0a5f55fb4acc11a52f34b94595673d4376752849 Mon Sep 17 00:00:00 2001 From: Subrat Mishra Date: Mon, 15 Nov 2021 11:48:45 +0530 Subject: [PATCH] qcacmn: Add more stats to cdp_soc_stats structure Add more stats to cdp_soc_stats interface structure to ship it to userspace. Move soc, delay and jitter stats apis from dp_main.c to dp_stats.c. Change-Id: Idb7f8b706e8744350d7fb2e8802d9303b3f25b5c CRs-Fixed: 3084586 --- dp/inc/cdp_txrx_stats_struct.h | 275 ++++++++++++++++++++++++++++++++- dp/wifi3.0/dp_internal.h | 55 +++++-- dp/wifi3.0/dp_main.c | 139 ----------------- dp/wifi3.0/dp_stats.c | 269 +++++++++++++++++++++++++++++++- 4 files changed, 574 insertions(+), 164 deletions(-) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 4903309c3e..ced11a33ae 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021,2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -58,6 +58,16 @@ #define MAX_BW 8 #define MAX_RECEPTION_TYPES 4 +#define CDP_MAX_RX_DEST_RINGS 8 +#define CDP_MAX_TX_DATA_RINGS 5 +#define CDP_MAX_WIFI_INT_ERROR_REASONS 5 +/** + * This header file is being accessed in userspace applications. + * NR_CPUS is a linux kernel macro and cannot be accessible by user space apps. + * Defining maximum possible cpu count locally. + */ +#define CDP_NR_CPUS 8 + #define MAX_TRANSMIT_TYPES 9 #define MAX_USER_POS 8 @@ -192,6 +202,103 @@ #define PKT_BW_GAIN_320MHZ 12 #endif +/** + * This enum is a direct replica of hal_rxdma_error_code enum. + * New element addition to the enum need to make a entry in this enum too. + * enum cdp_wifi_error_code - Code describing the type of WIFI error detected + * + * @CDP_WIFI_ERR_OVERFLOW: MPDU frame is not complete due to overflow + * @CDP_WIFI_ERR_MPDU_LENGTH: MPDU frame is not complete due to receiving + * incomplete MPDU from the PHY + * @CDP_WIFI_ERR_FCS: FCS check on the MPDU frame failed + * @CDP_WIFI_ERR_DECRYPT: Decryption error + * @CDP_WIFI_ERR_TKIP_MIC: TKIP MIC error + * @CDP_WIFI_ERR_UNENCRYPTED: Received a frame that was expected to be + * encrypted but wasn’t + * @CDP_WIFI_ERR_MSDU_LEN: MSDU related length error + * @CDP_WIFI_ERR_MSDU_LIMIT: Number of MSDUs in the MPDUs exceeded the max + * allowed + * @CDP_WIFI_ERR_WIFI_PARSE: Wifi parsing error + * @CDP_WIFI_ERR_AMSDU_PARSE: Amsdu parsing error + * @CDP_WIFI_ERR_SA_TIMEOUT: Source Address search timeout + * @CDP_WIFI_ERR_DA_TIMEOUT: Destination Address search timeout + * @CDP_WIFI_ERR_FLOW_TIMEOUT: Flow Search Timeout + * @CDP_WIFI_ERR_FLUSH_REQUEST: Flush request error + * @CDP_WIFI_ERR_AMSDU_FRAGMENT: Reported A-MSDU present along with a fragmented + * MPDU + * @CDP_WIFI_ERR_MULTICAST_ECHO: Reported a multicast echo error + * @CDP_WIFI_ERR_DUMMY: Dummy errors + */ +enum cdp_wifi_error_code { + CDP_WIFI_ERR_OVERFLOW = 0, + CDP_WIFI_ERR_MPDU_LENGTH, + CDP_WIFI_ERR_FCS, + CDP_WIFI_ERR_DECRYPT, + CDP_WIFI_ERR_TKIP_MIC, + CDP_WIFI_ERR_UNENCRYPTED, + CDP_WIFI_ERR_MSDU_LEN, + CDP_WIFI_ERR_MSDU_LIMIT, + CDP_WIFI_ERR_WIFI_PARSE, + CDP_WIFI_ERR_AMSDU_PARSE, + CDP_WIFI_ERR_SA_TIMEOUT, + CDP_WIFI_ERR_DA_TIMEOUT, + CDP_WIFI_ERR_FLOW_TIMEOUT, + CDP_WIFI_ERR_FLUSH_REQUEST, + CDP_WIFI_ERR_AMSDU_FRAGMENT, + CDP_WIFI_ERR_MULTICAST_ECHO, + CDP_WIFI_ERR_DUMMY = 31, + CDP_WIFI_ERR_MAX +}; + +/** + * This enum is a direct replica of hal_reo_error_code enum. + * New element addition to the enum need to make a entry in this enum too. + * enum cdp_phy_rx_error_code - Error code describing the type of error detected + * + * @CDP_RX_ERR_QUEUE_ADDR_0: Rx queue descriptor is set to 0 + * @CDP_RX_ERR_QUEUE_INVALID: Rx queue descriptor valid bit is NOT set + * @CDP_RX_ERR_AMPDU_IN_NON_BA: AMPDU frame received without BA session having + * been setup + * @CDP_RX_ERR_NON_BA_DUPLICATE: Non-BA session, SN equal to SSN retry bit set + * duplicate frame + * @CDP_RX_ERR_BA_DUPLICATE: BA session, duplicate frame + * @CDP_RX_ERR_REGULAR_FRAME_2K_JUMP: A normal management/data frame received + * with 2K jump in SN + * @CDP_RX_ERR_BAR_FRAME_2K_JUMP: A bar received with 2K jump in SSN + * @CDP_RX_ERR_REGULAR_FRAME_OOR: A normal management/data frame received with + * SN falling within the OOR window + * @CDP_RX_ERR_BAR_FRAME_OOR: A bar received with SSN falling within the OOR + * window + * @CDP_RX_ERR_BAR_FRAME_NO_BA_SESSION: A bar received without a BA session + * @CDP_RX_ERR_BAR_FRAME_SN_EQUALS_SSN: A bar received with SSN equal to SN + * @CDP_RX_ERR_PN_CHECK_FAILED: PN Check Failed packet + * @CDP_RX_ERR_2K_ERROR_HANDLING_FLAG_SET: Frame is forwarded as a result of + * the Seq_2k_error_detected_flag been set in the REO Queue descriptor + * @CDP_RX_ERR_PN_ERROR_HANDLING_FLAG_SET: Frame is forwarded as a result of + * the pn_error_detected_flag been set in the REO Queue descriptor + * @CDP_RX_ERR_QUEUE_BLOCKED_SET: Frame is forwarded as a result of the queue + * descriptor(address) being blocked as SW/FW seems to be currently in the + * process of making updates to this descriptor + */ +enum cdp_phy_rx_error_code { + CDP_RX_ERR_QUEUE_ADDR_0 = 0, + CDP_RX_ERR_QUEUE_INVALID, + CDP_RX_ERR_AMPDU_IN_NON_BA, + CDP_RX_ERR_NON_BA_DUPLICATE, + CDP_RX_ERR_BA_DUPLICATE, + CDP_RX_ERR_REGULAR_FRAME_2K_JUMP, + CDP_RX_ERR_BAR_FRAME_2K_JUMP, + CDP_RX_ERR_REGULAR_FRAME_OOR, + CDP_RX_ERR_BAR_FRAME_OOR, + CDP_RX_ERR_BAR_FRAME_NO_BA_SESSION, + CDP_RX_ERR_BAR_FRAME_SN_EQUALS_SSN, + CDP_RX_ERR_PN_CHECK_FAILED, + CDP_RX_ERR_2K_ERROR_HANDLING_FLAG_SET, + CDP_RX_ERR_PN_ERROR_HANDLING_FLAG_SET, + CDP_RX_ERR_QUEUE_BLOCKED_SET, + CDP_RX_ERR_MAX +}; + /* * cdp_tx_transmit_type: Transmit type index * SU: SU Transmit type index @@ -2236,33 +2343,193 @@ struct cdp_cfr_rcc_stats { }; #endif +/* struct cdp_per_cpu_packets - Per cpu packets + * @num_cpus: Number of cpus + * @pkts: packet count per core + */ +struct cdp_per_cpu_packets { + uint8_t num_cpus; + uint64_t pkts[CDP_NR_CPUS][CDP_MAX_RX_DEST_RINGS]; +}; + /* struct cdp_soc_stats - soc stats * @tx.egress: Total packets transmitted + * @tx.tx_invalid_peer: packets dropped on tx because of no peer + * @tx.tx_hw_enq: Enqueues per tx hw ring + * @tx.tx_hw_ring_full: descriptors in each tx hw ring + * @tx.desc_in_use: Descriptors in use at soc + * @tx.dropped_fw_removed: HW_release_reason == FW removed + * @tx.invalid_release_source: tx completion release_src != HW or FW + * @tx.wifi_internal_error: tx completion wifi_internal_error + * @tx.non_wifi_internal_err: tx completion non_wifi_internal_error + * @tx.tx_comp_loop_pkt_limit_hit: TX Comp loop packet limit hit + * @tx.hp_oos2: Head pointer Out of sync at the end of dp_tx_comp_handler + * @tx.tx_comp_exception: tx desc freed as part of vdev detach * @rx.ingress: Total rx packets count * @rx.err_ring_pkts: Total Packets in Rx Error ring * @rx.rx_frags: No of Fragments - * @rx.reo_reinject: No of reinjected packets + * @rx.rx_hw_reinject: No of reinjected packets * @rx.bar_frame: Number of bar frames received - * @rx.err.rejected: RX msdu rejected count on delivery to vdev stack_fn + * @rx.rx_frag_err_len_error: Fragments dropped due to len errors in skb + * @rx.rx_frag_err_no_peer: Fragments dropped due to no peer found + * @rx.rx_frag_wait: No of incomplete fragments in waitlist + * @rx.rx_frag_err: Fragments dropped due to errors + * @rx.rx_frag_oor: Fragments received OOR causing sequence num mismatch + * @rx.reap_loop_pkt_limit_hit: Reap loop packet limit hit + * @rx.hp_oos2: Head pointer Out of sync at the end of dp_rx_process + * @rx.near_full: Rx ring near full + * @rx.msdu_scatter_wait_break: Break ring reaping as not all scattered msdu + * received + * @rx.rx_sw_route_drop: Number of frames routed from rx sw ring + * @rx.rx_hw_route_drop: Number of frames routed from rx hw ring + * @rx.rx_packets: packet count per core + * @rx.err.rx_rejected: RX msdu rejected count on delivery to vdev stack_fn * @rx.err.raw_frm_drop: RX raw frame dropped count + * @rx.err.phy_ring_access_fail: phy ring access Fail error count + * @rx.err.phy_ring_access_full_fail: phy ring access full Fail error count + * @rx.err.phy_rx_error: phy rx order ERR Count + * @rx.err.phy_rx_dest_dup: phy rx order DEST Duplicate count + * @rx.err.phy_wifi_rel_dup: phy wifi RELEASE Duplicate count + * @rx.err.phy_rx_sw_err_dup: phy rx sw error Duplicate count + * @rx.err.invalid_rbm: Invalid RBM error count + * @rx.err.invalid_vdev: Invalid VDEV Error count + * @rx.err.invalid_pdev: Invalid PDEV error count + * @rx.err.pkt_delivered_no_peer: Pkts delivered to stack that no related peer + * @rx.err.defrag_peer_uninit: Defrag peer uninit error count + * @rx.err.invalid_sa_da_idx: Invalid sa_idx or da_idx + * @rx.err.msdu_done_fail: MSDU DONE failures + * @ex.err.rx_invalid_peer: Invalid PEER Error count + * @rx.err.rx_invalid_peer_id: Invalid PEER ID count + * @rx.err.rx_invalid_pkt_len: Invalid packet length count + * @rx.err.rx_sw_error: RX sw error count + * @rx.err.rx_desc_invalid_magic: RX DEST Desc Invalid Magic count + * @rx.err.rx_hw_error: rx hw Error count + * @rx.err.rx_hw_cmd_send_fail: Rx hw cmd send fail/requeue count + * @rx.err.rx_hw_cmd_send_drain: Rx hw cmd send drain count + * @rx.err.scatter_msdu: RX msdu drop count due to scatter + * @rx.err.invalid_cookie: RX msdu drop count due to invalid cookie + * @rx.err.stale_cookie: Count of stale cookie read in RX path + * @rx.err.rx_2k_jump_delba_sent: Delba sent count due to RX 2k jump + * @rx.err.rx_2k_jump_to_stack: RX 2k jump msdu indicated to stack count + * @rx.err.rx_2k_jump_drop: RX 2k jump msdu dropped count + * @rx.err.rx_hw_err_oor_drop: Rx HW OOR msdu drop count + * @rx.err.rx_hw_err_oor_to_stack: Rx HW OOR msdu indicated to stack count + * @rx.err.rx_hw_err_oor_sg_count: Rx HW OOR scattered msdu count + * @rx.err.msdu_count_mismatch: Incorrect msdu count in MPDU desc info + * @rx.err.invalid_link_cookie: Stale link desc cookie count + * @rx.err.nbuf_sanity_fail: Nbuf sanity failure + * @rx.err.dup_refill_link_desc: Duplicate link desc refilled + * @rx.err.msdu_continuation_err: Incorrect msdu continuation bit in MSDU desc + * @rx.err.ssn_update_count: Count of start sequence (ssn) updates + * @rx.err.bar_handle_fail_count: Count of bar handling fail + * @rx.err.intrabss_eapol_drop: EAPOL drop count in intrabss scenario + * @rx.err.pn_in_dest_check_fail: PN check failed for 2K-jump or OOR error + * @rx.err.msdu_len_err: MSDU len err count + * @rx.err.rx_flush_count: Rx flush count + * @ast.added: ast entry added count + * @ast.deleted: ast entry deleted count + * @ast.aged_out: ast entry aged out count + * @ast.map_err: ast entry mapping error count + * @ast.ast_mismatch: ast entry mismatch count + * @mec.added: Mec added count + * @mec.deleted: Mec deleted count */ struct cdp_soc_stats { struct { struct cdp_pkt_info egress; + struct cdp_pkt_info tx_invalid_peer; + uint32_t tx_hw_enq[CDP_MAX_TX_DATA_RINGS]; + uint32_t tx_hw_ring_full[CDP_MAX_TX_DATA_RINGS]; + uint32_t desc_in_use; + uint32_t dropped_fw_removed; + uint32_t invalid_release_source; + uint32_t wifi_internal_error[CDP_MAX_WIFI_INT_ERROR_REASONS]; + uint32_t non_wifi_internal_err; + uint32_t tx_comp_loop_pkt_limit_hit; + uint32_t hp_oos2; + uint32_t tx_comp_exception; } tx; struct { struct cdp_pkt_info ingress; uint32_t err_ring_pkts; uint32_t rx_frags; - uint32_t reo_reinject; + uint32_t rx_hw_reinject; uint32_t bar_frame; + uint32_t rx_frag_err_len_error; + uint32_t rx_frag_err_no_peer; + uint32_t rx_frag_wait; + uint32_t rx_frag_err; + uint32_t rx_frag_oor; + uint32_t reap_loop_pkt_limit_hit; + uint32_t hp_oos2; + uint32_t near_full; + uint32_t msdu_scatter_wait_break; + uint32_t rx_sw_route_drop; + uint32_t rx_hw_route_drop; + struct cdp_per_cpu_packets rx_packets; struct { uint32_t rx_rejected; uint32_t rx_raw_frm_drop; + uint32_t phy_ring_access_fail; + uint32_t phy_ring_access_full_fail; + uint32_t phy_rx_hw_error[CDP_MAX_RX_DEST_RINGS]; + uint32_t phy_rx_hw_dest_dup; + uint32_t phy_wifi_rel_dup; + uint32_t phy_rx_sw_err_dup; + uint32_t invalid_rbm; + uint32_t invalid_vdev; + uint32_t invalid_pdev; + uint32_t pkt_delivered_no_peer; + uint32_t defrag_peer_uninit; + uint32_t invalid_sa_da_idx; + uint32_t msdu_done_fail; + struct cdp_pkt_info rx_invalid_peer; + struct cdp_pkt_info rx_invalid_peer_id; + struct cdp_pkt_info rx_invalid_pkt_len; + uint32_t rx_sw_error[CDP_WIFI_ERR_MAX]; + uint32_t rx_desc_invalid_magic; + uint32_t rx_hw_error[CDP_RX_ERR_MAX]; + uint32_t rx_hw_cmd_send_fail; + uint32_t rx_hw_cmd_send_drain; + uint32_t scatter_msdu; + uint32_t invalid_cookie; + uint32_t stale_cookie; + uint32_t rx_2k_jump_delba_sent; + uint32_t rx_2k_jump_to_stack; + uint32_t rx_2k_jump_drop; + uint32_t rx_hw_err_msdu_buf_rcved; + uint32_t rx_hw_err_msdu_buf_invalid_cookie; + uint32_t rx_hw_err_oor_drop; + uint32_t rx_hw_err_oor_to_stack; + uint32_t rx_hw_err_oor_sg_count; + uint32_t msdu_count_mismatch; + uint32_t invalid_link_cookie; + uint32_t nbuf_sanity_fail; + uint32_t dup_refill_link_desc; + uint32_t msdu_continuation_err; + uint32_t ssn_update_count; + uint32_t bar_handle_fail_count; + uint32_t intrabss_eapol_drop; + uint32_t pn_in_dest_check_fail; + uint32_t msdu_len_err; + uint32_t rx_flush_count; } err; } rx; + + struct { + uint32_t added; + uint32_t deleted; + uint32_t aged_out; + uint32_t map_err; + uint32_t ast_mismatch; + } ast; + + struct { + uint32_t added; + uint32_t deleted; + } mec; }; /* struct cdp_pdev_stats - pdev stats diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 782d1fbf94..b8b7e48042 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -2911,21 +2911,46 @@ void dp_peer_flush_frags(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, */ void dp_soc_reset_mon_intr_mask(struct dp_soc *soc); -#ifdef QCA_PEER_EXT_STATS -/* - * dp_accumulate_delay_tid_stats(): Accumulate the tid stats to the - * hist stats. - * @soc: DP SoC handle - * @stats: cdp_delay_tid stats - * @dst_hstats: Destination histogram to copy tid stats - * @tid: TID value +/** + * dp_txrx_get_soc_stats() - will return cdp_soc_stats + * @soc_hdl: soc handle + * @soc_stats: buffer to hold the values * - * Return: void + * Return: QDF_STATUS_SUCCESS: Success + * QDF_STATUS_E_FAILURE: Error */ -void dp_accumulate_delay_tid_stats(struct dp_soc *soc, - struct cdp_delay_tid_stats stats[] - [CDP_MAX_TXRX_CTX], - struct cdp_hist_stats *dst_hstats, - uint8_t tid, uint32_t mode); -#endif /* QCA_PEER_EXT_STATS */ +QDF_STATUS dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl, + struct cdp_soc_stats *soc_stats); + +/** + * dp_txrx_get_peer_delay_stats() - to get peer delay stats per TIDs + * @soc: soc handle + * @vdev_id: id of vdev handle + * @peer_mac: mac of DP_PEER handle + * @delay_stats: pointer to delay stats array + * + * Return: QDF_STATUS_SUCCESS: Success + * QDF_STATUS_E_FAILURE: Error + */ +QDF_STATUS +dp_txrx_get_peer_delay_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_delay_tid_stats *delay_stats); + +/** + * dp_txrx_get_peer_jitter_stats() - to get peer jitter stats per TIDs + * @soc: soc handle + * @pdev_id: id of pdev handle + * @vdev_id: id of vdev handle + * @peer_mac: mac of DP_PEER handle + * @tid_stats: pointer to jitter stats array + * + * Return: QDF_STATUS_SUCCESS: Success + * QDF_STATUS_E_FAILURE: Error + */ +QDF_STATUS +dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t vdev_id, uint8_t *peer_mac, + struct cdp_peer_tid_stats *tid_stats); + #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index cda85b9f09..b542274eab 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -9951,145 +9951,6 @@ static QDF_STATUS dp_txrx_update_vdev_host_stats(struct cdp_soc_t *soc_hdl, return QDF_STATUS_SUCCESS; } -/* dp_txrx_get_soc_stats - will return cdp_soc_stats - * @soc_hdl: soc handle - * @soc_stats: buffer to hold the values - * - * return: status success/failure - */ -static QDF_STATUS -dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl, - struct cdp_soc_stats *soc_stats) -{ - struct dp_soc *soc = (struct dp_soc *)soc_hdl; - - soc_stats->tx.egress = soc->stats.tx.egress; - soc_stats->rx.ingress = soc->stats.rx.ingress; - soc_stats->rx.err_ring_pkts = soc->stats.rx.err_ring_pkts; - soc_stats->rx.rx_frags = soc->stats.rx.rx_frags; - soc_stats->rx.reo_reinject = soc->stats.rx.reo_reinject; - soc_stats->rx.bar_frame = soc->stats.rx.bar_frame; - soc_stats->rx.err.rx_rejected = soc->stats.rx.err.rejected; - soc_stats->rx.err.rx_raw_frm_drop = soc->stats.rx.err.raw_frm_drop; - - return QDF_STATUS_SUCCESS; -} - -#ifdef QCA_PEER_EXT_STATS -/* dp_txrx_get_peer_delay_stats - to get peer delay stats per TIDs - * @soc: soc handle - * @vdev_id: id of vdev handle - * @peer_mac: mac of DP_PEER handle - * @delay_stats: pointer to delay stats array - * return: status success/failure - */ -static QDF_STATUS -dp_txrx_get_peer_delay_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, - uint8_t *peer_mac, - struct cdp_delay_tid_stats *delay_stats) -{ - struct dp_soc *soc = (struct dp_soc *)soc_hdl; - struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, - DP_MOD_ID_CDP); - struct cdp_peer_ext_stats *pext_stats; - struct cdp_delay_rx_stats *rx_delay; - struct cdp_delay_tx_stats *tx_delay; - uint8_t tid; - - if (!peer) - return QDF_STATUS_E_FAILURE; - - if (!wlan_cfg_is_peer_ext_stats_enabled(soc->wlan_cfg_ctx)) { - dp_peer_unref_delete(peer, DP_MOD_ID_CDP); - return QDF_STATUS_E_FAILURE; - } - - pext_stats = peer->pext_stats; - if (!pext_stats) { - dp_peer_unref_delete(peer, DP_MOD_ID_CDP); - return QDF_STATUS_E_FAILURE; - } - - for (tid = 0; tid < CDP_MAX_DATA_TIDS; tid++) { - rx_delay = &delay_stats[tid].rx_delay; - dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, - &rx_delay->to_stack_delay, tid, - CDP_HIST_TYPE_REAP_STACK); - tx_delay = &delay_stats[tid].tx_delay; - dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, - &tx_delay->tx_swq_delay, tid, - CDP_HIST_TYPE_SW_ENQEUE_DELAY); - dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, - &tx_delay->hwtx_delay, tid, - CDP_HIST_TYPE_HW_COMP_DELAY); - } - dp_peer_unref_delete(peer, DP_MOD_ID_CDP); - - return QDF_STATUS_SUCCESS; -} -#else -static QDF_STATUS -dp_txrx_get_peer_delay_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, - uint8_t *peer_mac, - struct cdp_delay_tid_stats *delay_stats) -{ - return QDF_STATUS_E_FAILURE; -} -#endif /* QCA_PEER_EXT_STATS */ - -#ifdef WLAN_PEER_JITTER -/* dp_txrx_get_peer_jitter_stats - to get peer jitter stats per TIDs - * @soc: soc handle - * @pdev_id: id of pdev handle - * @vdev_id: id of vdev handle - * @peer_mac: mac of DP_PEER handle - * @tid_stats: pointer to jitter stats array - * return: status success/failure - */ -static QDF_STATUS -dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, - uint8_t vdev_id, uint8_t *peer_mac, - struct cdp_peer_tid_stats *tid_stats) -{ - struct dp_soc *soc = (struct dp_soc *)soc_hdl; - struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); - struct dp_peer *peer; - uint8_t tid; - - if (!pdev) - return QDF_STATUS_E_FAILURE; - - if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) - return QDF_STATUS_E_FAILURE; - - peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, DP_MOD_ID_CDP); - if (!peer) - return QDF_STATUS_E_FAILURE; - - for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) { - struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; - - tid_stats[tid].tx_avg_jitter = rx_tid->stats.tx_avg_jitter; - tid_stats[tid].tx_avg_delay = rx_tid->stats.tx_avg_delay; - tid_stats[tid].tx_avg_err = rx_tid->stats.tx_avg_err; - tid_stats[tid].tx_total_success = - rx_tid->stats.tx_total_success; - tid_stats[tid].tx_drop = rx_tid->stats.tx_drop; - } - dp_peer_unref_delete(peer, DP_MOD_ID_CDP); - - return QDF_STATUS_SUCCESS; -} -#else -static QDF_STATUS -dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, - uint8_t vdev_id, uint8_t *peer_mac, - struct cdp_peer_tid_stats *tid_stats) -{ - return QDF_STATUS_E_FAILURE; -} -#endif /* WLAN_PEER_JITTER */ - /* dp_txrx_get_peer_stats - will return cdp_peer_stats * @soc: soc handle * @vdev_id: id of vdev handle diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index c524c00cfd..85887992be 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -5692,11 +5692,21 @@ static void dp_print_hist_stats(struct cdp_hist_stats *hstats, DP_PRINT_STATS("Avg = %u\n", hstats->avg); } -void dp_accumulate_delay_tid_stats(struct dp_soc *soc, - struct cdp_delay_tid_stats stats[] - [CDP_MAX_TXRX_CTX], - struct cdp_hist_stats *dst_hstats, - uint8_t tid, uint32_t mode) +/* + * dp_accumulate_delay_tid_stats(): Accumulate the tid stats to the + * hist stats. + * @soc: DP SoC handle + * @stats: cdp_delay_tid stats + * @dst_hstats: Destination histogram to copy tid stats + * @tid: TID value + * + * Return: void + */ +static void dp_accumulate_delay_tid_stats(struct dp_soc *soc, + struct cdp_delay_tid_stats stats[] + [CDP_MAX_TXRX_CTX], + struct cdp_hist_stats *dst_hstats, + uint8_t tid, uint32_t mode) { uint8_t ring_id; @@ -7559,3 +7569,250 @@ void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj, tgtobj->stats.tx_i.dropped.res_full + tgtobj->stats.tx_i.dropped.headroom_insufficient; } + +QDF_STATUS dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl, + struct cdp_soc_stats *soc_stats) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + uint8_t inx; + uint8_t cpus; + + /* soc tx stats */ + soc_stats->tx.egress = soc->stats.tx.egress; + soc_stats->tx.tx_invalid_peer = soc->stats.tx.tx_invalid_peer; + for (inx = 0; inx < CDP_MAX_TX_DATA_RINGS; inx++) { + soc_stats->tx.tx_hw_enq[inx] = soc->stats.tx.tcl_enq[inx]; + soc_stats->tx.tx_hw_ring_full[inx] = + soc->stats.tx.tcl_ring_full[inx]; + } + soc_stats->tx.desc_in_use = soc->stats.tx.desc_in_use; + soc_stats->tx.dropped_fw_removed = soc->stats.tx.dropped_fw_removed; + soc_stats->tx.invalid_release_source = + soc->stats.tx.invalid_release_source; + for (inx = 0; inx < CDP_MAX_WIFI_INT_ERROR_REASONS; inx++) + soc_stats->tx.wifi_internal_error[inx] = + soc->stats.tx.wbm_internal_error[inx]; + soc_stats->tx.non_wifi_internal_err = + soc->stats.tx.non_wbm_internal_err; + soc_stats->tx.tx_comp_loop_pkt_limit_hit = + soc->stats.tx.tx_comp_loop_pkt_limit_hit; + soc_stats->tx.hp_oos2 = soc->stats.tx.hp_oos2; + soc_stats->tx.tx_comp_exception = soc->stats.tx.tx_comp_exception; + /* soc rx stats */ + soc_stats->rx.ingress = soc->stats.rx.ingress; + soc_stats->rx.err_ring_pkts = soc->stats.rx.err_ring_pkts; + soc_stats->rx.rx_frags = soc->stats.rx.rx_frags; + soc_stats->rx.rx_hw_reinject = soc->stats.rx.reo_reinject; + soc_stats->rx.bar_frame = soc->stats.rx.bar_frame; + soc_stats->rx.rx_frag_err_len_error = + soc->stats.rx.rx_frag_err_len_error; + soc_stats->rx.rx_frag_err_no_peer = soc->stats.rx.rx_frag_err_no_peer; + soc_stats->rx.rx_frag_wait = soc->stats.rx.rx_frag_wait; + soc_stats->rx.rx_frag_err = soc->stats.rx.rx_frag_err; + soc_stats->rx.rx_frag_oor = soc->stats.rx.rx_frag_oor; + soc_stats->rx.reap_loop_pkt_limit_hit = + soc->stats.rx.reap_loop_pkt_limit_hit; + soc_stats->rx.hp_oos2 = soc->stats.rx.hp_oos2; + soc_stats->rx.near_full = soc->stats.rx.near_full; + soc_stats->rx.msdu_scatter_wait_break = + soc->stats.rx.msdu_scatter_wait_break; + soc_stats->rx.rx_sw_route_drop = soc->stats.rx.rxdma2rel_route_drop; + soc_stats->rx.rx_hw_route_drop = soc->stats.rx.reo2rel_route_drop; + soc_stats->rx.rx_packets.num_cpus = qdf_min((uint32_t)CDP_NR_CPUS, + num_possible_cpus()); + for (cpus = 0; cpus < soc_stats->rx.rx_packets.num_cpus; cpus++) { + for (inx = 0; inx < CDP_MAX_RX_DEST_RINGS; inx++) + soc_stats->rx.rx_packets.pkts[cpus][inx] = + soc->stats.rx.ring_packets[cpus][inx]; + } + soc_stats->rx.err.rx_rejected = soc->stats.rx.err.rejected; + soc_stats->rx.err.rx_raw_frm_drop = soc->stats.rx.err.raw_frm_drop; + soc_stats->rx.err.phy_ring_access_fail = + soc->stats.rx.err.hal_ring_access_fail; + soc_stats->rx.err.phy_ring_access_full_fail = + soc->stats.rx.err.hal_ring_access_full_fail; + for (inx = 0; inx < CDP_MAX_RX_DEST_RINGS; inx++) + soc_stats->rx.err.phy_rx_hw_error[inx] = + soc->stats.rx.err.hal_reo_error[inx]; + soc_stats->rx.err.phy_rx_hw_dest_dup = + soc->stats.rx.err.hal_reo_dest_dup; + soc_stats->rx.err.phy_wifi_rel_dup = soc->stats.rx.err.hal_wbm_rel_dup; + soc_stats->rx.err.phy_rx_sw_err_dup = + soc->stats.rx.err.hal_rxdma_err_dup; + soc_stats->rx.err.invalid_rbm = soc->stats.rx.err.invalid_rbm; + soc_stats->rx.err.invalid_vdev = soc->stats.rx.err.invalid_vdev; + soc_stats->rx.err.invalid_pdev = soc->stats.rx.err.invalid_pdev; + soc_stats->rx.err.pkt_delivered_no_peer = + soc->stats.rx.err.pkt_delivered_no_peer; + soc_stats->rx.err.defrag_peer_uninit = + soc->stats.rx.err.defrag_peer_uninit; + soc_stats->rx.err.invalid_sa_da_idx = + soc->stats.rx.err.invalid_sa_da_idx; + soc_stats->rx.err.msdu_done_fail = soc->stats.rx.err.msdu_done_fail; + soc_stats->rx.err.rx_invalid_peer = soc->stats.rx.err.rx_invalid_peer; + soc_stats->rx.err.rx_invalid_peer_id = + soc->stats.rx.err.rx_invalid_peer_id; + soc_stats->rx.err.rx_invalid_pkt_len = + soc->stats.rx.err.rx_invalid_pkt_len; + for (inx = 0; inx < qdf_min((uint32_t)CDP_WIFI_ERR_MAX, + (uint32_t)HAL_RXDMA_ERR_MAX); inx++) + soc_stats->rx.err.rx_sw_error[inx] = + soc->stats.rx.err.rxdma_error[inx]; + for (inx = 0; inx < qdf_min((uint32_t)CDP_RX_ERR_MAX, + (uint32_t)HAL_REO_ERR_MAX); inx++) + soc_stats->rx.err.rx_hw_error[inx] = + soc->stats.rx.err.reo_error[inx]; + soc_stats->rx.err.rx_desc_invalid_magic = + soc->stats.rx.err.rx_desc_invalid_magic; + soc_stats->rx.err.rx_hw_cmd_send_fail = + soc->stats.rx.err.reo_cmd_send_fail; + soc_stats->rx.err.rx_hw_cmd_send_drain = + soc->stats.rx.err.reo_cmd_send_drain; + soc_stats->rx.err.scatter_msdu = soc->stats.rx.err.scatter_msdu; + soc_stats->rx.err.invalid_cookie = soc->stats.rx.err.invalid_cookie; + soc_stats->rx.err.stale_cookie = soc->stats.rx.err.stale_cookie; + soc_stats->rx.err.rx_2k_jump_delba_sent = + soc->stats.rx.err.rx_2k_jump_delba_sent; + soc_stats->rx.err.rx_2k_jump_to_stack = + soc->stats.rx.err.rx_2k_jump_to_stack; + soc_stats->rx.err.rx_2k_jump_drop = soc->stats.rx.err.rx_2k_jump_drop; + soc_stats->rx.err.rx_hw_err_msdu_buf_rcved = + soc->stats.rx.err.reo_err_msdu_buf_rcved; + soc_stats->rx.err.rx_hw_err_msdu_buf_invalid_cookie = + soc->stats.rx.err.reo_err_msdu_buf_invalid_cookie; + soc_stats->rx.err.rx_hw_err_oor_drop = + soc->stats.rx.err.reo_err_oor_drop; + soc_stats->rx.err.rx_hw_err_oor_to_stack = + soc->stats.rx.err.reo_err_oor_to_stack; + soc_stats->rx.err.rx_hw_err_oor_sg_count = + soc->stats.rx.err.reo_err_oor_sg_count; + soc_stats->rx.err.msdu_count_mismatch = + soc->stats.rx.err.msdu_count_mismatch; + soc_stats->rx.err.invalid_link_cookie = + soc->stats.rx.err.invalid_link_cookie; + soc_stats->rx.err.nbuf_sanity_fail = soc->stats.rx.err.nbuf_sanity_fail; + soc_stats->rx.err.dup_refill_link_desc = + soc->stats.rx.err.dup_refill_link_desc; + soc_stats->rx.err.msdu_continuation_err = + soc->stats.rx.err.msdu_continuation_err; + soc_stats->rx.err.ssn_update_count = soc->stats.rx.err.ssn_update_count; + soc_stats->rx.err.bar_handle_fail_count = + soc->stats.rx.err.bar_handle_fail_count; + soc_stats->rx.err.intrabss_eapol_drop = + soc->stats.rx.err.intrabss_eapol_drop; + soc_stats->rx.err.pn_in_dest_check_fail = + soc->stats.rx.err.pn_in_dest_check_fail; + soc_stats->rx.err.msdu_len_err = soc->stats.rx.err.msdu_len_err; + soc_stats->rx.err.rx_flush_count = soc->stats.rx.err.rx_flush_count; + /* soc ast stats */ + soc_stats->ast.added = soc->stats.ast.added; + soc_stats->ast.deleted = soc->stats.ast.deleted; + soc_stats->ast.aged_out = soc->stats.ast.aged_out; + soc_stats->ast.map_err = soc->stats.ast.map_err; + soc_stats->ast.ast_mismatch = soc->stats.ast.ast_mismatch; + /* soc mec stats */ + soc_stats->mec.added = soc->stats.mec.added; + soc_stats->mec.deleted = soc->stats.mec.deleted; + + return QDF_STATUS_SUCCESS; +} + +#ifdef QCA_PEER_EXT_STATS +QDF_STATUS +dp_txrx_get_peer_delay_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_delay_tid_stats *delay_stats) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, + DP_MOD_ID_CDP); + struct cdp_peer_ext_stats *pext_stats; + struct cdp_delay_rx_stats *rx_delay; + struct cdp_delay_tx_stats *tx_delay; + uint8_t tid; + + if (!peer) + return QDF_STATUS_E_FAILURE; + + if (!wlan_cfg_is_peer_ext_stats_enabled(soc->wlan_cfg_ctx)) { + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + return QDF_STATUS_E_FAILURE; + } + + pext_stats = peer->pext_stats; + if (!pext_stats) { + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + return QDF_STATUS_E_FAILURE; + } + + for (tid = 0; tid < CDP_MAX_DATA_TIDS; tid++) { + rx_delay = &delay_stats[tid].rx_delay; + dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, + &rx_delay->to_stack_delay, tid, + CDP_HIST_TYPE_REAP_STACK); + tx_delay = &delay_stats[tid].tx_delay; + dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, + &tx_delay->tx_swq_delay, tid, + CDP_HIST_TYPE_SW_ENQEUE_DELAY); + dp_accumulate_delay_tid_stats(soc, pext_stats->delay_stats, + &tx_delay->hwtx_delay, tid, + CDP_HIST_TYPE_HW_COMP_DELAY); + } + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + + return QDF_STATUS_SUCCESS; +} +#else +QDF_STATUS +dp_txrx_get_peer_delay_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_delay_tid_stats *delay_stats) +{ + return QDF_STATUS_E_FAILURE; +} +#endif /* QCA_PEER_EXT_STATS */ + +#ifdef WLAN_PEER_JITTER +QDF_STATUS +dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t vdev_id, uint8_t *peer_mac, + struct cdp_peer_tid_stats *tid_stats) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct dp_peer *peer; + uint8_t tid; + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) + return QDF_STATUS_E_FAILURE; + + peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, DP_MOD_ID_CDP); + if (!peer) + return QDF_STATUS_E_FAILURE; + + for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) { + struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + + tid_stats[tid].tx_avg_jitter = rx_tid->stats.tx_avg_jitter; + tid_stats[tid].tx_avg_delay = rx_tid->stats.tx_avg_delay; + tid_stats[tid].tx_avg_err = rx_tid->stats.tx_avg_err; + tid_stats[tid].tx_total_success = + rx_tid->stats.tx_total_success; + tid_stats[tid].tx_drop = rx_tid->stats.tx_drop; + } + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + + return QDF_STATUS_SUCCESS; +} +#else +QDF_STATUS +dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t vdev_id, uint8_t *peer_mac, + struct cdp_peer_tid_stats *tid_stats) +{ + return QDF_STATUS_E_FAILURE; +} +#endif /* WLAN_PEER_JITTER */