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
This commit is contained in:
Subrat Mishra
2021-11-15 11:48:45 +05:30
committed by Madan Koyyalamudi
parent 362e95bae6
commit 0a5f55fb4a
4 changed files with 574 additions and 164 deletions

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -58,6 +58,16 @@
#define MAX_BW 8 #define MAX_BW 8
#define MAX_RECEPTION_TYPES 4 #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_TRANSMIT_TYPES 9
#define MAX_USER_POS 8 #define MAX_USER_POS 8
@@ -192,6 +202,103 @@
#define PKT_BW_GAIN_320MHZ 12 #define PKT_BW_GAIN_320MHZ 12
#endif #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 wasnt
* @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 * cdp_tx_transmit_type: Transmit type index
* SU: SU Transmit type index * SU: SU Transmit type index
@@ -2236,33 +2343,193 @@ struct cdp_cfr_rcc_stats {
}; };
#endif #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 /* struct cdp_soc_stats - soc stats
* @tx.egress: Total packets transmitted * @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.ingress: Total rx packets count
* @rx.err_ring_pkts: Total Packets in Rx Error ring * @rx.err_ring_pkts: Total Packets in Rx Error ring
* @rx.rx_frags: No of Fragments * @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.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.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 cdp_soc_stats {
struct { struct {
struct cdp_pkt_info egress; 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; } tx;
struct { struct {
struct cdp_pkt_info ingress; struct cdp_pkt_info ingress;
uint32_t err_ring_pkts; uint32_t err_ring_pkts;
uint32_t rx_frags; uint32_t rx_frags;
uint32_t reo_reinject; uint32_t rx_hw_reinject;
uint32_t bar_frame; 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 { struct {
uint32_t rx_rejected; uint32_t rx_rejected;
uint32_t rx_raw_frm_drop; 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; } err;
} rx; } 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 /* struct cdp_pdev_stats - pdev stats

View File

@@ -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); void dp_soc_reset_mon_intr_mask(struct dp_soc *soc);
#ifdef QCA_PEER_EXT_STATS /**
/* * dp_txrx_get_soc_stats() - will return cdp_soc_stats
* dp_accumulate_delay_tid_stats(): Accumulate the tid stats to the * @soc_hdl: soc handle
* hist stats. * @soc_stats: buffer to hold the values
* @soc: DP SoC handle
* @stats: cdp_delay_tid stats
* @dst_hstats: Destination histogram to copy tid stats
* @tid: TID value
* *
* Return: void * Return: QDF_STATUS_SUCCESS: Success
* QDF_STATUS_E_FAILURE: Error
*/ */
void dp_accumulate_delay_tid_stats(struct dp_soc *soc, QDF_STATUS dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl,
struct cdp_delay_tid_stats stats[] struct cdp_soc_stats *soc_stats);
[CDP_MAX_TXRX_CTX],
struct cdp_hist_stats *dst_hstats, /**
uint8_t tid, uint32_t mode); * dp_txrx_get_peer_delay_stats() - to get peer delay stats per TIDs
#endif /* QCA_PEER_EXT_STATS */ * @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_ */ #endif /* #ifndef _DP_INTERNAL_H_ */

View File

@@ -9951,145 +9951,6 @@ static QDF_STATUS dp_txrx_update_vdev_host_stats(struct cdp_soc_t *soc_hdl,
return QDF_STATUS_SUCCESS; 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 /* dp_txrx_get_peer_stats - will return cdp_peer_stats
* @soc: soc handle * @soc: soc handle
* @vdev_id: id of vdev handle * @vdev_id: id of vdev handle

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * 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); DP_PRINT_STATS("Avg = %u\n", hstats->avg);
} }
void dp_accumulate_delay_tid_stats(struct dp_soc *soc, /*
struct cdp_delay_tid_stats stats[] * dp_accumulate_delay_tid_stats(): Accumulate the tid stats to the
[CDP_MAX_TXRX_CTX], * hist stats.
struct cdp_hist_stats *dst_hstats, * @soc: DP SoC handle
uint8_t tid, uint32_t mode) * @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; 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.res_full +
tgtobj->stats.tx_i.dropped.headroom_insufficient; 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 */