qcacmn: Send cmd to dump FW stats on suspend failure
Add support to send unit test command to FW to dump stats on suspend failure due to pending tx completions. Change-Id: I6afb69a862c366c66a1e1f3dc009964272dfb75a CRs-Fixed: 3151458
This commit is contained in:

committed by
Madan Koyyalamudi

parent
925aca8a6b
commit
68116c0a80
@@ -1327,6 +1327,10 @@ struct ol_if_ops {
|
|||||||
uint8_t add_or_sub, uint8_t ac);
|
uint8_t add_or_sub, uint8_t ac);
|
||||||
#endif
|
#endif
|
||||||
uint32_t (*dp_get_tx_inqueue)(ol_txrx_soc_handle soc);
|
uint32_t (*dp_get_tx_inqueue)(ol_txrx_soc_handle soc);
|
||||||
|
QDF_STATUS(*dp_send_unit_test_cmd)(uint32_t vdev_id,
|
||||||
|
uint32_t module_id,
|
||||||
|
uint32_t arg_count, uint32_t *arg);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DP_PEER_EXTENDED_API
|
#ifdef DP_PEER_EXTENDED_API
|
||||||
|
@@ -52,6 +52,7 @@
|
|||||||
#include "htt_ppdu_stats.h"
|
#include "htt_ppdu_stats.h"
|
||||||
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
||||||
#include "cfg_ucfg_api.h"
|
#include "cfg_ucfg_api.h"
|
||||||
|
#include <wlan_module_ids.h>
|
||||||
|
|
||||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||||
#include "cdp_txrx_flow_ctrl_v2.h"
|
#include "cdp_txrx_flow_ctrl_v2.h"
|
||||||
@@ -12658,6 +12659,8 @@ static void dp_find_missing_tx_comp(struct dp_soc *soc)
|
|||||||
uint16_t num_desc_per_page;
|
uint16_t num_desc_per_page;
|
||||||
struct dp_tx_desc_s *tx_desc = NULL;
|
struct dp_tx_desc_s *tx_desc = NULL;
|
||||||
struct dp_tx_desc_pool_s *tx_desc_pool = NULL;
|
struct dp_tx_desc_pool_s *tx_desc_pool = NULL;
|
||||||
|
bool send_fw_stats_cmd = false;
|
||||||
|
uint8_t vdev_id;
|
||||||
|
|
||||||
for (i = 0; i < MAX_TXDESC_POOLS; i++) {
|
for (i = 0; i < MAX_TXDESC_POOLS; i++) {
|
||||||
tx_desc_pool = &soc->tx_desc[i];
|
tx_desc_pool = &soc->tx_desc[i];
|
||||||
@@ -12686,6 +12689,11 @@ static void dp_find_missing_tx_comp(struct dp_soc *soc)
|
|||||||
tx_desc->timestamp)) {
|
tx_desc->timestamp)) {
|
||||||
dp_err_rl("Tx completion not rcvd for id: %u",
|
dp_err_rl("Tx completion not rcvd for id: %u",
|
||||||
tx_desc->id);
|
tx_desc->id);
|
||||||
|
|
||||||
|
if (!send_fw_stats_cmd) {
|
||||||
|
send_fw_stats_cmd = true;
|
||||||
|
vdev_id = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dp_err_rl("tx desc %u corrupted, flags: 0x%x",
|
dp_err_rl("tx desc %u corrupted, flags: 0x%x",
|
||||||
@@ -12693,6 +12701,18 @@ static void dp_find_missing_tx_comp(struct dp_soc *soc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The unit test command to dump FW stats is required only once as the
|
||||||
|
* stats are dumped at pdev level and not vdev level.
|
||||||
|
*/
|
||||||
|
if (send_fw_stats_cmd && soc->cdp_soc.ol_ops->dp_send_unit_test_cmd) {
|
||||||
|
uint32_t fw_stats_args[2] = {533, 1};
|
||||||
|
|
||||||
|
soc->cdp_soc.ol_ops->dp_send_unit_test_cmd(vdev_id,
|
||||||
|
WLAN_MODULE_TX, 2,
|
||||||
|
fw_stats_args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void dp_find_missing_tx_comp(struct dp_soc *soc)
|
static inline void dp_find_missing_tx_comp(struct dp_soc *soc)
|
||||||
|
@@ -6319,10 +6319,15 @@ void dp_txrx_path_stats(struct dp_soc *soc)
|
|||||||
DP_PRINT_STATS("successfully transmitted: %u msdus (%llu bytes)",
|
DP_PRINT_STATS("successfully transmitted: %u msdus (%llu bytes)",
|
||||||
pdev->stats.tx.tx_success.num,
|
pdev->stats.tx.tx_success.num,
|
||||||
pdev->stats.tx.tx_success.bytes);
|
pdev->stats.tx.tx_success.bytes);
|
||||||
for (i = 0; i < soc->num_tcl_data_rings; i++)
|
for (i = 0; i < soc->num_tcl_data_rings; i++) {
|
||||||
DP_PRINT_STATS("Enqueue to SW2TCL%u: %u", i + 1,
|
DP_PRINT_STATS("Enqueue to SW2TCL%u: %u", i + 1,
|
||||||
soc->stats.tx.tcl_enq[i]);
|
soc->stats.tx.tcl_enq[i]);
|
||||||
|
DP_PRINT_STATS("TX completions reaped from ring %u: %u",
|
||||||
|
i, soc->stats.tx.tx_comp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DP_PRINT_STATS("Invalid release source: %u",
|
||||||
|
soc->stats.tx.invalid_release_source);
|
||||||
DP_PRINT_STATS("Dropped in host:");
|
DP_PRINT_STATS("Dropped in host:");
|
||||||
DP_PRINT_STATS("Total packets dropped: %u,",
|
DP_PRINT_STATS("Total packets dropped: %u,",
|
||||||
pdev->stats.tx_i.dropped.dropped_pkt.num);
|
pdev->stats.tx_i.dropped.dropped_pkt.num);
|
||||||
|
@@ -5114,6 +5114,8 @@ next_desc:
|
|||||||
if (head_desc)
|
if (head_desc)
|
||||||
dp_tx_comp_process_desc_list(soc, head_desc, ring_id);
|
dp_tx_comp_process_desc_list(soc, head_desc, ring_id);
|
||||||
|
|
||||||
|
DP_STATS_INC(soc, tx.tx_comp[ring_id], count);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are processing in near-full condition, there are 3 scenario
|
* If we are processing in near-full condition, there are 3 scenario
|
||||||
* 1) Ring entries has reached critical state
|
* 1) Ring entries has reached critical state
|
||||||
|
@@ -1045,6 +1045,8 @@ struct dp_soc_stats {
|
|||||||
uint32_t tx_comp_exception;
|
uint32_t tx_comp_exception;
|
||||||
/* TQM drops after/during peer delete */
|
/* TQM drops after/during peer delete */
|
||||||
uint64_t tqm_drop_no_peer;
|
uint64_t tqm_drop_no_peer;
|
||||||
|
/* Number of tx completions reaped per WBM2SW release ring */
|
||||||
|
uint32_t tx_comp[MAX_TCL_DATA_RINGS];
|
||||||
} tx;
|
} tx;
|
||||||
|
|
||||||
/* SOC level RX stats */
|
/* SOC level RX stats */
|
||||||
|
Reference in New Issue
Block a user