qcacmn: debug and reset functionality for monitor

monitor reset functionality when bkpressure is seen.
debug logs added to inspect monitor ring in case of bp.

Change-Id: I8e79f97b315653f302da087ea8d82362ba02723d
CRs-Fixed: 3542923
This commit is contained in:
Ruben Columbus
2023-08-20 20:20:51 -07:00
committed by Rahul Choudhary
parent 084db81bf9
commit dcfc490267
7 changed files with 575 additions and 8 deletions

View File

@@ -3151,6 +3151,21 @@ static void dp_queue_ring_stats(struct dp_pdev *pdev)
&pdev->bkp_stats.work); &pdev->bkp_stats.work);
} }
#ifdef WIFI_MONITOR_SUPPORT
static void
dp_check_backpressure_in_monitor(uint8_t ring_id, struct dp_pdev *pdev)
{
if (ring_id >= HTT_SW_RING_IDX_MONITOR_STATUS_RING &&
ring_id <= HTT_SW_LMAC_RING_IDX_MAX)
pdev->monitor_pdev->is_bkpressure = true;
}
#else
static void
dp_check_backpressure_in_monitor(uint8_t ring_id, struct dp_pdev *pdev)
{
}
#endif
/** /**
* dp_htt_bkp_event_alert() - htt backpressure event alert * dp_htt_bkp_event_alert() - htt backpressure event alert
* @msg_word: htt packet context * @msg_word: htt packet context
@@ -3209,6 +3224,7 @@ static void dp_htt_bkp_event_alert(u_int32_t *msg_word, struct htt_soc *soc)
case HTT_SW_RING_TYPE_LMAC: case HTT_SW_RING_TYPE_LMAC:
if (!time_allow_print(radio_tt->lmac_path, ring_id, th_time)) if (!time_allow_print(radio_tt->lmac_path, ring_id, th_time))
return; return;
dp_check_backpressure_in_monitor(ring_id, pdev);
dp_htt_alert_print(msg_type, pdev, ring_id, hp_idx, tp_idx, dp_htt_alert_print(msg_type, pdev, ring_id, hp_idx, tp_idx,
bkp_time, radio_tt->lmac_path, bkp_time, radio_tt->lmac_path,
"HTT_SW_RING_TYPE_LMAC"); "HTT_SW_RING_TYPE_LMAC");

View File

@@ -5453,4 +5453,42 @@ void dp_tx_remove_vlan_tag(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
* Return: None. * Return: None.
*/ */
void dp_print_per_link_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id); void dp_print_per_link_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id);
/**
* dp_get_ring_stats_from_hal(): get hal level ring pointer values
* @soc: DP_SOC handle
* @srng: DP_SRNG handle
* @ring_type: srng src/dst ring
* @_tailp: pointer to tail of ring
* @_headp: pointer to head of ring
* @_hw_headp: pointer to head of ring in HW
* @_hw_tailp: pointer to tail of ring in HW
*
* Return: void
*/
static inline void
dp_get_ring_stats_from_hal(struct dp_soc *soc, struct dp_srng *srng,
enum hal_ring_type ring_type,
uint32_t *_tailp, uint32_t *_headp,
int32_t *_hw_headp, int32_t *_hw_tailp)
{
uint32_t tailp;
uint32_t headp;
int32_t hw_headp = -1;
int32_t hw_tailp = -1;
struct hal_soc *hal_soc;
if (soc && srng && srng->hal_srng) {
hal_soc = (struct hal_soc *)soc->hal_soc;
hal_get_sw_hptp(soc->hal_soc, srng->hal_srng, &tailp, &headp);
*_headp = headp;
*_tailp = tailp;
hal_get_hw_hptp(soc->hal_soc, srng->hal_srng, &hw_headp,
&hw_tailp, ring_type);
*_hw_headp = hw_headp;
*_hw_tailp = hw_tailp;
}
}
#endif /* #ifndef _DP_INTERNAL_H_ */ #endif /* #ifndef _DP_INTERNAL_H_ */

