Przeglądaj źródła

qcacld-3.0: Add WMI EVENT handler for offloaded mgmt data

Register event handler for WMI_VDEV_MGMT_OFFLOAD_DATA_EVENTID
to handle offloaded management data.

Change-Id: I340d79b08f8453425092f4582059f184e0dfb625
CRs-Fixed: 2619319
Dundi Raviteja 5 lat temu
rodzic
commit
9465ea0c01

+ 17 - 2
components/target_if/pkt_capture/inc/target_if_pkt_capture.h

@@ -25,8 +25,12 @@
 #ifndef _TARGET_IF_PKT_CAPTURE_H_
 #define _TARGET_IF_PKT_CAPTURE_H_
 
-#include <qdf_types.h>
-#include "wlan_pkt_capture_public_structs.h"
+#include <wlan_pkt_capture_main.h>
+#include <wlan_pkt_capture_ucfg_api.h>
+#include <wlan_pkt_capture_mgmt_txrx.h>
+#include <wlan_pkt_capture_public_structs.h>
+#include <target_if.h>
+#include <linux/ieee80211.h>
 
 /**
  * target_if_set_packet_capture_mode() - set packet capture mode
@@ -39,4 +43,15 @@
 QDF_STATUS target_if_set_packet_capture_mode(struct wlan_objmgr_psoc *psoc,
 					     uint8_t vdev_id,
 					     enum pkt_capture_mode mode);
+
+/**
+ * target_if_register_mgmt_data_offload_event() - Register offload event handler
+ * @psoc: wlan psoc object
+ *
+ * Register mgmt data offload event handler
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+target_if_register_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc);
 #endif /* _TARGET_IF_PKT_CAPTURE_H_ */

+ 122 - 2
components/target_if/pkt_capture/src/target_if_pkt_capture.c

@@ -22,8 +22,6 @@
  * in target_if internally.
  */
 
-#include <wlan_pkt_capture_main.h>
-#include <wlan_pkt_capture_ucfg_api.h>
 #include <target_if_pkt_capture.h>
 #include <wmi_unified_api.h>
 #include <target_if.h>
@@ -59,3 +57,125 @@ QDF_STATUS target_if_set_packet_capture_mode(struct wlan_objmgr_psoc *psoc,
 	}
 	return status;
 }
+
+/**
+ * target_if_mgmt_offload_data_event_handler() - offload event handler
+ * @handle: scn handle
+ * @data: mgmt data
+ * @data_len: data length
+ *
+ * Process management offload frame.
+ *
+ * Return: 0 for success or error code
+ */
+static int
+target_if_mgmt_offload_data_event_handler(void *handle, uint8_t *data,
+					  uint32_t data_len)
+{
+	static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1;
+	struct mgmt_offload_event_params params;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	QDF_STATUS status;
+	qdf_nbuf_t wbuf;
+
+	psoc = target_if_get_psoc_from_scn_hdl(handle);
+	if (!psoc) {
+		pkt_capture_err("psoc is NULL");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid WMI handle");
+		return -EINVAL;
+	}
+
+	pdev = target_if_get_pdev_from_scn_hdl(handle);
+	if (!pdev) {
+		pkt_capture_err("pdev is NULL");
+		return -EINVAL;
+	}
+
+	if (!(ucfg_pkt_capture_get_pktcap_mode(psoc) &
+	      PKT_CAPTURE_MODE_MGMT_ONLY))
+		return -EINVAL;
+
+	status = wmi_unified_extract_vdev_mgmt_offload_event(wmi_handle, data,
+							     &params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pkt_capture_err("Extract mgmt offload event failed");
+		return -EINVAL;
+	}
+
+	if (!params.buf) {
+		pkt_capture_err("Mgmt offload buf is NULL");
+		return -EINVAL;
+	}
+
+	if (params.buf_len < sizeof(struct ieee80211_hdr_3addr) ||
+	    params.buf_len > data_len) {
+		limit_prints_invalid_len++;
+		if (limit_prints_invalid_len == RATE_LIMIT) {
+			pkt_capture_debug(
+			"Invalid mgmt packet, data_len %u, params.buf_len %u",
+			data_len, params.buf_len);
+			limit_prints_invalid_len = 0;
+		}
+		return -EINVAL;
+	}
+
+	wbuf = qdf_nbuf_alloc(NULL,
+			      roundup(params.buf_len + RESERVE_BYTES, 4),
+			      RESERVE_BYTES, 4, false);
+	if (!wbuf) {
+		pkt_capture_err("Failed to allocate wbuf for mgmt pkt len(%u)",
+				params.buf_len);
+		return -ENOMEM;
+	}
+
+	qdf_nbuf_put_tail(wbuf, params.buf_len);
+	qdf_nbuf_set_protocol(wbuf, ETH_P_CONTROL);
+	qdf_mem_copy(qdf_nbuf_data(wbuf), params.buf, params.buf_len);
+
+	status = params.tx_status;
+	if (QDF_STATUS_SUCCESS !=
+		ucfg_pkt_capture_process_mgmt_tx_data(pdev, &params,
+						      wbuf, status))
+		qdf_nbuf_free(wbuf);
+
+	return 0;
+}
+
+QDF_STATUS
+target_if_register_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle;
+
+	PKT_CAPTURE_ENTER();
+
+	if (!psoc) {
+		pkt_capture_err("psoc got NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+
+	if (ucfg_pkt_capture_get_mode(psoc) &&
+	    wmi_service_enabled(wmi_handle,
+				wmi_service_packet_capture_support)) {
+		uint8_t status;
+
+		status = wmi_unified_register_event_handler(
+				wmi_handle,
+				wmi_mgmt_offload_data_event_id,
+				target_if_mgmt_offload_data_event_handler,
+				WMI_RX_WORK_CTX);
+		if (status) {
+			pkt_capture_err("Failed to register MGMT offload handler");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	PKT_CAPTURE_ENTER();
+	return QDF_STATUS_SUCCESS;
+}