diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 362fbb85a5..013e67732d 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -5261,6 +5261,50 @@ static inline void dp_soc_rx_history_detach(struct dp_soc *soc) } #endif +#ifdef WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY +/** + * dp_soc_mon_status_ring_history_attach() - Attach the monitor status + * buffer record history. + * @soc: DP soc handle + * + * This function allocates memory to track the event for a monitor + * status buffer, before its parsed and freed. + * + * Return: None + */ +static void dp_soc_mon_status_ring_history_attach(struct dp_soc *soc) +{ + soc->mon_status_ring_history = dp_context_alloc_mem(soc, + DP_MON_STATUS_BUF_HIST_TYPE, + sizeof(struct dp_mon_status_ring_history)); + if (!soc->mon_status_ring_history) { + dp_err("Failed to alloc memory for mon status ring history"); + return; + } +} + +/** + * dp_soc_mon_status_ring_history_detach() - Detach the monitor status buffer + * record history. + * @soc: DP soc handle + * + * Return: None + */ +static void dp_soc_mon_status_ring_history_detach(struct dp_soc *soc) +{ + dp_context_free_mem(soc, DP_MON_STATUS_BUF_HIST_TYPE, + soc->mon_status_ring_history); +} +#else +static void dp_soc_mon_status_ring_history_attach(struct dp_soc *soc) +{ +} + +static void dp_soc_mon_status_ring_history_detach(struct dp_soc *soc) +{ +} +#endif + #ifdef WLAN_FEATURE_DP_TX_DESC_HISTORY /** * dp_soc_tx_history_attach() - Attach the ring history record buffers @@ -5931,6 +5975,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc) wlan_cfg_soc_detach(soc->wlan_cfg_ctx); dp_soc_tx_hw_desc_history_detach(soc); dp_soc_tx_history_detach(soc); + dp_soc_mon_status_ring_history_detach(soc); dp_soc_rx_history_detach(soc); if (!dp_monitor_modularized_enable()) { @@ -13920,6 +13965,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, dp_soc_tx_hw_desc_history_attach(soc); dp_soc_rx_history_attach(soc); + dp_soc_mon_status_ring_history_attach(soc); dp_soc_tx_history_attach(soc); wlan_set_srng_cfg(&soc->wlan_srng_cfg); soc->wlan_cfg_ctx = wlan_cfg_soc_attach(soc->ctrl_psoc); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 04652d3755..3e51d78f6e 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -425,6 +425,7 @@ struct dp_rx_nbuf_frag_info { * @DP_TX_HW_DESC_HIST_TYPE: Datapath TX HW descriptor history * @DP_MON_SOC_TYPE: Datapath monitor soc context * @DP_MON_PDEV_TYPE: Datapath monitor pdev context + * @DP_MON_STATUS_BUF_HIST_TYPE: DP monitor status buffer history */ enum dp_ctxt_type { DP_PDEV_TYPE, @@ -438,6 +439,7 @@ enum dp_ctxt_type { DP_TX_HW_DESC_HIST_TYPE, DP_MON_SOC_TYPE, DP_MON_PDEV_TYPE, + DP_MON_STATUS_BUF_HIST_TYPE, }; /** @@ -1356,6 +1358,50 @@ struct dp_tx_hw_desc_history { }; #endif +/* + * enum dp_mon_status_process_event - Events for monitor status buffer record + * @DP_MON_STATUS_BUF_REAP: Monitor status buffer is reaped from ring + * @DP_MON_STATUS_BUF_ENQUEUE: Status buffer is enqueued to local queue + * @DP_MON_STATUS_BUF_DEQUEUE: Status buffer is dequeued from local queue + */ +enum dp_mon_status_process_event { + DP_MON_STATUS_BUF_REAP, + DP_MON_STATUS_BUF_ENQUEUE, + DP_MON_STATUS_BUF_DEQUEUE, +}; + +#ifdef WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY +#define DP_MON_STATUS_HIST_MAX 2048 + +/** + * struct dp_buf_info_record - ring buffer info + * @hbi: HW ring buffer info + * @timestamp: timestamp when this entry was recorded + * @event: event + * @rx_desc: RX descriptor corresponding to the received buffer + * @nbuf: buffer attached to rx_desc, if event is REAP, else the buffer + * which was enqueued or dequeued. + * @rx_desc_nbuf_data: nbuf data pointer. + */ +struct dp_mon_stat_info_record { + struct hal_buf_info hbi; + uint64_t timestamp; + enum dp_mon_status_process_event event; + void *rx_desc; + qdf_nbuf_t nbuf; + uint8_t *rx_desc_nbuf_data; +}; + +/* struct dp_rx_history - rx ring hisotry + * @index: Index where the last entry is written + * @entry: history entries + */ +struct dp_mon_status_ring_history { + qdf_atomic_t index; + struct dp_mon_stat_info_record entry[DP_MON_STATUS_HIST_MAX]; +}; +#endif + #ifdef WLAN_FEATURE_DP_RX_RING_HISTORY /* * The logic for get current index of these history is dependent on this @@ -2142,6 +2188,10 @@ struct dp_soc { struct dp_rx_reinject_history *rx_reinject_ring_history; #endif +#ifdef WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY + struct dp_mon_status_ring_history *mon_status_ring_history; +#endif + #ifdef WLAN_FEATURE_DP_TX_DESC_HISTORY struct dp_tx_tcl_history *tx_tcl_history; struct dp_tx_comp_history *tx_comp_history; diff --git a/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c b/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c index 53461bcbce..572431332b 100644 --- a/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c +++ b/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c @@ -329,6 +329,84 @@ dp_rx_mon_update_scan_spcl_vap_stats(struct dp_pdev *pdev, } #endif +#ifdef WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY +/** + * dp_rx_mon_status_ring_record_entry() - Record one entry of a particular + * event type into the monitor status + * buffer tracking history. + * @soc: DP soc handle + * @event: event type + * @ring_desc: Monitor status ring descriptor + * @rx_desc: RX descriptor + * @nbuf: status buffer. + * + * Return: None + */ +static void +dp_rx_mon_status_ring_record_entry(struct dp_soc *soc, + enum dp_mon_status_process_event event, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc, + qdf_nbuf_t nbuf) +{ + struct dp_mon_stat_info_record *record; + struct hal_buf_info hbi; + uint32_t idx; + + if (qdf_unlikely(!soc->mon_status_ring_history)) + return; + + idx = dp_history_get_next_index(&soc->mon_status_ring_history->index, + DP_MON_STATUS_HIST_MAX); + + /* No NULL check needed for record since its an array */ + record = &soc->mon_status_ring_history->entry[idx]; + + record->timestamp = qdf_get_log_timestamp(); + if (event == DP_MON_STATUS_BUF_REAP) { + hal_rx_buffer_addr_info_get_paddr(ring_desc, &hbi); + + /* buffer_addr_info is the first element of ring_desc */ + hal_rx_buf_cookie_rbm_get(soc->hal_soc, (uint32_t *)ring_desc, + &hbi); + + record->hbi.paddr = hbi.paddr; + record->hbi.sw_cookie = hbi.sw_cookie; + record->hbi.rbm = hbi.rbm; + record->rx_desc = rx_desc; + if (rx_desc) { + record->nbuf = rx_desc->nbuf; + record->rx_desc_nbuf_data = qdf_nbuf_data(rx_desc->nbuf); + } else { + record->nbuf = NULL; + record->rx_desc_nbuf_data = NULL; + } + } + + if (event == DP_MON_STATUS_BUF_ENQUEUE) { + record->nbuf = nbuf; + record->rx_desc_nbuf_data = qdf_nbuf_data(nbuf); + } + + if (event == DP_MON_STATUS_BUF_DEQUEUE) { + record->nbuf = nbuf; + if (nbuf) + record->rx_desc_nbuf_data = qdf_nbuf_data(nbuf); + else + record->rx_desc_nbuf_data = NULL; + } +} +#else +static void +dp_rx_mon_status_ring_record_entry(struct dp_soc *soc, + enum dp_mon_status_process_event event, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc, + qdf_nbuf_t nbuf) +{ +} +#endif + /** * dp_rx_mon_status_process_tlv() - Process status TLV in status * buffer on Rx status Queue posted by status SRNG processing. @@ -376,6 +454,9 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, struct dp_intr *int_ctx, while (!qdf_nbuf_is_queue_empty(&mon_pdev->rx_status_q)) { status_nbuf = qdf_nbuf_queue_remove(&mon_pdev->rx_status_q); + dp_rx_mon_status_ring_record_entry(soc, + DP_MON_STATUS_BUF_DEQUEUE, + NULL, NULL, status_nbuf); if (!status_nbuf) return; @@ -593,6 +674,9 @@ dp_rx_mon_status_srng_process(struct dp_soc *soc, struct dp_intr *int_ctx, &hbi); rx_desc = dp_rx_cookie_2_va_mon_status(soc, hbi.sw_cookie); + dp_rx_mon_status_ring_record_entry(soc, DP_MON_STATUS_BUF_REAP, + rxdma_mon_status_ring_entry, + rx_desc, NULL); qdf_assert_always(rx_desc); @@ -662,6 +746,9 @@ dp_rx_mon_status_srng_process(struct dp_soc *soc, struct dp_intr *int_ctx, /* Put the status_nbuf to queue */ qdf_nbuf_queue_add(&mon_pdev->rx_status_q, status_nbuf); + dp_rx_mon_status_ring_record_entry(soc, DP_MON_STATUS_BUF_ENQUEUE, + rxdma_mon_status_ring_entry, + rx_desc, status_nbuf); } else { union dp_rx_desc_list_elem_t *desc_list = NULL;