View File

@@ -120,6 +120,19 @@ dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id)
uint32_t uint32_t
dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id, dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id,
bool force_flush); bool force_flush);
#else
#ifdef QCA_SUPPORT_FULL_MON
/**
* dp_mon_dest_srng_drop_for_mac() - Drop the mon dest ring packets for
* a given mac
* @pdev: DP pdev
* @mac_id: mac id
*
* Return: None
*/
uint32_t
dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id);
#endif
#endif #endif
/** /**

View File

@@ -1032,6 +1032,159 @@ dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id,
return reap_cnt; return reap_cnt;
} }
#else
#if defined(QCA_SUPPORT_FULL_MON) && defined(WIFI_MONITOR_SUPPORT)
uint32_t
dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id)
{
struct dp_soc *soc = pdev->soc;
hal_rxdma_desc_t rxdma_dst_ring_desc;
hal_soc_handle_t hal_soc;
void *mon_dst_srng;
union dp_rx_desc_list_elem_t *head = NULL;
union dp_rx_desc_list_elem_t *tail = NULL;
uint32_t rx_bufs_used = 0;
void *rx_msdu_link_desc;
uint16_t num_msdus;
struct hal_rx_msdu_list msdu_list;
qdf_nbuf_t nbuf = NULL;
uint32_t i;
uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS];
struct rx_desc_pool *rx_desc_pool = NULL;
uint32_t reap_cnt = 0;
struct dp_mon_pdev *mon_pdev;
struct hal_rx_mon_desc_info *desc_info;
if (qdf_unlikely(!soc || !soc->hal_soc))
return reap_cnt;
mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_id);
if (qdf_unlikely(!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)))
return reap_cnt;
hal_soc = soc->hal_soc;
mon_pdev = pdev->monitor_pdev;
desc_info = mon_pdev->mon_desc;
rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id);
while ((rxdma_dst_ring_desc =
hal_srng_dst_peek(hal_soc, mon_dst_srng))) {
qdf_mem_zero(desc_info, sizeof(struct hal_rx_mon_desc_info));
hal_rx_sw_mon_desc_info_get((struct hal_soc *)soc->hal_soc,
(void *)rxdma_dst_ring_desc,
(void *)desc_info);
if (desc_info->end_of_ppdu) {
rxdma_dst_ring_desc =
hal_srng_dst_get_next(hal_soc, mon_dst_srng);
continue;
}
do {
rx_msdu_link_desc =
dp_rx_cookie_2_mon_link_desc(pdev,
&desc_info->
link_desc,
mac_id);
if (qdf_unlikely(!rx_msdu_link_desc)) {
mon_pdev->rx_mon_stats.mon_link_desc_invalid++;
goto next_entry;
}
hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc,
&msdu_list, &num_msdus);
for (i = 0; i < num_msdus; i++) {
struct dp_rx_desc *rx_desc;
qdf_dma_addr_t buf_paddr;
rx_desc =
dp_rx_get_mon_desc(soc, msdu_list.
sw_cookie[i]);
if (qdf_unlikely(!rx_desc)) {
mon_pdev->rx_mon_stats.
mon_rx_desc_invalid++;
continue;
}
nbuf = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc);
buf_paddr =
dp_rx_mon_get_paddr_from_desc(rx_desc);
if (qdf_unlikely(!rx_desc->in_use || !nbuf ||
msdu_list.paddr[i] !=
buf_paddr)) {
mon_pdev->rx_mon_stats.
mon_nbuf_sanity_err++;
continue;
}
rx_bufs_used++;
if (!rx_desc->unmapped) {
dp_rx_mon_buffer_unmap(soc, rx_desc,
rx_desc_pool->
buf_size);
rx_desc->unmapped = 1;
}
dp_rx_mon_buffer_free(rx_desc);
dp_rx_add_to_free_desc_list(&head, &tail,
rx_desc);
if (!(msdu_list.msdu_info[i].msdu_flags &
HAL_MSDU_F_MSDU_CONTINUATION))
desc_info->msdu_count--;
}
/*
* Store the current link buffer into to the local
* structure to be used for release purpose.
*/
hal_rxdma_buff_addr_info_set(soc->hal_soc,
rx_link_buf_info,
desc_info->link_desc.paddr,
desc_info->link_desc.
sw_cookie,
desc_info->link_desc.rbm);
hal_rx_mon_next_link_desc_get(soc->hal_soc,
rx_msdu_link_desc,
&desc_info->link_desc);
if (dp_rx_monitor_link_desc_return(pdev,
(hal_buff_addrinfo_t)
rx_link_buf_info,
mac_id, bm_action) !=
QDF_STATUS_SUCCESS)
dp_info_rl("monitor link desc return failed");
} while (desc_info->link_desc.paddr);
next_entry:
reap_cnt++;
rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc,
mon_dst_srng);
}
if (rx_bufs_used) {
dp_rx_buffers_replenish(soc, mac_id,
dp_rxdma_get_mon_buf_ring(pdev, mac_id),
rx_desc_pool,
rx_bufs_used, &head, &tail, false);
}
return reap_cnt;
}
#else
uint32_t
dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id)
{
return 0;
}
#endif
#endif #endif
static void static void

