فهرست منبع

qcacmn: Add target interface support for Agile DFS feature

Add target interface support for Agile DFS feature. This includes:
	1)target interface to send agile dfs request command
	2)target interace to send  off-channel cac abort command

Change-Id: Ica0cecd08dc1cd90fe71a618afe749b50dc1cb6d
CRs-Fixed: 2385536
Shaakir Mohamed 6 سال پیش
والد
کامیت
14ac61de4d

+ 34 - 1
target_if/dfs/inc/target_if_dfs_full_offload.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -60,6 +60,39 @@ static QDF_STATUS target_process_bang_radar_cmd(struct wlan_objmgr_pdev *pdev,
 }
 #endif
 
+#if defined(QCA_SUPPORT_AGILE_DFS)
+/**
+ * target_send_ocac_abort_cmd() - Send off channel CAC abort to target for
+ * to cancel current offchannel CAC
+ * @pdev: Pointer to DFS pdev object.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_send_ocac_abort_cmd(struct wlan_objmgr_pdev *pdev);
+/**
+ * target_send_agile_ch_cfg_cmd() - Send agile channel to target for
+ * off channel precac.
+ * @pdev: Pointer to DFS pdev object.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev,
+					uint8_t *ch_freq);
+#else
+static inline QDF_STATUS
+target_send_ocac_abort_cmd(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev,
+			     uint8_t *ch_freq)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
 /**
  * target_send_usenol_pdev_param - send usenol pdev param to FW.

+ 5 - 1
target_if/dfs/src/target_if_dfs.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -366,6 +366,10 @@ QDF_STATUS target_if_register_dfs_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 
 	dfs_tx_ops->dfs_process_emulate_bang_radar_cmd =
 				&target_process_bang_radar_cmd;
+	dfs_tx_ops->dfs_agile_ch_cfg_cmd =
+				&target_send_agile_ch_cfg_cmd;
+	dfs_tx_ops->dfs_ocac_abort_cmd =
+				&target_send_ocac_abort_cmd;
 	dfs_tx_ops->dfs_is_pdev_5ghz = &target_if_dfs_is_pdev_5ghz;
 	dfs_tx_ops->dfs_send_offload_enable_cmd =
 		&target_send_dfs_offload_enable_cmd;

+ 203 - 2
target_if/dfs/src/target_if_dfs_full_offload.c

@@ -28,7 +28,13 @@
 #include <init_deinit_lmac.h>
 #include <wlan_module_ids.h>
 #include <target_if_dfs_full_offload.h>
+#include <wlan_dfs_tgt_api.h>
+#include <wlan_objmgr_pdev_obj.h>
 
+#if defined(QCA_SUPPORT_AGILE_DFS)
+#include <wlan_mlme_dispatcher.h>
+#define QUICK_OCAC_MODE 0
+#endif
 /**
  * target_if_dfs_cac_complete_event_handler() - CAC complete indication.
  * @scn: scn handle.
@@ -99,6 +105,86 @@ static int target_if_dfs_cac_complete_event_handler(
 	return ret;
 }
 
+#if defined(QCA_SUPPORT_AGILE_DFS)
+/**
+ * target_if_dfs_ocac_complete_event_handler() - Off Channel CAC complete
+ *						 indication.
+ * @scn: scn handle.
+ * @data: Pointer to data buffer.
+ * @datalen: data length.
+ *
+ * Return: 0 on successful indication.
+ */
+static int target_if_dfs_ocac_complete_event_handler(
+		ol_scn_t scn, uint8_t *data, uint32_t datalen)
+{
+	struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev;
+	struct vdev_adfs_complete_status ocac_status;
+	int ret = 0;
+	struct wmi_unified *wmi_handle;
+
+	if (!scn || !data) {
+		target_if_err("scn: %pK, data: %pK", scn, data);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return -EINVAL;
+	}
+
+	dfs_rx_ops = target_if_dfs_get_rx_ops(psoc);
+	if (!dfs_rx_ops || !dfs_rx_ops->dfs_dfs_ocac_complete_ind) {
+		target_if_err("Invalid dfs_rx_ops: %pK", dfs_rx_ops);
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid WMI handle");
+		return -EINVAL;
+	}
+
+	if (wmi_extract_dfs_ocac_complete_event(wmi_handle,
+						data,
+						&ocac_status)
+						!= QDF_STATUS_SUCCESS) {
+		target_if_err("failed to extract off channel cac complete event");
+		return -EFAULT;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+						    ocac_status.vdev_id,
+						    WLAN_DFS_ID);
+	if (!vdev) {
+		target_if_err("null vdev");
+		return -EINVAL;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		target_if_err("null pdev");
+		ret = -EINVAL;
+		goto free_vdevref;
+	}
+
+	if (!ret && (QDF_STATUS_SUCCESS !=
+	    dfs_rx_ops->dfs_dfs_ocac_complete_ind(pdev, &ocac_status))) {
+		target_if_err("dfs_dfs_ocac_complete_ind failed");
+		ret = -EINVAL;
+	}
+
+free_vdevref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
+
+	return ret;
+}
+#endif
+
 /**
  * target_if_dfs_radar_detection_event_handler() - Indicate RADAR detection and
  * process RADAR detection.
@@ -166,10 +252,32 @@ static int target_if_dfs_radar_detection_event_handler(
 	return ret;
 }
 
+/**
+ * target_if_dfs_reg_ocac_event() - registers dfs off channel event
+ * for full offload.
+ * @psoc: Pointer to psoc object.
+ *
+ * Return: 0 on successful registration.
+ */
+#if defined(QCA_SUPPORT_AGILE_DFS)
+static int target_if_dfs_reg_ocac_event(struct wlan_objmgr_psoc *psoc)
+{
+	return wmi_unified_register_event(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_vdev_ocac_complete_event_id,
+			target_if_dfs_ocac_complete_event_handler);
+}
+#else
+static int target_if_dfs_reg_ocac_event(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+#endif
+
 QDF_STATUS target_if_dfs_reg_offload_events(
 		struct wlan_objmgr_psoc *psoc)
 {
-	int ret1, ret2;
+	int ret1, ret2, ret3;
 
 	ret1 = wmi_unified_register_event(
 			get_wmi_unified_hdl_from_psoc(psoc),
@@ -183,12 +291,104 @@ QDF_STATUS target_if_dfs_reg_offload_events(
 			target_if_dfs_cac_complete_event_handler);
 	target_if_debug("wmi_dfs_cac_complete_id ret=%d", ret2);
 
-	if (ret1 || ret2)
+	ret3 = target_if_dfs_reg_ocac_event(psoc);
+	target_if_debug("wmi_vdev_ocac_complete_event_id ret=%d", ret3);
+
+	if (ret1 || ret2 || ret3)
 		return QDF_STATUS_E_FAILURE;
 	else
 		return QDF_STATUS_SUCCESS;
 }
 
+#if defined(QCA_SUPPORT_AGILE_DFS)
+QDF_STATUS target_send_ocac_abort_cmd(struct wlan_objmgr_pdev *pdev)
+{
+	wmi_unified_t wmi_handle;
+	struct vdev_adfs_abort_params param;
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+
+	if (!pdev) {
+		target_if_err("null pdev");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_DFS_ID);
+
+	if (!vdev) {
+		target_if_err("null vdev");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
+	if (!wmi_handle) {
+		target_if_err("null wmi_handle");
+		status = QDF_STATUS_E_FAILURE;
+		goto free_vdevref;
+	}
+
+	qdf_mem_set(&param, sizeof(param), 0);
+	param.vdev_id = wlan_vdev_get_id(vdev);
+	utils_dfs_cancel_precac_timer(pdev);
+
+	status = wmi_unified_send_vdev_adfs_ocac_abort_cmd(wmi_handle, &param);
+	if (QDF_IS_STATUS_ERROR(status))
+		target_if_err("dfs: unit_test_cmd send failed %d", status);
+
+free_vdevref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
+
+	return status;
+}
+
+QDF_STATUS target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev,
+					uint8_t *ch_freq)
+{
+	wmi_unified_t wmi_handle;
+	struct vdev_adfs_ch_cfg_params param;
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+
+	if (!pdev) {
+		target_if_err("null pdev");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_DFS_ID);
+
+	if (!vdev) {
+		target_if_err("null vdev");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
+	if (!wmi_handle) {
+		target_if_err("null wmi_handle");
+		status = QDF_STATUS_E_FAILURE;
+		goto free_vdevref;
+	}
+
+	qdf_mem_set(&param, sizeof(param), 0);
+	param.vdev_id = wlan_vdev_get_id(vdev);
+	param.ocac_mode = QUICK_OCAC_MODE;
+	param.min_duration_ms = 60000;
+	param.max_duration_ms = 0;
+	param.chan_freq = *ch_freq;
+	param.chan_width = wlan_vdev_get_ch_width(vdev);
+	param.center_freq = *ch_freq;
+
+	status = wmi_unified_send_vdev_adfs_ch_cfg_cmd(wmi_handle, &param);
+	if (QDF_IS_STATUS_ERROR(status))
+		target_if_err("dfs: unit_test_cmd send failed %d", status);
+
+free_vdevref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
+
+	return status;
+}
+#endif
+
+#if (defined(CONFIG_MCL) || (QCA_WIFI_QCA8074))
 QDF_STATUS target_process_bang_radar_cmd(
 		struct wlan_objmgr_pdev *pdev,
 		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
@@ -234,6 +434,7 @@ QDF_STATUS target_process_bang_radar_cmd(
 		target_if_err("dfs: unit_test_cmd send failed %d", status);
 	return status;
 }
+#endif
 
 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
 QDF_STATUS target_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,

+ 5 - 0
target_if/init_deinit/src/init_event_handler.c

@@ -400,6 +400,11 @@ static int init_deinit_ready_event_handler(ol_scn_t scn_handle,
 		return -EINVAL;
 	}
 
+	if (!ready_ev.agile_capability)
+		target_if_err("agile capability disabled in HW");
+	else
+		info->wlan_res_cfg.agile_capability = ready_ev.agile_capability;
+
 	if ((ready_ev.num_total_peer != 0) &&
 	    (info->wlan_res_cfg.num_peers != ready_ev.num_total_peer)) {
 		/* FW allocated number of peers is different than host