Browse Source

qcacld-3.0: Register tx and rx ops for packet capture component

Register tx and rx ops to send packet capture mode command and
to receive mgmt offload handler for packet capture component.

Change-Id: I70da00feff29399b98c5916eec17e26b62285db3
CRs-Fixed: 2619321
Vulupala Shashank Reddy 5 years ago
parent
commit
4affa222c9

+ 29 - 1
components/pkt_capture/core/inc/wlan_pkt_capture_priv.h

@@ -31,6 +31,28 @@
 #include "wlan_pkt_capture_public_structs.h"
 #include "wlan_pkt_capture_mon_thread.h"
 
+/**
+ * struct wlan_pkt_capture_tx_ops - structure of tx operation function
+ * pointers for packet capture component
+ * @pkt_capture_send_mode: send packet capture mode
+ *
+ */
+struct wlan_pkt_capture_tx_ops {
+	QDF_STATUS (*pkt_capture_send_mode)(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id,
+					    enum pkt_capture_mode mode);
+};
+
+/**
+ * struct wlan_pkt_capture_rx_ops - structure of rx operation function
+ * pointers for packet capture component
+ * @pkt_capture_register_mgmt_data_offload_event: register mgmt offload event
+ */
+struct wlan_pkt_capture_rx_ops {
+	QDF_STATUS (*pkt_capture_register_mgmt_data_offload_event)
+					(struct wlan_objmgr_psoc *psoc);
+};
+
 /**
  * struct pkt_capture_cfg - packet capture cfg to store ini values
  * @pkt_capture_mode: packet capture mode
@@ -54,13 +76,19 @@ struct pkt_capture_cb_context {
 /**
  * struct pkt_capture_vdev_priv - Private object to be stored in vdev
  * @vdev: pointer to vdev object
- * @pkt_capture_mon_ctx: pointer to packet capture mon context
+ * @mon_ctx: pointer to packet capture mon context
  * @cb_ctx: pointer to packet capture mon callback context
+ * @rx_ops: rx ops
+ * @tx_ops: tx ops
+ * @is_ops_registered: is tx and rx ops registered
  */
 struct pkt_capture_vdev_priv {
 	struct wlan_objmgr_vdev *vdev;
 	struct pkt_capture_mon_context *mon_ctx;
 	struct pkt_capture_cb_context *cb_ctx;
+	struct wlan_pkt_capture_rx_ops rx_ops;
+	struct wlan_pkt_capture_tx_ops tx_ops;
+	bool is_ops_registered;
 };
 
 /**

+ 15 - 0
components/pkt_capture/core/src/wlan_pkt_capture_main.c

@@ -25,6 +25,7 @@
 #include "cfg_ucfg_api.h"
 #include "wlan_pkt_capture_mon_thread.h"
 #include "wlan_pkt_capture_mgmt_txrx.h"
+#include "target_if_pkt_capture.h"
 
 enum pkt_capture_mode pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc)
 {
@@ -72,6 +73,9 @@ pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev,
 		return status;
 	}
 
+	target_if_pkt_capture_register_tx_ops(&vdev_priv->tx_ops);
+	target_if_pkt_capture_register_rx_ops(&vdev_priv->rx_ops);
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -141,6 +145,9 @@ pkt_capture_get_pktcap_mode(struct wlan_objmgr_psoc *psoc)
 		return 0;
 	}
 
+	if (!pkt_capture_get_mode(psoc))
+		return 0;
+
 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc,
 							QDF_STA_MODE,
 							WLAN_PKT_CAPTURE_ID);
@@ -271,6 +278,10 @@ pkt_capture_vdev_create_notification(struct wlan_objmgr_vdev *vdev, void *arg)
 	struct pkt_capture_vdev_priv *vdev_priv;
 	QDF_STATUS status;
 
+	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
+	    !pkt_capture_get_mode(wlan_vdev_get_psoc(vdev)))
+		return QDF_STATUS_SUCCESS;
+
 	vdev_priv = qdf_mem_malloc(sizeof(*vdev_priv));
 	if (!vdev_priv)
 		return QDF_STATUS_E_NOMEM;
@@ -334,6 +345,10 @@ pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg)
 	struct pkt_capture_vdev_priv *vdev_priv;
 	QDF_STATUS status;
 
+	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
+	    !pkt_capture_get_mode(wlan_vdev_get_psoc(vdev)))
+		return QDF_STATUS_SUCCESS;
+
 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
 	if (!vdev_priv) {
 		pkt_capture_err("vdev priv is NULL");

+ 8 - 0
components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h

@@ -147,6 +147,14 @@ ucfg_pkt_capture_mgmt_tx_completion(
 				uint32_t desc_id,
 				uint32_t status,
 				struct mgmt_offload_event_params *params);
+
+/**
+ * ucfg_pkt_capture_enable_ops - Enable packet capture tx and rx ops handlers
+ * @wlan_objmgr_vdev: wlan vdev object manager
+ *
+ * Return: 0 on success, -EINVAL on failure
+ */
+int ucfg_pkt_capture_enable_ops(struct wlan_objmgr_vdev *vdev);
 #else
 static inline
 QDF_STATUS ucfg_pkt_capture_init(void)

