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:

committed by
Rahul Choudhary

parent
084db81bf9
commit
dcfc490267
@@ -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");
|
||||||
|
@@ -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_ */
|
||||||
|
@@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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
|
||||||
|
@@ -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,9 +490,9 @@ 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)
|
||||||
{
|
{
|
||||||
struct dp_soc *soc = (struct dp_soc *)dp_soc;
|
struct dp_soc *soc = (struct dp_soc *)dp_soc;
|
||||||
struct dp_pdev *pdev;
|
struct dp_pdev *pdev;
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
@@ -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_ */
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user