View File

@@ -216,6 +216,29 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
pdev_id); pdev_id);
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
struct dp_mon_pdev *mon_pdev; struct dp_mon_pdev *mon_pdev;
if (!pdev)
return QDF_STATUS_E_FAILURE;
mon_pdev = pdev->monitor_pdev;
qdf_spin_lock_bh(&mon_pdev->mon_lock);
status = dp_reset_monitor_mode_unlock(soc_hdl, pdev_id,
special_monitor);
qdf_spin_unlock_bh(&mon_pdev->mon_lock);
return status;
}
QDF_STATUS dp_reset_monitor_mode_unlock(struct cdp_soc_t *soc_hdl,
uint8_t pdev_id,
uint8_t special_monitor)
{
struct dp_soc *soc = (struct dp_soc *)soc_hdl;
struct dp_pdev *pdev =
dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
pdev_id);
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct dp_mon_pdev *mon_pdev;
struct cdp_mon_ops *cdp_ops; struct cdp_mon_ops *cdp_ops;
if (!pdev) if (!pdev)
@@ -223,12 +246,20 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
mon_pdev = pdev->monitor_pdev; mon_pdev = pdev->monitor_pdev;
qdf_spin_lock_bh(&mon_pdev->mon_lock);
cdp_ops = dp_mon_cdp_ops_get(soc); cdp_ops = dp_mon_cdp_ops_get(soc);
if (cdp_ops && cdp_ops->soc_config_full_mon_mode) if (cdp_ops && cdp_ops->soc_config_full_mon_mode) {
cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev, cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev,
DP_FULL_MON_DISABLE); DP_FULL_MON_DISABLE);
mon_pdev->hold_mon_dest_ring = false;
mon_pdev->is_bkpressure = false;
mon_pdev->set_reset_mon = false;
#if defined(QCA_SUPPORT_FULL_MON)
if (mon_pdev->mon_desc)
qdf_mem_zero(mon_pdev->mon_desc,
sizeof(struct hal_rx_mon_desc_info));
#endif
}
mon_pdev->mvdev = NULL; mon_pdev->mvdev = NULL;
/* /*
@@ -263,7 +294,6 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
mon_pdev->monitor_configured = false; mon_pdev->monitor_configured = false;
qdf_spin_unlock_bh(&mon_pdev->mon_lock);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
@@ -460,7 +490,7 @@ dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev *mon_vdev)
* *
* Return: 0 on success, not 0 on failure * Return: 0 on success, not 0 on failure
*/ */
static QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *dp_soc, QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *dp_soc,
uint8_t vdev_id, uint8_t vdev_id,
uint8_t special_monitor) uint8_t special_monitor)
{ {
@@ -6915,3 +6945,241 @@ QDF_STATUS dp_mon_soc_detach(struct dp_soc *soc)
qdf_mem_free(mon_soc); qdf_mem_free(mon_soc);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
#ifdef QCA_SUPPORT_FULL_MON
static void print_ring_tracker_stats(struct dp_mon_pdev *mon_pdev,
uint8_t target)
{
struct dp_ring_ppdu_id_tracker *tracker;
uint8_t i;
if (target)
tracker = mon_pdev->hist_ppdu_id_mon_s;
else
tracker = mon_pdev->hist_ppdu_id_mon_d;
for (i = 0; i < DP_HIST_TRACK_SIZE; i++) {
qdf_print("idx: %d dest_ppdu_id: %d dest_time: %lld d_hp: %d ",
i, tracker[i].ppdu_id_mon_dest,
tracker[i].time_ppdu_id_mon_dest,
tracker[i].dest_hp);
qdf_print("d_tp: %d d_hw_hp: %d d_hw_tp: %d status_ppdu_id: %d",
tracker[i].dest_tp,
tracker[i].dest_hw_hp,
tracker[i].dest_hw_tp,
tracker[i].ppdu_id_mon_status);
qdf_print(" status_time: %lld s_hp: %d s_tp: %d s_hw_hp: %d ",
tracker[i].time_ppdu_id_mon_status,
tracker[i].status_hp,
tracker[i].status_tp,
tracker[i].status_hw_hp);
qdf_print("s_hw_tp: %d\n",
tracker[i].status_hw_tp);
}
}
#else
static void print_ring_tracker_stats(struct dp_mon_pdev *mon_pdev,
uint8_t target)
{
}
#endif
void
dp_check_and_dump_full_mon_info(struct dp_soc *soc, struct dp_pdev *pdev,
int mac_id, int war)
{
struct dp_mon_soc *mon_soc = soc->monitor_soc;
struct dp_mon_pdev *mon_pdev;
hal_soc_handle_t hal_soc;
uint64_t buf_addr;
void *mon_status_srng;
void *rxdma_mon_status_ring_entry;
struct hal_buf_info hbi;
hal_ring_handle_t mon_dest_srng;
void *ring_desc;
struct hal_rx_mon_desc_info desc_info = {0};
struct dp_rx_desc *rx_desc;
uint64_t ppdu_id = 0;
if (!mon_soc) {
dp_err("Monitor soc is NULL\n");
return;
}
if (!mon_soc->full_mon_mode) {
dp_err("Full monitor mode is disable\n");
return;
}
/**
* As rx_mon_ring_mask is set but workdone is 0
* there is a more chance backpressure can happen.
* dump the content of rx monitor status and destination ring
* and move to next pointers.
*/
mon_pdev = pdev->monitor_pdev;
if (!mon_pdev) {
dp_err("mon_pdev is NULL\n");
return;
}
hal_soc = soc->hal_soc;
if (!war)
qdf_spin_lock_bh(&mon_pdev->mon_lock);
mon_status_srng = soc->rxdma_mon_status_ring[mac_id].hal_srng;
if (!mon_status_srng)
goto unlock_monitor;
dp_print_ring_stat_from_hal(soc, &soc->rxdma_mon_status_ring[mac_id],
RXDMA_MONITOR_STATUS);
rxdma_mon_status_ring_entry =
hal_srng_src_peek_n_get_next(hal_soc, mon_status_srng);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"hold_mon_dest_ring: %d\n", mon_pdev->hold_mon_dest_ring);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"mon_pdev last_ppdu_id: %d\n", mon_pdev->last_ppdu_id);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"soc: %d\n", hal_get_target_type(hal_soc));
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"reap_status:\n");
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_NO_DMA : %lld\n",
mon_pdev->reap_status[DP_MON_STATUS_NO_DMA]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_MATCH : %lld\n",
mon_pdev->reap_status[DP_MON_STATUS_MATCH]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_LAG : %lld\n",
mon_pdev->reap_status[DP_MON_STATUS_LAG]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_LEAD : %lld\n",
mon_pdev->reap_status[DP_MON_STATUS_LEAD]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_REPLENISH : %lld\n",
mon_pdev->reap_status[DP_MON_STATUS_REPLENISH]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"prev_status:\n");
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_NO_DMA : %lld\n",
mon_pdev->prev_status[DP_MON_STATUS_NO_DMA]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_MATCH : %lld\n",
mon_pdev->prev_status[DP_MON_STATUS_MATCH]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_LAG : %lld\n",
mon_pdev->prev_status[DP_MON_STATUS_LAG]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_LEAD : %lld\n",
mon_pdev->prev_status[DP_MON_STATUS_LEAD]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_REPLENISH : %lld\n",
mon_pdev->prev_status[DP_MON_STATUS_REPLENISH]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"match_stats:\n");
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_LAG : %lld\n",
mon_pdev->status_match[DP_MON_STATUS_LAG]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"\t DP_MON_STATUS_LEAD : %lld\n",
mon_pdev->status_match[DP_MON_STATUS_LEAD]);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"mismatch: %d\n",
mon_pdev->rx_mon_stats.ppdu_id_mismatch);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"status_ppdu_drop: %d\n",
mon_pdev->rx_mon_stats.status_ppdu_drop);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"dest_ppdu_drop: %d\n",
mon_pdev->rx_mon_stats.dest_ppdu_drop);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"tlv_tag_status_err: %d\n",
mon_pdev->rx_mon_stats.tlv_tag_status_err);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"status_buf_done_war: %d\n",
mon_pdev->rx_mon_stats.status_buf_done_war);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"soc[%pK] pdev[%pK] mac_id[%d]\n",
soc, pdev, mac_id);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"MON DEST TRACKER STATS:\n");
print_ring_tracker_stats(mon_pdev, 0);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"MON STA TRACKER STATS:\n");
print_ring_tracker_stats(mon_pdev, 1);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"rxdma_mon_status_ring:\n");
if (!rxdma_mon_status_ring_entry) {
dp_err("rxdma_mon_status_ring_entry NULL\n");
goto dump_mon_destination_ring;
}
buf_addr =
(HAL_RX_BUFFER_ADDR_31_0_GET(rxdma_mon_status_ring_entry) |
((uint64_t)
(HAL_RX_BUFFER_ADDR_39_32_GET(rxdma_mon_status_ring_entry))
<< 32));
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"Buffer address : %llx\n", buf_addr);
if (!buf_addr)
goto dump_mon_destination_ring;
hal_rx_buf_cookie_rbm_get(soc->hal_soc,
(uint32_t *)rxdma_mon_status_ring_entry,
&hbi);
print_hex_dump(KERN_ERR, "\tHAL_BUF_INFO: ", DUMP_PREFIX_NONE, 32, 4,
&hbi, sizeof(struct hal_buf_info), false);
rx_desc = dp_rx_cookie_2_va_mon_status(soc, hbi.sw_cookie);
if (!rx_desc) {
dp_err("rx_desc is NULL\n");
goto dump_mon_destination_ring;
}
print_hex_dump(KERN_ERR, "\tRX_DESC: ", DUMP_PREFIX_NONE, 32, 4,
rx_desc, sizeof(struct dp_rx_desc), false);
dump_mon_destination_ring:
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"rxdma_mon_destination_ring:\n");
mon_dest_srng = pdev->soc->rxdma_mon_dst_ring[mac_id].hal_srng;
if (!mon_dest_srng) {
dp_err("rxdma_mon_dst_ring hal_srng is NULL\n");
goto unlock_monitor;
}
dp_print_ring_stat_from_hal(soc, &soc->rxdma_mon_dst_ring[mac_id],
RXDMA_MONITOR_DST);
ring_desc = hal_srng_dst_peek(hal_soc, mon_dest_srng);
if (!ring_desc)
goto unlock_monitor;
ppdu_id = hal_rx_hw_desc_get_ppduid_get(hal_soc, NULL, ring_desc);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"Next dest ring ppdu id: %lld\n", ppdu_id);
hal_rx_sw_mon_desc_info_get((struct hal_soc *)soc->hal_soc,
ring_desc, &desc_info);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"Next desc_info ppdu_id: %d\n", desc_info.ppdu_id);
print_hex_dump(KERN_ERR, "\tDESC_INFO: ", DUMP_PREFIX_NONE, 32, 4,
&desc_info, sizeof(struct hal_rx_mon_desc_info), false);
unlock_monitor:
if (!war)
qdf_spin_unlock_bh(&mon_pdev->mon_lock);
}