+ 49 - 0
components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c

@@ -25,6 +25,7 @@
 #include "wlan_pkt_capture_ucfg_api.h"
 #include "wlan_pkt_capture_mon_thread.h"
 #include "wlan_pkt_capture_mgmt_txrx.h"
+#include "target_if_pkt_capture.h"
 
 enum pkt_capture_mode ucfg_pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc)
 {
@@ -222,3 +223,51 @@ ucfg_pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev,
 {
 	pkt_capture_mgmt_tx_completion(pdev, desc_id, status, params);
 }
+
+int ucfg_pkt_capture_enable_ops(struct wlan_objmgr_vdev *vdev)
+{
+	struct pkt_capture_vdev_priv *vdev_priv;
+	struct wlan_pkt_capture_rx_ops *rx_ops;
+	struct wlan_pkt_capture_tx_ops *tx_ops;
+	struct wlan_objmgr_psoc *psoc;
+	enum pkt_capture_mode mode;
+	QDF_STATUS status;
+	int ret;
+
+	if (!vdev)
+		return -EINVAL;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return -EINVAL;
+
+	vdev_priv = pkt_capture_vdev_get_priv(vdev);
+	if (!vdev_priv) {
+		pkt_capture_err("vdev_priv got NULL");
+		return -EINVAL;
+	}
+
+	if (vdev_priv->is_ops_registered)
+		return 0;
+
+	rx_ops = &vdev_priv->rx_ops;
+	tx_ops = &vdev_priv->tx_ops;
+
+	status = rx_ops->pkt_capture_register_mgmt_data_offload_event(psoc);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pkt_capture_err("Unable to register mgmt offload handler");
+		return -EINVAL;
+	}
+
+	mode = ucfg_pkt_capture_get_mode(psoc);
+	ret = tx_ops->pkt_capture_send_mode(psoc,
+					    vdev->vdev_objmgr.vdev_id,
+					    mode);
+	if (ret) {
+		pkt_capture_err("Unable to send packet capture mode to fw");
+		return ret;
+	}
+	vdev_priv->is_ops_registered = true;
+
+	return 0;
+}

+ 10 - 16
components/target_if/pkt_capture/inc/target_if_pkt_capture.h

@@ -33,25 +33,19 @@
 #include <linux/ieee80211.h>
 
 /**
- * target_if_set_packet_capture_mode() - set packet capture mode
- * @psoc: pointer to psoc object
- * @vdev_id: vdev id
- * @mode: mode to set
- *
- * Return: QDF_STATUS
+ * target_if_pkt_capture_register_rx_ops() - Register packet capture RX ops
+ * @rx_ops: packet capture component reception ops
+ * Return: None
  */
-QDF_STATUS target_if_set_packet_capture_mode(struct wlan_objmgr_psoc *psoc,
-					     uint8_t vdev_id,
-					     enum pkt_capture_mode mode);
+void
+target_if_pkt_capture_register_rx_ops(struct wlan_pkt_capture_rx_ops *rx_ops);
 
 /**
- * target_if_register_mgmt_data_offload_event() - Register offload event handler
- * @psoc: wlan psoc object
- *
- * Register mgmt data offload event handler
+ * target_if_pkt_capture_register_tx_ops() - Register packet capture TX ops
+ * @tx_ops: pkt capture component transmit ops
  *
- * Return: QDF_STATUS
+ * Return: None
  */
-QDF_STATUS
-target_if_register_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc);
+void target_if_pkt_capture_register_tx_ops(struct wlan_pkt_capture_tx_ops
+					   *tx_ops);
 #endif /* _TARGET_IF_PKT_CAPTURE_H_ */

+ 43 - 4
components/target_if/pkt_capture/src/target_if_pkt_capture.c

@@ -27,9 +27,18 @@
 #include <target_if.h>
 #include <init_deinit_lmac.h>
 
