|
@@ -23,6 +23,7 @@
|
|
|
|
|
|
#ifdef WLAN_FEATURE_PKT_CAPTURE_V2
|
|
|
#include <dp_types.h>
|
|
|
+#include "htt_ppdu_stats.h"
|
|
|
#endif
|
|
|
#include "wlan_pkt_capture_main.h"
|
|
|
#include "cfg_ucfg_api.h"
|
|
@@ -40,6 +41,7 @@ wdi_event_subscribe PKT_CAPTURE_TX_SUBSCRIBER;
|
|
|
wdi_event_subscribe PKT_CAPTURE_RX_SUBSCRIBER;
|
|
|
wdi_event_subscribe PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER;
|
|
|
wdi_event_subscribe PKT_CAPTURE_OFFLOAD_TX_SUBSCRIBER;
|
|
|
+wdi_event_subscribe PKT_CAPTURE_PPDU_STATS_SUBSCRIBER;
|
|
|
|
|
|
/**
|
|
|
* pkt_capture_wdi_event_subscribe() - Subscribe pkt capture callbacks
|
|
@@ -89,6 +91,16 @@ static void pkt_capture_wdi_event_subscribe(struct wlan_objmgr_psoc *psoc)
|
|
|
|
|
|
cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_OFFLOAD_TX_SUBSCRIBER,
|
|
|
WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA);
|
|
|
+
|
|
|
+ /* subscribe for packet capture mode related ppdu stats */
|
|
|
+ PKT_CAPTURE_PPDU_STATS_SUBSCRIBER.callback =
|
|
|
+ pkt_capture_callback;
|
|
|
+
|
|
|
+ PKT_CAPTURE_PPDU_STATS_SUBSCRIBER.context =
|
|
|
+ wlan_psoc_get_dp_handle(psoc);
|
|
|
+
|
|
|
+ cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_PPDU_STATS_SUBSCRIBER,
|
|
|
+ WDI_EVENT_PKT_CAPTURE_PPDU_STATS);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -117,6 +129,10 @@ static void pkt_capture_wdi_event_unsubscribe(struct wlan_objmgr_psoc *psoc)
|
|
|
/* unsubscribing for offload tx data packets */
|
|
|
cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_OFFLOAD_TX_SUBSCRIBER,
|
|
|
WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA);
|
|
|
+
|
|
|
+ /* unsubscribe ppdu smu stats */
|
|
|
+ cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_PPDU_STATS_SUBSCRIBER,
|
|
|
+ WDI_EVENT_PKT_CAPTURE_PPDU_STATS);
|
|
|
}
|
|
|
|
|
|
enum pkt_capture_mode
|
|
@@ -140,6 +156,7 @@ pkt_capture_get_pktcap_mode_v2()
|
|
|
}
|
|
|
|
|
|
#define RX_OFFLOAD_PKT 1
|
|
|
+#define PPDU_STATS_Q_MAX_SIZE 500
|
|
|
|
|
|
static void
|
|
|
pkt_capture_process_rx_data_no_peer(void *soc, uint16_t vdev_id, uint8_t *bssid,
|
|
@@ -181,6 +198,57 @@ pkt_capture_process_rx_data_no_peer(void *soc, uint16_t vdev_id, uint8_t *bssid,
|
|
|
bssid, psoc, 0);
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+pkt_capture_process_ppdu_stats(void *log_data)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+ struct pkt_capture_vdev_priv *vdev_priv;
|
|
|
+ struct pkt_capture_ppdu_stats_q_node *q_node;
|
|
|
+ htt_ppdu_stats_for_smu_tlv *smu;
|
|
|
+ uint32_t stats_len;
|
|
|
+
|
|
|
+ vdev = pkt_capture_get_vdev();
|
|
|
+ if (qdf_unlikely(!vdev))
|
|
|
+ return;
|
|
|
+
|
|
|
+ vdev_priv = pkt_capture_vdev_get_priv(vdev);
|
|
|
+ if (qdf_unlikely(!vdev_priv))
|
|
|
+ return;
|
|
|
+
|
|
|
+ smu = (htt_ppdu_stats_for_smu_tlv *)log_data;
|
|
|
+
|
|
|
+ qdf_spin_lock(&vdev_priv->lock_q);
|
|
|
+ if (qdf_list_size(&vdev_priv->ppdu_stats_q) <
|
|
|
+ PPDU_STATS_Q_MAX_SIZE) {
|
|
|
+ /*
|
|
|
+ * win size indicates the size of block ack bitmap, currently
|
|
|
+ * we support only 256 bit ba bitmap.
|
|
|
+ */
|
|
|
+ if (smu->win_size > 8) {
|
|
|
+ qdf_spin_unlock(&vdev_priv->lock_q);
|
|
|
+ pkt_capture_err("win size %d > 8 not supported\n",
|
|
|
+ smu->win_size);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ stats_len = sizeof(htt_ppdu_stats_for_smu_tlv) +
|
|
|
+ smu->win_size * sizeof(uint32_t);
|
|
|
+
|
|
|
+ q_node = qdf_mem_malloc(sizeof(*q_node) + stats_len);
|
|
|
+ if (!q_node) {
|
|
|
+ qdf_spin_unlock(&vdev_priv->lock_q);
|
|
|
+ pkt_capture_err("stats node and buf allocation fail\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_mem_copy(q_node->buf, log_data, stats_len);
|
|
|
+ /* Insert received ppdu stats in queue */
|
|
|
+ qdf_list_insert_back(&vdev_priv->ppdu_stats_q,
|
|
|
+ &q_node->node);
|
|
|
+ }
|
|
|
+ qdf_spin_unlock(&vdev_priv->lock_q);
|
|
|
+}
|
|
|
+
|
|
|
void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data,
|
|
|
u_int16_t vdev_id, uint32_t status)
|
|
|
{
|
|
@@ -380,8 +448,13 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data,
|
|
|
pkt_capture_offload_deliver_indication_handler(
|
|
|
log_data,
|
|
|
vdev_id, bssid, soc);
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
+ case WDI_EVENT_PKT_CAPTURE_PPDU_STATS:
|
|
|
+ pkt_capture_process_ppdu_stats(log_data);
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
@@ -763,6 +836,9 @@ pkt_capture_vdev_create_notification(struct wlan_objmgr_vdev *vdev, void *arg)
|
|
|
pkt_capture_err("Failed to open mon thread");
|
|
|
goto open_mon_thread_fail;
|
|
|
}
|
|
|
+ qdf_spinlock_create(&vdev_priv->lock_q);
|
|
|
+ qdf_list_create(&vdev_priv->ppdu_stats_q, PPDU_STATS_Q_MAX_SIZE);
|
|
|
+
|
|
|
return status;
|
|
|
|
|
|
open_mon_thread_fail:
|
|
@@ -784,6 +860,8 @@ QDF_STATUS
|
|
|
pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg)
|
|
|
{
|
|
|
struct pkt_capture_vdev_priv *vdev_priv;
|
|
|
+ struct pkt_capture_ppdu_stats_q_node *stats_node;
|
|
|
+ qdf_list_node_t *node;
|
|
|
QDF_STATUS status;
|
|
|
|
|
|
if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
|
|
@@ -796,6 +874,15 @@ pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg)
|
|
|
return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
|
|
|
+ while (qdf_list_remove_front(&vdev_priv->ppdu_stats_q, &node)
|
|
|
+ == QDF_STATUS_SUCCESS) {
|
|
|
+ stats_node = qdf_container_of(
|
|
|
+ node, struct pkt_capture_ppdu_stats_q_node, node);
|
|
|
+ qdf_mem_free(stats_node);
|
|
|
+ }
|
|
|
+ qdf_list_destroy(&vdev_priv->ppdu_stats_q);
|
|
|
+ qdf_spinlock_destroy(&vdev_priv->lock_q);
|
|
|
+
|
|
|
status = wlan_objmgr_vdev_component_obj_detach(
|
|
|
vdev,
|
|
|
WLAN_UMAC_COMP_PKT_CAPTURE,
|
|
@@ -806,6 +893,7 @@ pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg)
|
|
|
pkt_capture_close_mon_thread(vdev_priv->mon_ctx);
|
|
|
pkt_capture_mon_context_destroy(vdev_priv);
|
|
|
pkt_capture_callback_ctx_destroy(vdev_priv);
|
|
|
+
|
|
|
qdf_mem_free(vdev_priv);
|
|
|
gp_pkt_capture_vdev = NULL;
|
|
|
return status;
|