View File

@@ -22,6 +22,7 @@
#include "dp_internal.h" #include "dp_internal.h"
#include "dp_types.h" #include "dp_types.h"
#include "dp_htt.h" #include "dp_htt.h"
#include "dp_rx_mon.h"
#include <dp_mon_filter.h> #include <dp_mon_filter.h>
#ifdef WLAN_TX_PKT_CAPTURE_ENH #ifdef WLAN_TX_PKT_CAPTURE_ENH
@@ -33,6 +34,7 @@
#endif #endif
#define DP_INTR_POLL_TIMER_MS 5 #define DP_INTR_POLL_TIMER_MS 5
#define DP_HIST_TRACK_SIZE 50
#define MON_VDEV_TIMER_INIT 0x1 #define MON_VDEV_TIMER_INIT 0x1
#define MON_VDEV_TIMER_RUNNING 0x2 #define MON_VDEV_TIMER_RUNNING 0x2
@@ -1030,9 +1032,25 @@ struct dp_rx_mon_rssi_offset {
int32_t rssi_offset; int32_t rssi_offset;
}; };
struct dp_ring_ppdu_id_tracker {
uint64_t time_ppdu_id_mon_dest;
uint32_t ppdu_id_mon_dest;
uint64_t time_ppdu_id_mon_status;
uint32_t ppdu_id_mon_status;
uint32_t dest_hp;
uint32_t dest_tp;
int32_t dest_hw_hp;
int32_t dest_hw_tp;
uint32_t status_hp;
uint32_t status_tp;
int32_t status_hw_hp;
int32_t status_hw_tp;
};
struct dp_mon_pdev { struct dp_mon_pdev {
/* monitor */ /* monitor */
bool monitor_configured; bool monitor_configured;
uint32_t mon_vdev_id;
struct dp_mon_filter **filter; /* Monitor Filter pointer */ struct dp_mon_filter **filter; /* Monitor Filter pointer */
@@ -1086,9 +1104,18 @@ struct dp_mon_pdev {
* struct dp_mon_mpdu_list mpdu_list[MAX_MU_USERS]; * struct dp_mon_mpdu_list mpdu_list[MAX_MU_USERS];
*/ */
struct hal_rx_mon_desc_info *mon_desc; struct hal_rx_mon_desc_info *mon_desc;
struct dp_ring_ppdu_id_tracker hist_ppdu_id_mon_d[DP_HIST_TRACK_SIZE];
struct dp_ring_ppdu_id_tracker hist_ppdu_id_mon_s[DP_HIST_TRACK_SIZE];
uint8_t hist_mon_dest_idx;
uint8_t hist_mon_status_idx;
#endif #endif
bool set_reset_mon;
bool is_bkpressure;
/* Flag to hold on to monitor destination ring */ /* Flag to hold on to monitor destination ring */
bool hold_mon_dest_ring; bool hold_mon_dest_ring;
uint64_t reap_status[DP_MON_STATUS_MAX];
uint64_t prev_status[DP_MON_STATUS_MAX];
uint64_t status_match[DP_MON_STATUS_MAX];
/* Flag to indicate monitor rings are initialized */ /* Flag to indicate monitor rings are initialized */
uint8_t pdev_mon_init; uint8_t pdev_mon_init;
@@ -4241,6 +4268,27 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
uint8_t pdev_id, uint8_t pdev_id,
uint8_t smart_monitor); uint8_t smart_monitor);
/**
* dp_reset_monitor_mode_unlock() - Disable monitor mode with no locks
* @soc_hdl: Datapath soc handle
* @pdev_id: id of datapath PDEV handle
* @smart_monitor: smart monitor flag
*
* Return: QDF_STATUS
*/
#ifdef WIFI_MONITOR_SUPPORT
QDF_STATUS dp_reset_monitor_mode_unlock(struct cdp_soc_t *soc_hdl,
uint8_t pdev_id,
uint8_t smart_monitor);
#else
QDF_STATUS dp_reset_monitor_mode_unlock(struct cdp_soc_t *soc_hdl,
uint8_t pdev_id,
uint8_t smart_monitor)
{
return QDF_STATUS_SUCCESS;
}
#endif
static inline static inline
struct dp_mon_ops *dp_mon_ops_get(struct dp_soc *soc) struct dp_mon_ops *dp_mon_ops_get(struct dp_soc *soc)
{ {
@@ -4510,6 +4558,10 @@ QDF_STATUS dp_pdev_get_rx_mon_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
bool dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, bool dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl,
enum cdp_mon_reap_source source, bool enable); enum cdp_mon_reap_source source, bool enable);
QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *dp_soc,
uint8_t vdev_id,
uint8_t special_monitor);
#ifdef QCA_ENHANCED_STATS_SUPPORT #ifdef QCA_ENHANCED_STATS_SUPPORT
/** /**
* dp_enable_enhanced_stats() - enable enhanced and MLD Link Peer stats * dp_enable_enhanced_stats() - enable enhanced and MLD Link Peer stats
@@ -4866,4 +4918,18 @@ QDF_STATUS dp_local_pkt_capture_tx_config(struct dp_pdev *pdev)
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
#endif #endif
#ifdef WIFI_MONITOR_SUPPORT
void
dp_check_and_dump_full_mon_info(struct dp_soc *soc, struct dp_pdev *pdev,
int mac_id, int war);
#else
void
dp_check_and_dump_full_mon_info(struct dp_soc *soc, struct dp_pdev *pdev,
int mac_id, int war);
{
}
#endif
#endif /* _DP_MON_H_ */ #endif /* _DP_MON_H_ */