-QDF_STATUS target_if_set_packet_capture_mode(struct wlan_objmgr_psoc *psoc,
-					     uint8_t vdev_id,
-					     enum pkt_capture_mode mode)
+/**
+ * target_if_set_packet_capture_mode() - set packet capture mode
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id
+ * @mode: mode to set
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+target_if_set_packet_capture_mode(struct wlan_objmgr_psoc *psoc,
+				  uint8_t vdev_id,
+				  enum pkt_capture_mode mode)
 {
 	wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
@@ -148,7 +157,14 @@ target_if_mgmt_offload_data_event_handler(void *handle, uint8_t *data,
 	return 0;
 }
 
-QDF_STATUS
+/**
+ * target_if_register_mgmt_data_offload_event() - Register mgmt data offload
+ * event handler
+ * @psoc: wlan psoc object
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
 target_if_register_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc)
 {
 	wmi_unified_t wmi_handle;
@@ -179,3 +195,26 @@ target_if_register_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc)
 	PKT_CAPTURE_ENTER();
 	return QDF_STATUS_SUCCESS;
 }
+
+void
+target_if_pkt_capture_register_rx_ops(struct wlan_pkt_capture_rx_ops *rx_ops)
+{
+	if (!rx_ops) {
+		target_if_err("packet capture rx_ops is null");
+		return;
+	}
+
+	rx_ops->pkt_capture_register_mgmt_data_offload_event =
+				target_if_register_mgmt_data_offload_event;
+}
+
+void
+target_if_pkt_capture_register_tx_ops(struct wlan_pkt_capture_tx_ops *tx_ops)
+{
+	if (!tx_ops) {
+		target_if_err("packet capture tx_ops is null");
+		return;
+	}
+
+	tx_ops->pkt_capture_send_mode = target_if_set_packet_capture_mode;
+}

+ 36 - 9
core/hdd/src/wlan_hdd_main.c

@@ -2570,6 +2570,7 @@ static int __hdd_pktcapture_open(struct net_device *dev)
 	int ret;
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_adapter *sta_adapter;
 
 	hdd_enter_dev(dev);
 
@@ -2577,11 +2578,27 @@ static int __hdd_pktcapture_open(struct net_device *dev)
 	if (ret)
 		return ret;
 
+	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
+	if (!sta_adapter) {
+		hdd_err("No station interface found");
+		return -EINVAL;
+	}
+
+	adapter->vdev = hdd_objmgr_get_vdev(sta_adapter);
+	if (!adapter->vdev)
+		return -EINVAL;
+
 	hdd_mon_mode_ether_setup(dev);
 
 	ret = ucfg_pkt_capture_register_callbacks(adapter->vdev,
 						  hdd_mon_rx_packet_cbk,
 						  adapter);
+	if (ret) {
+		hdd_objmgr_put_vdev(sta_adapter->vdev);
+		return ret;
+	}
+
+	ret = ucfg_pkt_capture_enable_ops(adapter->vdev);
 	if (!ret)
 		set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
 
@@ -3810,8 +3827,11 @@ static int __hdd_stop(struct net_device *dev)
 	if (adapter->device_mode == QDF_STA_MODE)
 		hdd_lpass_notify_stop(hdd_ctx);
 
-	if (wlan_hdd_is_session_type_monitor(adapter->device_mode))
+	if (wlan_hdd_is_session_type_monitor(adapter->device_mode)) {
 		ucfg_pkt_capture_deregister_callbacks(adapter->vdev);
+		hdd_objmgr_put_vdev(adapter->vdev);
+		adapter->vdev = NULL;
+	}
 
 	/*
 	 * NAN data interface is different in some sense. The traffic on NDI is
@@ -6093,6 +6113,16 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
 		break;
 
 	case QDF_MONITOR_MODE:
+		if (wlan_hdd_is_session_type_monitor(QDF_MONITOR_MODE)) {
+			adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
+
+			if (adapter->vdev) {
+				ucfg_pkt_capture_deregister_callbacks(
+						adapter->vdev);
+				hdd_objmgr_put_vdev(adapter->vdev);
+				adapter->vdev = NULL;
+			}
+		}
 		wlan_hdd_scan_abort(adapter);
 		hdd_deregister_hl_netdev_fc_timer(adapter);
 		hdd_deregister_tx_flow_control(adapter);
@@ -7980,7 +8010,6 @@ static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
 void hdd_wlan_exit(struct hdd_context *hdd_ctx)
 {
 	struct wiphy *wiphy = hdd_ctx->wiphy;
-	struct hdd_adapter *adapter;
 
 	hdd_enter();
 
@@ -8020,13 +8049,6 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx)
 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
 		hdd_abort_sched_scan_all_adapters(hdd_ctx);
 
-		if (wlan_hdd_is_session_type_monitor(QDF_MONITOR_MODE)) {
-			adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
-			if (adapter)
-				ucfg_pkt_capture_deregister_callbacks(
-						adapter->vdev);
-		}
-
 		hdd_stop_all_adapters(hdd_ctx);
 		hdd_deinit_all_adapters(hdd_ctx, false);
 	}
@@ -16497,6 +16519,11 @@ void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx,
 	hdd_stop_adapter(hdd_ctx, adapter);
 	hdd_close_adapter(hdd_ctx, adapter, true);
 
+	if (adapter->vdev) {
+		hdd_objmgr_put_vdev(adapter->vdev);
+		adapter->vdev = NULL;
+	}
+
 	hdd_open_p2p_interface(hdd_ctx);
 }