View File

@@ -72,13 +72,15 @@
* @DP_MON_STATUS_LAG: status ppdu id is lagging * @DP_MON_STATUS_LAG: status ppdu id is lagging
* @DP_MON_STATUS_LEAD: status ppdu id is leading * @DP_MON_STATUS_LEAD: status ppdu id is leading
* @DP_MON_STATUS_REPLENISH: status ring entry is NULL * @DP_MON_STATUS_REPLENISH: status ring entry is NULL
* @DP_MON_STATUS_MAX: max num of different status
*/ */
enum dp_mon_reap_status { enum dp_mon_reap_status {
DP_MON_STATUS_NO_DMA, DP_MON_STATUS_NO_DMA,
DP_MON_STATUS_MATCH, DP_MON_STATUS_MATCH,
DP_MON_STATUS_LAG, DP_MON_STATUS_LAG,
DP_MON_STATUS_LEAD, DP_MON_STATUS_LEAD,
DP_MON_STATUS_REPLENISH DP_MON_STATUS_REPLENISH,
DP_MON_STATUS_MAX
}; };
/** /**
@@ -147,6 +149,17 @@ void dp_full_mon_attach(struct dp_pdev *pdev);
*/ */
void dp_full_mon_detach(struct dp_pdev *pdev); void dp_full_mon_detach(struct dp_pdev *pdev);
/**
* dp_full_mon_partial_detach() - Full monitor mode detach with no locks
* This API deinitilises full monitor mode resources but mon_desc not free
*
* @pdev: dp pdev object
*
* Return: void
*
*/
void dp_full_mon_partial_detach(struct dp_pdev *pdev);
/** /**
* dp_rx_mon_process()- API to process monitor destination ring for * dp_rx_mon_process()- API to process monitor destination ring for
* full monitor mode * full monitor mode