Browse Source

qcacmn: Have separate macros for DA/PO/FO to reduce the code size

Since, an AP may have any combinations of DA,PO, and FO chips on it,
having support for all chips always is redundant. Therefore, enable the
chip specific code as and when required.
DA:- Direct attach
PO:- Partial offload
FO:- Full offload
WLAN_DFS_DIRECT_ATTACH    :- enable/disable DA specific DFS code.
WLAN_DFS_PARTIAL_OFFLOAD  :- enable/disable PO specific DFS code.
WLAN_DFS_FULL_OFFLOAD     :- enable/disable FO specific DFS code.

Change-Id: I498ac1f8cd1d6423032d7b3b8c233656c5f0bf22
CRs-Fixed: 2199819
Abhijit Pradhan 7 years ago
parent
commit
ed8c9d3bc8

+ 14 - 1
target_if/dfs/inc/target_if_dfs.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -31,3 +31,16 @@
  * Return: QDF_STATUS
  */
 QDF_STATUS target_if_register_dfs_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
+
+/**
+ * target_if_dfs_get_rx_ops() - Get dfs_rx_ops
+ * @psoc: psoc handle.
+ *
+ * Return: dfs_rx_ops.
+ */
+static inline struct wlan_lmac_if_dfs_rx_ops *
+target_if_dfs_get_rx_ops(struct wlan_objmgr_psoc *psoc)
+{
+	return &psoc->soc_cb.rx_ops.dfs_rx_ops;
+}
+

+ 64 - 0
target_if/dfs/inc/target_if_dfs_full_offload.h

@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+ /**
+ * DOC: target_if_dfs_full_offload.h
+ * This file contains dfs target interface for full-offload.
+ */
+
+#ifndef _TARGET_IF_DFS_FULL_OFFLOAD_H_
+#define _TARGET_IF_DFS_FULL_OFFLOAD_H_
+
+/**
+ * target_if_dfs_reg_offload_events() - registers dfs events for full offload.
+ * @psoc: Pointer to psoc object.
+ *
+ * Return: QDF_STATUS
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD)
+QDF_STATUS target_if_dfs_reg_offload_events(struct wlan_objmgr_psoc *psoc);
+#else
+static QDF_STATUS
+target_if_dfs_reg_offload_events(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * target_process_bang_radar_cmd() - fill unit test args and send bangradar
+ * command to firmware.
+ * @pdev: Pointer to DFS pdev object.
+ * @dfs_unit_test: Pointer to dfs_unit_test structure.
+ *
+ * Return: QDF_STATUS
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD)
+QDF_STATUS target_process_bang_radar_cmd(struct wlan_objmgr_pdev *pdev,
+		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test);
+#else
+static QDF_STATUS target_process_bang_radar_cmd(struct wlan_objmgr_pdev *pdev,
+		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#endif /* _TARGET_IF_DFS_FULL_OFFLOAD_H_ */
+

+ 61 - 0
target_if/dfs/inc/target_if_dfs_partial_offload.h

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+ /**
+ * DOC: target_if_dfs_partial_offload.h
+ * This file contains dfs target interface for partial offload.
+ */
+
+#ifndef _TARGET_IF_DFS_PARTIAL_OFFLOAD_H_
+#define _TARGET_IF_DFS_PARTIAL_OFFLOAD_H_
+
+/**
+ * target_if_dfs_reg_phyerr_events() - register phyerror events.
+ * @psoc: Pointer to psoc object.
+ *
+ * Return: QDF_STATUS
+ */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
+QDF_STATUS target_if_dfs_reg_phyerr_events(struct wlan_objmgr_psoc *psoc);
+#else
+static QDF_STATUS
+target_if_dfs_reg_phyerr_events(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * target_if_dfs_get_caps() - get dfs caps.
+ * @pdev: Pointer to DFS pdev object.
+ * @dfs_caps: Pointer to dfs_caps structure.
+ *
+ * Return: QDF_STATUS
+ */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
+QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev,
+		struct wlan_dfs_caps *dfs_caps);
+#else
+static QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev,
+		struct wlan_dfs_caps *dfs_caps)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#endif /* _TARGET_IF_DFS_PARTIAL_OFFLOAD_H_ */

+ 2 - 249
target_if/dfs/src/target_if_dfs.c

@@ -37,12 +37,8 @@
 #include "target_type.h"
 #include <init_deinit_ucfg.h>
 #include <wlan_reg_ucfg_api.h>
-
-static inline struct wlan_lmac_if_dfs_rx_ops *
-target_if_dfs_get_rx_ops(struct wlan_objmgr_psoc *psoc)
-{
-	return &psoc->soc_cb.rx_ops.dfs_rx_ops;
-}
+#include <target_if_dfs_full_offload.h>
+#include <target_if_dfs_partial_offload.h>
 
 /**
  * target_if_is_dfs_3() - Is dfs3 support or not
@@ -68,138 +64,6 @@ static bool target_if_is_dfs_3(uint32_t target_type)
 	return is_dfs_3;
 }
 
-static int target_if_dfs_cac_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;
-	int ret = 0;
-	uint32_t vdev_id = 0;
-
-	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_cac_complete_ind) {
-		target_if_err("Invalid dfs_rx_ops: %pK", dfs_rx_ops);
-		return -EINVAL;
-	}
-
-	if (wmi_extract_dfs_cac_complete_event(GET_WMI_HDL_FROM_PSOC(psoc),
-			data, &vdev_id, datalen) != QDF_STATUS_SUCCESS) {
-		target_if_err("failed to extract cac complete event");
-		return -EFAULT;
-	}
-
-	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 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;
-	}
-
-	if (!ret && (QDF_STATUS_SUCCESS !=
-	    dfs_rx_ops->dfs_dfs_cac_complete_ind(pdev, vdev_id))) {
-		target_if_err("dfs_dfs_cac_complete_ind failed");
-		ret = -EINVAL;
-	}
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
-
-	return ret;
-}
-
-static int target_if_dfs_radar_detection_event_handler(
-		ol_scn_t scn, uint8_t *data, uint32_t datalen)
-{
-	struct radar_found_info radar;
-	struct wlan_objmgr_psoc *psoc = NULL;
-	struct wlan_objmgr_pdev *pdev = NULL;
-	struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops;
-	int ret = 0;
-
-	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_process_radar_ind) {
-		target_if_err("Invalid dfs_rx_ops: %pK", dfs_rx_ops);
-		return -EINVAL;
-	}
-
-	if (wmi_extract_dfs_radar_detection_event(GET_WMI_HDL_FROM_PSOC(psoc),
-			data, &radar, datalen) != QDF_STATUS_SUCCESS) {
-		target_if_err("failed to extract cac complete event");
-		return -EFAULT;
-	}
-
-	pdev = wlan_objmgr_get_pdev_by_id(psoc, radar.pdev_id, WLAN_DFS_ID);
-	if (!pdev) {
-		target_if_err("null pdev");
-		return -EINVAL;
-	}
-
-	if (QDF_STATUS_SUCCESS != dfs_rx_ops->dfs_process_radar_ind(pdev,
-				&radar)) {
-		target_if_err("dfs_process_radar_ind failed pdev_id=%d",
-			      radar.pdev_id);
-		ret = -EINVAL;
-	}
-
-	wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
-
-	return ret;
-}
-
-static QDF_STATUS target_if_dfs_reg_offload_events(
-		struct wlan_objmgr_psoc *psoc)
-{
-	int ret1, ret2;
-
-	ret1 = wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc),
-			wmi_dfs_radar_detection_event_id,
-			target_if_dfs_radar_detection_event_handler);
-	target_if_debug("wmi_dfs_radar_detection_event_id ret=%d", ret1);
-
-	ret2 = wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc),
-			wmi_dfs_cac_complete_id,
-			target_if_dfs_cac_complete_event_handler);
-	target_if_debug("wmi_dfs_cac_complete_id ret=%d", ret2);
-
-	if (ret1 || ret2)
-		return QDF_STATUS_E_FAILURE;
-	else
-		return QDF_STATUS_SUCCESS;
-}
-
-static QDF_STATUS target_if_dfs_reg_phyerr_events(struct wlan_objmgr_psoc *psoc)
-{
-	/* TODO: dfs non-offload case */
-	return QDF_STATUS_SUCCESS;
-}
-
 #ifdef QCA_MCL_DFS_SUPPORT
 /**
  * target_if_radar_event_handler() - handle radar event when
@@ -320,54 +184,6 @@ static QDF_STATUS target_if_dfs_register_event_handler(
 	}
 }
 
-#if (defined(CONFIG_MCL) || (QCA_WIFI_QCA8074))
-static QDF_STATUS target_process_bang_radar_cmd(
-		struct wlan_objmgr_pdev *pdev,
-		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
-{
-	QDF_STATUS status;
-	struct wmi_unit_test_cmd wmi_utest;
-	int i;
-	wmi_unified_t wmi_handle;
-
-	if (!pdev) {
-		target_if_err("null pdev");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
-	if (!wmi_handle) {
-		target_if_err("null wmi_handle");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	wmi_utest.vdev_id = dfs_unit_test->vdev_id;
-	wmi_utest.module_id = WLAN_MODULE_PHYERR_DFS;
-	wmi_utest.num_args = dfs_unit_test->num_args;
-
-	for (i = 0; i < dfs_unit_test->num_args; i++)
-		wmi_utest.args[i] = dfs_unit_test->args[i];
-	/*
-	 * Host to Target  conversion for pdev id required
-	 * before we send a wmi unit test command
-	 */
-	wmi_utest.args[IDX_PDEV_ID] = wmi_handle->ops->
-		convert_pdev_id_host_to_target(pdev->pdev_objmgr.wlan_pdev_id);
-
-	status = wmi_unified_unit_test_cmd(wmi_handle, &wmi_utest);
-	if (QDF_IS_STATUS_ERROR(status))
-		target_if_err("dfs: unit_test_cmd send failed %d", status);
-	return status;
-}
-#else
-static QDF_STATUS target_process_bang_radar_cmd(
-		struct wlan_objmgr_pdev *pdev,
-		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
-{
-	return QDF_STATUS_SUCCESS;
-}
-#endif
-
 static QDF_STATUS target_if_dfs_is_pdev_5ghz(struct wlan_objmgr_pdev *pdev,
 		bool *is_5ghz)
 {
@@ -441,69 +257,6 @@ static QDF_STATUS target_if_dfs_set_phyerr_filter_offload(
 }
 #endif
 
-/**
- * target_if_dfs_get_caps - get dfs caps.
- * @pdev: Pointer to DFS pdev object.
- * @dfs_caps: Pointer to dfs_caps structure.
- *
- * Return: QDF_STATUS
- */
-static QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev,
-					struct wlan_dfs_caps *dfs_caps)
-{
-	struct wlan_objmgr_psoc *psoc = NULL;
-	struct target_psoc_info *tgt_psoc_info;
-
-	if (!dfs_caps) {
-		target_if_err("null dfs_caps");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	dfs_caps->wlan_dfs_combined_rssi_ok = 0;
-	dfs_caps->wlan_dfs_ext_chan_ok = 0;
-	dfs_caps->wlan_dfs_use_enhancement = 0;
-	dfs_caps->wlan_strong_signal_diversiry = 0;
-	dfs_caps->wlan_fastdiv_val = 0;
-	dfs_caps->wlan_chip_is_bb_tlv = 1;
-	dfs_caps->wlan_chip_is_over_sampled = 0;
-	dfs_caps->wlan_chip_is_ht160 = 0;
-	dfs_caps->wlan_chip_is_false_detect = 0;
-
-	psoc = wlan_pdev_get_psoc(pdev);
-	if (!psoc) {
-		target_if_err("null psoc");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
-	if (!tgt_psoc_info) {
-		target_if_err("null tgt_psoc_info");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	switch (target_psoc_get_target_type(tgt_psoc_info)) {
-	case TARGET_TYPE_AR900B:
-		break;
-
-	case TARGET_TYPE_IPQ4019:
-		dfs_caps->wlan_chip_is_false_detect = 0;
-		break;
-
-	case TARGET_TYPE_AR9888:
-		dfs_caps->wlan_chip_is_over_sampled = 1;
-		break;
-
-	case TARGET_TYPE_QCA9984:
-	case TARGET_TYPE_QCA9888:
-		dfs_caps->wlan_chip_is_ht160 = 1;
-		break;
-	default:
-		break;
-	}
-
-	return QDF_STATUS_SUCCESS;
-}
-
 static QDF_STATUS target_send_dfs_offload_enable_cmd(
 		struct wlan_objmgr_pdev *pdev, bool enable)
 {

+ 221 - 0
target_if/dfs/src/target_if_dfs_full_offload.c

@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: target_if_dfs_full_offload.c
+ * This file contains dfs target interface for full offload
+ */
+
+#include <target_if.h>
+#include <target_if_dfs.h>
+#include <wmi_unified_dfs_api.h>
+#include <init_deinit_ucfg.h>
+#include <wlan_module_ids.h>
+#include <target_if_dfs_full_offload.h>
+
+/**
+ * target_if_dfs_cac_complete_event_handler() - CAC complete indication.
+ * @scn: scn handle.
+ * @data: Pointer to data buffer.
+ * @datalen: data length.
+ *
+ * Return: 0 on successful indication.
+ */
+static int target_if_dfs_cac_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;
+	int ret = 0;
+	uint32_t vdev_id = 0;
+
+	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_cac_complete_ind) {
+		target_if_err("Invalid dfs_rx_ops: %pK", dfs_rx_ops);
+		return -EINVAL;
+	}
+
+	if (wmi_extract_dfs_cac_complete_event(GET_WMI_HDL_FROM_PSOC(psoc),
+			data, &vdev_id, datalen) != QDF_STATUS_SUCCESS) {
+		target_if_err("failed to extract cac complete event");
+		return -EFAULT;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 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;
+	}
+
+	if (!ret && (QDF_STATUS_SUCCESS !=
+	    dfs_rx_ops->dfs_dfs_cac_complete_ind(pdev, vdev_id))) {
+		target_if_err("dfs_dfs_cac_complete_ind failed");
+		ret = -EINVAL;
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
+
+	return ret;
+}
+
+/**
+ * target_if_dfs_radar_detection_event_handler() - Indicate RADAR detection and
+ * process RADAR detection.
+ * @scn: scn handle.
+ * @data: pointer to data buffer.
+ * @datalen: data length.
+ *
+ * Return: 0 on successful indication.
+ */
+static int target_if_dfs_radar_detection_event_handler(
+		ol_scn_t scn, uint8_t *data, uint32_t datalen)
+{
+	struct radar_found_info radar;
+	struct wlan_objmgr_psoc *psoc = NULL;
+	struct wlan_objmgr_pdev *pdev = NULL;
+	struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops;
+	int ret = 0;
+
+	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_process_radar_ind) {
+		target_if_err("Invalid dfs_rx_ops: %pK", dfs_rx_ops);
+		return -EINVAL;
+	}
+
+	if (wmi_extract_dfs_radar_detection_event(GET_WMI_HDL_FROM_PSOC(psoc),
+			data, &radar, datalen) != QDF_STATUS_SUCCESS) {
+		target_if_err("failed to extract cac complete event");
+		return -EFAULT;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, radar.pdev_id, WLAN_DFS_ID);
+	if (!pdev) {
+		target_if_err("null pdev");
+		return -EINVAL;
+	}
+
+	if (dfs_rx_ops->dfs_process_radar_ind(pdev,
+				&radar) != QDF_STATUS_SUCCESS) {
+		target_if_err("dfs_process_radar_ind failed pdev_id=%d",
+			      radar.pdev_id);
+		ret = -EINVAL;
+	}
+
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
+
+	return ret;
+}
+
+QDF_STATUS target_if_dfs_reg_offload_events(
+		struct wlan_objmgr_psoc *psoc)
+{
+	int ret1, ret2;
+
+	ret1 = wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc),
+			wmi_dfs_radar_detection_event_id,
+			target_if_dfs_radar_detection_event_handler);
+	target_if_debug("wmi_dfs_radar_detection_event_id ret=%d", ret1);
+
+	ret2 = wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc),
+			wmi_dfs_cac_complete_id,
+			target_if_dfs_cac_complete_event_handler);
+	target_if_debug("wmi_dfs_cac_complete_id ret=%d", ret2);
+
+	if (ret1 || ret2)
+		return QDF_STATUS_E_FAILURE;
+	else
+		return QDF_STATUS_SUCCESS;
+}
+
+#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)
+{
+	QDF_STATUS status;
+	struct wmi_unit_test_cmd wmi_utest;
+	int i;
+	wmi_unified_t wmi_handle;
+
+	if (!pdev) {
+		target_if_err("null pdev");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
+	if (!wmi_handle) {
+		target_if_err("null wmi_handle");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wmi_utest.vdev_id = dfs_unit_test->vdev_id;
+	wmi_utest.module_id = WLAN_MODULE_PHYERR_DFS;
+	wmi_utest.num_args = dfs_unit_test->num_args;
+
+	for (i = 0; i < dfs_unit_test->num_args; i++)
+		wmi_utest.args[i] = dfs_unit_test->args[i];
+	/*
+	 * Host to Target  conversion for pdev id required
+	 * before we send a wmi unit test command
+	 */
+	wmi_utest.args[IDX_PDEV_ID] = wmi_handle->ops->
+		convert_pdev_id_host_to_target(pdev->pdev_objmgr.wlan_pdev_id);
+
+	status = wmi_unified_unit_test_cmd(wmi_handle, &wmi_utest);
+	if (QDF_IS_STATUS_ERROR(status))
+		target_if_err("dfs: unit_test_cmd send failed %d", status);
+	return status;
+}
+#else
+static QDF_STATUS target_process_bang_radar_cmd(
+		struct wlan_objmgr_pdev *pdev,
+		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
+{
+	    return QDF_STATUS_SUCCESS;
+}
+#endif

+ 89 - 0
target_if/dfs/src/target_if_dfs_partial_offload.c

@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: target_if_dfs_partial_offload.c
+ * This file contains dfs target interface for partial offload
+ */
+
+#include <target_if.h>
+#include "target_type.h"
+#include "target_if_dfs_partial_offload.h"
+
+QDF_STATUS target_if_dfs_reg_phyerr_events(struct wlan_objmgr_psoc *psoc)
+{
+	/* TODO: dfs non-offload case */
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev,
+		struct wlan_dfs_caps *dfs_caps)
+{
+	struct wlan_objmgr_psoc *psoc = NULL;
+	struct target_psoc_info *tgt_psoc_info;
+
+	if (!dfs_caps) {
+		target_if_err("null dfs_caps");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_caps->wlan_dfs_combined_rssi_ok = 0;
+	dfs_caps->wlan_dfs_ext_chan_ok = 0;
+	dfs_caps->wlan_dfs_use_enhancement = 0;
+	dfs_caps->wlan_strong_signal_diversiry = 0;
+	dfs_caps->wlan_fastdiv_val = 0;
+	dfs_caps->wlan_chip_is_bb_tlv = 1;
+	dfs_caps->wlan_chip_is_over_sampled = 0;
+	dfs_caps->wlan_chip_is_ht160 = 0;
+	dfs_caps->wlan_chip_is_false_detect = 0;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
+	if (!tgt_psoc_info) {
+		target_if_err("null tgt_psoc_info");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	switch (target_psoc_get_target_type(tgt_psoc_info)) {
+	case TARGET_TYPE_AR900B:
+		break;
+
+	case TARGET_TYPE_IPQ4019:
+		dfs_caps->wlan_chip_is_false_detect = 0;
+		break;
+
+	case TARGET_TYPE_AR9888:
+		dfs_caps->wlan_chip_is_over_sampled = 1;
+		break;
+
+	case TARGET_TYPE_QCA9984:
+	case TARGET_TYPE_QCA9888:
+		dfs_caps->wlan_chip_is_ht160 = 1;
+		break;
+	default:
+		break;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}

+ 82 - 56
umac/dfs/core/src/dfs.h

@@ -459,6 +459,8 @@ struct dfs_event {
 #define DFS_MAX_NUM_RADAR_FILTERS 10
 /* Number of different radar types */
 #define DFS_MAX_RADAR_TYPES  32
+/* Number of filter index table rows */
+#define DFS_NUM_FT_IDX_TBL_ROWS  256
 
 /* RADAR filter pattern type 1*/
 #define WLAN_DFS_RF_PATTERN_TYPE_1 1
@@ -1424,7 +1426,13 @@ uint32_t dfs_round(int32_t val);
  * dfs_reset_alldelaylines() - Reset alldelaylines.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_reset_alldelaylines(struct wlan_dfs *dfs);
+#else
+static inline void dfs_reset_alldelaylines(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_reset_delayline() - Clear only a single delay line.
@@ -1442,7 +1450,13 @@ void dfs_reset_filter_delaylines(struct dfs_filtertype *dft);
  * dfs_reset_radarq() - Reset radar queue.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_reset_radarq(struct wlan_dfs *dfs);
+#else
+static inline void dfs_reset_radarq(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_add_pulse() - Adds pulse to the queue.
@@ -1592,8 +1606,15 @@ void dfs_reset(struct wlan_dfs *dfs);
  * @dfs: Pointer to wlan_dfs structure.
  * @no_cac: If no_cac is 0, it cancels the CAC.
  */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_radar_enable(struct wlan_dfs *dfs,
 		int no_cac, uint32_t opmode);
+#else
+static inline void dfs_radar_enable(struct wlan_dfs *dfs,
+		int no_cac, uint32_t opmode)
+{
+}
+#endif
 
 /**
  * dfs_process_phyerr() - Process phyerr.
@@ -1605,6 +1626,7 @@ void dfs_radar_enable(struct wlan_dfs *dfs,
  * @r_rs_tstamp: Timestamp.
  * @r_fulltsf: TSF64.
  */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_process_phyerr(struct wlan_dfs *dfs,
 		void *buf,
 		uint16_t datalen,
@@ -1612,6 +1634,17 @@ void dfs_process_phyerr(struct wlan_dfs *dfs,
 		uint8_t r_ext_rssi,
 		uint32_t r_rs_tstamp,
 		uint64_t r_fulltsf);
+#else
+static inline void dfs_process_phyerr(struct wlan_dfs *dfs,
+		void *buf,
+		uint16_t datalen,
+		uint8_t r_rssi,
+		uint8_t r_ext_rssi,
+		uint32_t r_rs_tstamp,
+		uint64_t r_fulltsf)
+{
+}
+#endif
 
 #ifdef QCA_MCL_DFS_SUPPORT
 /**
@@ -1621,21 +1654,29 @@ void dfs_process_phyerr(struct wlan_dfs *dfs,
  *
  * Return: None
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_process_phyerr_filter_offload(struct wlan_dfs *dfs,
 		struct radar_event_info *wlan_radar_event);
+#else
+static inline void dfs_process_phyerr_filter_offload(
+		struct wlan_dfs *dfs,
+		struct radar_event_info *wlan_radar_event)
+{
+}
+#endif
 #endif
-
-/**
- * dfs_is_precac_timer_running() - Check whether precac timer is running.
- * @dfs: Pointer to wlan_dfs structure.
- */
-bool dfs_is_precac_timer_running(struct wlan_dfs *dfs);
 
 /**
  * dfs_get_radars() - Based on the chipset, calls init radar table functions.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_get_radars(struct wlan_dfs *dfs);
+#else
+static inline void dfs_get_radars(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_attach() - Wrapper function to allocate memory for wlan_dfs members.
@@ -1643,11 +1684,6 @@ void dfs_get_radars(struct wlan_dfs *dfs);
  */
 int dfs_attach(struct wlan_dfs *dfs);
 
-/**
- * dfs_main_attach() - Allocates memory for wlan_dfs members.
- * @dfs: Pointer to wlan_dfs structure.
- */
-int dfs_main_attach(struct wlan_dfs *dfs);
 
 /**
  * dfs_create_object() - Creates DFS object.
@@ -1667,12 +1703,6 @@ void dfs_destroy_object(struct wlan_dfs *dfs);
  */
 void dfs_detach(struct wlan_dfs *dfs);
 
-/**
- * dfs_main_detach() - Free dfs variables.
- * @dfs: Pointer to wlan_dfs structure.
- */
-void dfs_main_detach(struct wlan_dfs *dfs);
-
 /**
  * dfs_cac_valid_reset() - Cancels the dfs_cac_valid_timer timer.
  * @dfs: Pointer to wlan_dfs structure.
@@ -1837,14 +1867,14 @@ void dfs_clear_stats(struct wlan_dfs *dfs);
  * dfs_radar_disable() - Disables the radar.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
 int dfs_radar_disable(struct wlan_dfs *dfs);
-
-/**
- * dfs_mark_precac_dfs() - Mark the precac channel as radar.
- * @dfs: Pointer to wlan_dfs structure.
- */
-void dfs_mark_precac_dfs(struct wlan_dfs *dfs,
-		uint8_t is_radar_found_on_secondary_seg);
+#else
+static inline int dfs_radar_disable(struct wlan_dfs *dfs)
+{
+	return 0;
+}
+#endif
 
 /**
  * dfs_get_debug_info() - Get debug info.
@@ -1924,8 +1954,16 @@ void dfs_phyerr_param_copy(struct wlan_dfs_phyerr_param *dst,
  * @dfs: Pointer to wlan_dfs structure.
  * @param: Pointer to wlan_dfs_phyerr_param structure.
  */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
 int dfs_get_thresholds(struct wlan_dfs *dfs,
 		struct wlan_dfs_phyerr_param *param);
+#else
+static inline int dfs_get_thresholds(struct wlan_dfs *dfs,
+		struct wlan_dfs_phyerr_param *param)
+{
+		return 0;
+}
+#endif
 
 /**
  * dfs_set_thresholds() - Sets the threshold value.
@@ -1933,9 +1971,18 @@ int dfs_get_thresholds(struct wlan_dfs *dfs,
  * @threshtype: DFS ioctl param type.
  * @value: Threshold value.
  */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
 int dfs_set_thresholds(struct wlan_dfs *dfs,
 		const uint32_t threshtype,
 		const uint32_t value);
+#else
+static inline int dfs_set_thresholds(struct wlan_dfs *dfs,
+		const uint32_t threshtype,
+		const uint32_t value)
+{
+		return 0;
+}
+#endif
 
 /**
  * dfs_set_current_channel() - Set DFS current channel.
@@ -1955,17 +2002,6 @@ void dfs_set_current_channel(struct wlan_dfs *dfs,
 		uint8_t dfs_ch_vhtop_ch_freq_seg1,
 		uint8_t dfs_ch_vhtop_ch_freq_seg2);
 
-/**
- * dfs_second_segment_radar_disable() - Disables the second segment radar.
- * @dfs: Pointer to wlan_dfs structure.
- *
- * This is called when AP detects the radar, to (potentially) disable
- * the radar code.
- *
- * Return: returns 0.
- */
-int dfs_second_segment_radar_disable(struct wlan_dfs *dfs);
-
 /**
  * dfs_get_nol_chfreq_and_chwidth() - Get channel freq and width from NOL list.
  * @dfs_nol: Pointer to NOL channel entry.
@@ -2085,24 +2121,12 @@ void bin5_rules_check_internal(struct wlan_dfs *dfs,
 		uint32_t this,
 		int *index);
 
-/**
- * dfs_main_task_timer_init() - Initialize dfs task timer.
- * @dfs: Pointer to wlan_dfs structure.
- */
-void dfs_main_task_timer_init(struct wlan_dfs *dfs);
-
 /**
  * dfs_main_task_testtimer_init() - Initialize dfs task testtimer.
  * @dfs: Pointer to wlan_dfs structure.
  */
 void dfs_main_task_testtimer_init(struct wlan_dfs *dfs);
 
-/**
- * dfs_main_timer_reset() - Stop dfs timers.
- * @dfs: Pointer to wlan_dfs structure.
- */
-void dfs_main_timer_reset(struct wlan_dfs *dfs);
-
 /**
  * dfs_stop() - Clear dfs timers.
  * @dfs: Pointer to wlan_dfs structure.
@@ -2119,15 +2143,6 @@ void dfs_update_cur_chan_flags(struct wlan_dfs *dfs,
 		uint64_t flags,
 		uint16_t flagext);
 
-/**
- * dfs_send_csa_to_current_chan() - Send CSA to current channel
- * @dfs: Pointer to wlan_dfs structure.
- *
- * For the test mode(usenol = 0), don't do a CSA; but setup the test timer so
- * we get a CSA _back_ to the current operating channel.
- */
-void dfs_send_csa_to_current_chan(struct wlan_dfs *dfs);
-
 /**
  * dfs_radarevent_basic_sanity() - Check basic sanity of the radar event
  * @dfs: Pointer to wlan_dfs structure.
@@ -2154,4 +2169,15 @@ wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc *psoc);
  */
 void dfs_nol_free_list(struct wlan_dfs *dfs);
 
+/**
+ * dfs_second_segment_radar_disable() - Disables the second segment radar.
+ * @dfs: Pointer to wlan_dfs structure.
+ *
+ * This is called when AP detects the radar, to (potentially) disable
+ * the radar code.
+ *
+ * Return: returns 0.
+ */
+int dfs_second_segment_radar_disable(struct wlan_dfs *dfs);
+
 #endif  /* _DFS_H_ */

+ 39 - 0
umac/dfs/core/src/dfs_direct_attach_radar.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: dfs_direct_attach_radar.h
+ * This file contains direct attach specific dfs interfaces
+ */
+
+#ifndef _DFS_DIRECT_ATTACH_RADAR_H_
+#define _DFS_DIRECT_ATTACH_RADAR_H_
+
+/**
+ * dfs_get_da_radars() - Initialize the RADAR table for DA.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(WLAN_DFS_DIRECT_ATTACH)
+void dfs_get_da_radars(struct wlan_dfs *dfs);
+#else
+static inline void dfs_get_da_radars(struct wlan_dfs *dfs)
+{
+}
+#endif
+#endif /* _DFS_DIRECT_ATTACH_RADAR_H_ */

+ 79 - 0
umac/dfs/core/src/dfs_filter_init.h

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: umac/dfs/core/src/dfs_filter_init.h
+ * This file contains dfs interfaces
+ */
+
+#ifndef _DFS_FILTER_INIT_H_
+#define _DFS_FILTER_INIT_H_
+
+/**
+ * dfs_main_attach() - Allocates memory for wlan_dfs members.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
+int dfs_main_attach(struct wlan_dfs *dfs);
+#else
+static inline int dfs_main_attach(struct wlan_dfs *dfs)
+{
+	return 0;
+}
+#endif
+
+/**
+ * dfs_main_detach() - Free dfs variables.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
+void dfs_main_detach(struct wlan_dfs *dfs);
+#else
+static inline void dfs_main_detach(struct wlan_dfs *dfs)
+{
+}
+#endif
+
+/**
+ * dfs_start_host_based_bangradar() - Mark as bangradar and start
+ * wlan_dfs_task_timer.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
+int dfs_start_host_based_bangradar(struct wlan_dfs *dfs);
+#else
+static int dfs_start_host_based_bangradar(struct wlan_dfs *dfs)
+{
+	return 0;
+}
+#endif
+
+/**
+ * dfs_main_timer_reset() - Stop dfs timers.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
+void dfs_main_timer_reset(struct wlan_dfs *dfs);
+#else
+static void dfs_main_timer_reset(struct wlan_dfs *dfs)
+{
+}
+#endif
+
+#endif /* _DFS_FILTER_INIT_H_ */

+ 49 - 0
umac/dfs/core/src/dfs_full_offload.h

@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: dfs_full_offload.h
+ * This file contains full offload specific dfs interfaces
+ */
+
+#ifndef _DFS_FULL_OFFLOAD_H_
+#define _DFS_FULL_OFFLOAD_H_
+
+/**
+ * dfs_fill_emulate_bang_radar_test() - Update dfs unit test arguments and
+ * send bangradar command to firmware.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @segid: Segment Identifier(Primary and Secondary)
+ * @dfs_unit_test: Pointer to Unit test command structure
+ *
+ * Return: If the event is received return 0.
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD)
+int dfs_fill_emulate_bang_radar_test(struct wlan_dfs *dfs,
+		uint32_t segid,
+		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test);
+#else
+static inline int dfs_fill_emulate_bang_radar_test(struct wlan_dfs *dfs,
+		uint32_t segid,
+		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
+{
+	return 0;
+}
+#endif
+#endif /* _DFS_FULL_OFFLOAD_H_ */

+ 39 - 0
umac/dfs/core/src/dfs_partial_offload_radar.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: dfs_partial_offload_radar.h
+ * This file contains partial offload specific dfs interfaces
+ */
+
+#ifndef _DFS_PARTIAL_OFFLOAD_RADAR_H_
+#define _DFS_PARTIAL_OFFLOAD_RADAR_H_
+
+/**
+ * dfs_get_po_radars() - Initialize the RADAR table for PO.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
+void dfs_get_po_radars(struct wlan_dfs *dfs);
+#else
+static void dfs_get_po_radars(struct wlan_dfs *dfs)
+{
+}
+#endif
+#endif /*  _DFS_PARTIAL_OFFLOAD_RADAR_H_ */

+ 107 - 1
umac/dfs/core/src/dfs_zero_cac.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
  * All rights reserved.
  *
@@ -59,13 +59,25 @@ void dfs_zero_cac_timer_init(struct wlan_dfs *dfs);
  * dfs_print_precaclists() - Print precac list.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_print_precaclists(struct wlan_dfs *dfs);
+#else
+static inline void dfs_print_precaclists(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_reset_precac_lists() - Resets the precac lists.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_reset_precac_lists(struct wlan_dfs *dfs);
+#else
+static inline void dfs_reset_precac_lists(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_reset_precaclists() - Clears and initiakizes precac_required_list,
@@ -73,7 +85,13 @@ void dfs_reset_precac_lists(struct wlan_dfs *dfs);
  *
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_reset_precaclists(struct wlan_dfs *dfs);
+#else
+static inline void dfs_reset_precaclists(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_deinit_precac_list() - Clears the precac list.
@@ -85,7 +103,13 @@ void dfs_deinit_precac_list(struct wlan_dfs *dfs);
  * dfs_zero_cac_detach() - Free zero_cac memory.
  * @dfs: Pointer to wlan_dfs dtructure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_zero_cac_detach(struct wlan_dfs *dfs);
+#else
+static inline void dfs_zero_cac_detach(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_init_precac_list() - Init precac list.
@@ -105,25 +129,50 @@ void dfs_start_precac_timer(struct wlan_dfs *dfs,
  * dfs_cancel_precac_timer() - Cancel the precac timer.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_cancel_precac_timer(struct wlan_dfs *dfs);
+#else
+static inline void dfs_cancel_precac_timer(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_zero_cac_attach() - Initialize dfs zerocac variables.
  * @dfs: Pointer to DFS structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_zero_cac_attach(struct wlan_dfs *dfs);
+#else
+static inline void dfs_zero_cac_attach(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_zero_cac_reset() - Reset Zero cac DFS variables.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_zero_cac_reset(struct wlan_dfs *dfs);
+#else
+static inline void dfs_zero_cac_reset(struct wlan_dfs *dfs)
+{
+}
+#endif
 
 /**
  * dfs_is_precac_done() - Is precac done.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 bool dfs_is_precac_done(struct wlan_dfs *dfs);
+#else
+static inline bool dfs_is_precac_done(struct wlan_dfs *dfs)
+{
+	return false;
+}
+#endif
 
 /**
  * dfs_get_freq_from_precac_required_list() - Get VHT80 freq from
@@ -140,16 +189,32 @@ uint8_t dfs_get_freq_from_precac_required_list(struct wlan_dfs *dfs,
  * @dfs: Pointer to wlan_dfs structure.
  * @precac_timeout: Precac timeout value.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 int dfs_override_precac_timeout(struct wlan_dfs *dfs,
 		int precac_timeout);
+#else
+static inline int dfs_override_precac_timeout(struct wlan_dfs *dfs,
+		int precac_timeout)
+{
+	return 0;
+}
+#endif
 
 /**
  * dfs_get_override_precac_timeout() - Get precac timeout.
  * @dfs: Pointer wlan_dfs structure.
  * @precac_timeout: Get precac timeout value in this variable.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 int dfs_get_override_precac_timeout(struct wlan_dfs *dfs,
 		int *precac_timeout);
+#else
+static inline int dfs_get_override_precac_timeout(struct wlan_dfs *dfs,
+		int *precac_timeout)
+{
+	return 0;
+}
+#endif
 
 /**
  * dfs_find_vht80_chan_for_precac() - Find VHT80 channel for precac.
@@ -186,6 +251,7 @@ int dfs_get_override_precac_timeout(struct wlan_dfs *dfs,
  * Which means when all the channels in precac-required-list are
  * exhausted the VHT80_80/VHT160 comes back to VHT80 mode.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
 		uint32_t chan_mode,
 		uint8_t ch_freq_seg1,
@@ -194,20 +260,46 @@ void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
 		uint32_t *phy_mode,
 		bool *dfs_set_cfreq2,
 		bool *set_agile);
+#else
+static inline void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
+		uint32_t chan_mode,
+		uint8_t ch_freq_seg1,
+		uint32_t *cfreq1,
+		uint32_t *cfreq2,
+		uint32_t *phy_mode,
+		bool *dfs_set_cfreq2,
+		bool *set_agile)
+{
+}
+#endif
 
 /**
  * dfs_set_precac_enable() - Set precac enable flag.
  * @dfs: Pointer to wlan_dfs structure.
  * @value: input value for dfs_precac_enable flag.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_set_precac_enable(struct wlan_dfs *dfs,
 		uint32_t value);
+#else
+static inline void dfs_set_precac_enable(struct wlan_dfs *dfs,
+		uint32_t value)
+{
+}
+#endif
 
 /**
  * dfs_get_precac_enable() - Get precac enable flag.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 uint32_t dfs_get_precac_enable(struct wlan_dfs *dfs);
+#else
+static inline uint32_t dfs_get_precac_enable(struct wlan_dfs *dfs)
+{
+	return 0;
+}
+#endif
 
 /**
  * dfs_zero_cac_reset() - Reset Zero cac DFS variables.
@@ -233,12 +325,26 @@ bool dfs_is_ht80_80_chan_in_precac_done_list(struct wlan_dfs *dfs);
  * dfs_mark_precac_dfs() - Mark the precac channel as radar.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 void dfs_mark_precac_dfs(struct wlan_dfs *dfs,
 		uint8_t is_radar_found_on_secondary_seg);
+#else
+static inline void dfs_mark_precac_dfs(struct wlan_dfs *dfs,
+		uint8_t is_radar_found_on_secondary_seg)
+{
+}
+#endif
 
 /**
  * dfs_is_precac_timer_running() - Check whether precac timer is running.
  * @dfs: Pointer to wlan_dfs structure.
  */
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD)
 bool dfs_is_precac_timer_running(struct wlan_dfs *dfs);
+#else
+static inline bool dfs_is_precac_timer_running(struct wlan_dfs *dfs)
+{
+	return false;
+}
+#endif
 #endif /* _DFS_ZERO_CAC_H_ */

+ 107 - 0
umac/dfs/core/src/filtering/dfs_direct_attach_radar.c

@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: This file has radar table and initialization function for Beeliner
+ * family of chipsets.
+ */
+
+#include "../dfs.h"
+#include "wlan_dfs_mlme_api.h"
+#include "wlan_dfs_utils_api.h"
+#include "wlan_dfs_lmac_api.h"
+#include "../dfs_internal.h"
+
+void dfs_get_da_radars(struct wlan_dfs *dfs)
+{
+#define AR5212_DEVID_IBM            0x1014 /* IBM minipci ID */
+#define AR5212_AR2413               0x001a /* AR2413 aka Griffin-lite */
+#define AR5212_AR2413               0x001a /* AR2413 aka Griffin-lite */
+#define AR5212_AR5413               0x001b /* Eagle */
+#define AR5212_AR5424               0x001c /* Condor (PCI express) */
+#define AR5212_DEVID_FF19           0xff19 /* PCI express */
+#define AR5212_AR2417               0x001d /* Nala, PCI */
+#define AR5212_DEVID                0x0013 /* Final ar5212 devid */
+#define AR5212_FPGA                 0xf013 /* Emulation board */
+#define AR5212_DEFAULT              0x1113 /* No eeprom HW default */
+
+#define AR5416_DEVID_PCI            0x0023 /* AR5416 PCI (CB/MB) (Owl)*/
+#define AR5416_DEVID_PCIE           0x0024 /* AR5416 PCI-E (XB) (Owl) */
+#define AR5416_DEVID_AR9160_PCI     0x0027 /* AR9160 PCI (Sowl) */
+#define AR5416_AR9100_DEVID         0x000b /* AR9100 (Howl)    */
+#define AR5416_DEVID_AR9280_PCI     0x0029 /* PCI (Merlin) */
+#define AR5416_DEVID_AR9280_PCIE    0x002a /* PCIE (Merlin) */
+#define AR5416_DEVID_AR9285_PCIE    0x002b /* PCIE (Kite) */
+#define AR5416_DEVID_AR9285G_PCIE   0x002c /* PCIE (Kite G only) */
+#define AR5416_DEVID_AR9287_PCI     0x002d /* PCI (Kiwi) */
+#define AR5416_DEVID_AR9287_PCIE    0x002e /* PCIE (Kiwi) */
+
+#define AR9300_DEVID_AR9380_PCIE    0x0030 /* PCIE (Osprey) */
+#define AR9300_DEVID_AR9340         0x0031 /* Wasp */
+#define AR9300_DEVID_AR9485_PCIE    0x0032 /* Poseidon */
+#define AR9300_DEVID_AR9580_PCIE    0x0033 /* Peacock */
+#define AR9300_DEVID_AR1111_PCIE    0x0037 /* AR1111 */
+#define AR9300_DEVID_AR946X_PCIE    0x0034 /* Jupiter: 2x2 DB + BT - AR9462 */
+#define AR9300_DEVID_AR955X         0x0039 /* Scorpion */
+#define AR9300_DEVID_AR953X         0x003d /* Honey Bee */
+#define AR9300_DEVID_AR956X         0x003f /* Dragonfly */
+#define AR9300_DEVID_AR956X_PCIE    0x0036 /* Aphrodite: 1x1 DB + BT - AR9564 */
+#define AR9300_DEVID_EMU_PCIE       0xabcd
+
+	uint16_t devid = lmac_get_ah_devid(dfs->dfs_pdev_obj);
+	/* For DA */
+
+	switch (devid) {
+	case AR5212_DEVID_IBM:
+	case AR5212_AR2413:
+	case AR5212_AR5413:
+	case AR5212_AR5424:
+	case AR5212_DEVID_FF19:
+		devid = AR5212_DEVID;
+	case AR5212_AR2417:
+	case AR5212_DEVID:
+	case AR5212_FPGA:
+	case AR5212_DEFAULT:
+		dfs_get_radars_for_ar5212(dfs);
+		break;
+	case AR5416_DEVID_PCI:
+	case AR5416_DEVID_PCIE:
+	case AR5416_DEVID_AR9160_PCI:
+	case AR5416_AR9100_DEVID:
+	case AR5416_DEVID_AR9280_PCI:
+	case AR5416_DEVID_AR9280_PCIE:
+	case AR5416_DEVID_AR9285_PCIE:
+	case AR5416_DEVID_AR9285G_PCIE:
+	case AR5416_DEVID_AR9287_PCI:
+	case AR5416_DEVID_AR9287_PCIE:
+		dfs_get_radars_for_ar5416(dfs);
+		break;
+	case AR9300_DEVID_AR9380_PCIE:
+	case AR9300_DEVID_AR9340:
+	case AR9300_DEVID_AR9485_PCIE:
+	case AR9300_DEVID_AR9580_PCIE:
+	case AR9300_DEVID_AR1111_PCIE:
+	case AR9300_DEVID_AR946X_PCIE:
+	case AR9300_DEVID_AR955X:
+	case AR9300_DEVID_AR953X:
+	case AR9300_DEVID_AR956X:
+	case AR9300_DEVID_AR956X_PCIE:
+	case AR9300_DEVID_EMU_PCIE:
+		dfs_get_radars_for_ar9300(dfs);
+		break;
+	}
+}

+ 424 - 0
umac/dfs/core/src/filtering/dfs_partial_offload_radar.c

@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: This file has radar table and initialization function for Beeliner
+ * family of chipsets.
+ */
+
+#include "../dfs.h"
+#include "wlan_dfs_mlme_api.h"
+#include "wlan_dfs_utils_api.h"
+#include "wlan_dfs_lmac_api.h"
+#include "../dfs_internal.h"
+#include "../dfs_partial_offload_radar.h"
+
+/**
+ * struct dfs_pulse dfs_fcc_radars - FCC radar table for Offload chipsets.
+ */
+static struct dfs_pulse dfs_fcc_radars[] = {
+	/* FCC TYPE 1 */
+	{18,  1,  700, 700, 0,  4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 0},
+	{18,  1,  350, 350, 0,  4,  5,  0,  1, 18,  0, 3,  0, 5, 0, 0},
+
+	/* FCC TYPE 6 */
+	{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0,  1, 1000, 0, 1},
+
+	/* FCC TYPE 2 */
+	{23, 5, 4347, 6666, 0,  4, 11,  0,  7, 22,  0, 3,  0, 5, 0, 2},
+
+	/* FCC TYPE 3 */
+	{18, 10, 2000, 5000, 0,  4,  8,  6, 13, 22,  0, 3, 0, 5, 0, 5},
+
+	/* FCC TYPE 4 */
+	{16, 15, 2000, 5000, 0,  4,  7, 11, 23, 22,  0, 3, 0, 5, 0, 11},
+
+	/* FCC NEW TYPE 1 */
+	/* 518us to 938us pulses (min 56 pulses) */
+	{57, 1, 1066, 1930, 0, 4,  20,  0,  1, 22,  0, 3,  0, 5, 0, 21},
+
+	/* 938us to 2000 pulses (min 26 pulses) */
+	{27, 1,  500, 1066, 0, 4,  13,  0,  1, 22,  0, 3,  0, 5, 0, 22},
+
+	/* 2000 to 3067us pulses (min 17 pulses) */
+	{18, 1,  325,  500, 0, 4,  9,   0,  1, 22,  0, 3,  0, 5, 0, 23},
+};
+
+/**
+ * struct dfs_pulse dfs_mkk4_radars - MKK4 radar table for Offload chipsets.
+ */
+static struct dfs_pulse dfs_mkk4_radars[] = {
+
+	/* following two filters are specific to Japan/MKK4 */
+	/* 1389 +/- 6 us */
+	{18,  1,  720,  720, 0,  4,  6,  0,  1, 18,  0, 3, 0, 5, 0, 17},
+
+	/* 4000 +/- 6 us */
+	{18,  4,  250,  250, 0,  4,  5,  1,  6, 18,  0, 3, 0, 5, 0, 18},
+
+	/* 3846 +/- 7 us */
+	{18,  5,  260,  260, 0,  4,  6,  1,  6, 18,  0, 3, 1, 5, 0, 19},
+
+	/* following filters are common to both FCC and JAPAN */
+
+	/* FCC TYPE 1 */
+	{18,  1,  700, 700, 0,  4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 0},
+	{18,  1,  350, 350, 0,  4,  5,  0,  1, 18,  0, 3,  0, 5, 0, 0},
+
+	/* FCC TYPE 6 */
+	{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0, 1,  1000, 0, 1},
+
+	/* FCC TYPE 2 */
+	{23, 5, 4347, 6666, 0,  4, 11,  0,  7, 22,  0, 3,  0, 5, 0, 2},
+
+	/* FCC TYPE 3 */
+	{18, 10, 2000, 5000, 0,  4,  8,  6, 13, 22,  0, 3, 0, 5, 0, 5},
+
+	/* FCC TYPE 4 */
+	{16, 15, 2000, 5000, 0,  4,  7, 11, 23, 22,  0, 3, 0, 5, 0, 11},
+};
+
+/**
+ * struct dfs_bin5pulse dfs_fcc_bin5pulses - FCC BIN5 pulses for Offload
+ *                                           chipsets.
+ */
+static struct dfs_bin5pulse dfs_fcc_bin5pulses[] = {
+	{5, 28, 105, 12, 22, 5},
+};
+
+/**
+ * struct dfs_bin5pulse dfs_jpn_bin5pulses - JAPAN BIN5 pulses for Offload
+ *                                           chipsets.
+ */
+static struct dfs_bin5pulse dfs_jpn_bin5pulses[] = {
+	{5, 28, 105, 12, 22, 5},
+};
+
+/**
+ * dfs_bin5pulse dfs_fcc_bin5pulses_ar900b - FCC BIN5 pulses for AR9300
+ *                                           chipsets.
+ *
+ * WAR : IR 42631
+ * Beeliner 2 is tested at -65dbm as opposed to -62 dbm.
+ * For FCC/JPN chirping pulses, HW reports RSSI value that is lower by 2dbm
+ * when we enable noise floor claibration. This is specially true for
+ * frequencies that are greater than center frequency and in VHT80 mode.
+ */
+
+static struct dfs_bin5pulse dfs_fcc_bin5pulses_ar900b[] = {
+	{5, 28, 105, 12, 20, 5},
+};
+
+/**
+ * dfs_bin5pulse dfs_jpn_bin5pulses_ar900b - JAPAN BIN5 pulses for AR9300
+ *                                           chipsets.
+ */
+static struct dfs_bin5pulse dfs_jpn_bin5pulses_ar900b[] = {
+	{5, 28, 105, 12, 20, 5},
+};
+
+/**
+ * dfs_bin5pulse dfs_fcc_bin5pulses_qca9984 - FCC BIN5 pulses for QCA9984
+ *                                            chipsets.
+ * WAR : IR-83400
+ * Cascade is tested at -65dbm as opposed to -62 dbm.
+ * For FCC/JPN chirping pulses, HW reports RSSI value that is significantly
+ * lower at left edge especially in HT80_80 mode. Also, duration may be
+ * significantly low. This can result in false detection and we may have to
+ * raise the threshold.
+ */
+static struct dfs_bin5pulse dfs_fcc_bin5pulses_qca9984[] = {
+	{5, 20, 105, 12, 20, 0},
+};
+
+/**
+ * dfs_bin5pulse dfs_jpn_bin5pulses_qca9984 - JAPAN BIN5 pulses for QCA9984
+ *                                            chipsets.
+ */
+static struct dfs_bin5pulse dfs_jpn_bin5pulses_qca9984[] = {
+	{5, 20, 105, 12, 20, 0},
+};
+
+/**
+ * dfs_pulse dfs_etsi_radars - ETSI radar table.
+ */
+static struct dfs_pulse dfs_etsi_radars[] = {
+
+	/* EN 302 502 frequency hopping pulse */
+	/* PRF 3000, 1us duration, 9 pulses per burst */
+	{9,   1, 3000, 3000, 1,  4,  5,  0,  1, 18,  0, 0, 1,  1000, 0, 40},
+	/* PRF 4500, 20us duration, 9 pulses per burst */
+	{9,  20, 4500, 4500, 1,  4,  5, 19, 21, 18,  0, 0, 1,  1000, 0, 41},
+
+	/* TYPE staggered pulse */
+	/* Type 5*/
+	/* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */
+	{30,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 5, 0, 31},
+	/* Type 6 */
+	/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */
+	{30,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 5, 0, 32},
+
+	/* constant PRF based */
+	/* Type 1 */
+	/* 0.8-5us, 200  300 PRF, 10 pulses */
+	{10, 5,   200,  400, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 33},
+	{10, 5,   400,  600, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 37},
+	{10, 5,   600,  800, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 38},
+	{10, 5,   800, 1000, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 39},
+	/* {10, 5,   200, 1000, 0,  6,  5,  0,  8, 15, 0,   0, 2, 5, 33}, */
+
+	/* Type 2 */
+	/* 0.8-15us, 200-1600 PRF, 15 pulses */
+	{15, 15,  200, 1600, 0,  4, 8,  0, 18, 24, 0,   0, 0, 5, 0, 34},
+
+	/* Type 3 */
+	/* 0.8-15us, 2300-4000 PRF, 25 pulses*/
+	{25, 15, 2300, 4000, 0,  4, 10, 0, 18, 24, 0,   0, 0, 5, 0, 35},
+
+	/* Type 4 */
+	/* 20-30us, 2000-4000 PRF, 20 pulses*/
+	{20, 30, 2000, 4000, 0,  4, 6, 19, 33, 24, 0,   0, 0, 24,  1, 36},
+};
+
+/**
+ * dfs_pulse dfs_china_radars - CHINA radar table.
+ */
+static struct dfs_pulse dfs_china_radars[] = {
+
+	/* TYPE staggered pulse */
+	/* Type 5*/
+	/* 0.8-2us, 2-3 bursts,300-400 PRF, 12 pulses each */
+	{36,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 51},
+	/* Type 6 */
+	/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 16 pulses each */
+	{48,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 52},
+
+	/* constant PRF based */
+	/* Type 1 */
+	/* 0.5-5us, 200  1000 PRF, 12 pulses */
+	{12, 5,   200,  400, 0, 24,  5,  0,  8, 15, 0,   0, 2, 53},
+	{12, 5,   400,  600, 0, 24,  5,  0,  8, 15, 0,   0, 2, 57},
+	{12, 5,   600,  800, 0, 24,  5,  0,  8, 15, 0,   0, 2, 58},
+	{12, 5,   800, 1000, 0, 24,  5,  0,  8, 15, 0,   0, 2, 59},
+
+	/* Type 2 */
+	/* 0.5-15us, 200-1600 PRF, 16 pulses */
+	{16, 15,  200, 1600, 0, 24, 8,  0, 18, 24, 0,   0, 0, 54},
+
+	/* Type 3 */
+	/* 0.5-30us, 2300-4000 PRF, 24 pulses*/
+	{24, 15, 2300, 4000,  0, 24, 10, 0, 33, 24, 0,   0, 0, 55},
+
+	/* Type 4 */
+	/* 20-30us, 2000-4000 PRF, 20 pulses*/
+	{20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0,   0, 0, 56},
+
+	/* 1us, 1000 PRF, 20 pulses */
+	/* 1000 us PRI */
+	{20,  1, 1000, 1000, 0,  6,  6,  0,  1, 18,  0, 3, 0, 50},
+};
+
+/**
+ * dfs_pulse dfs_korea_radars - KOREA radar table.
+ */
+static struct dfs_pulse dfs_korea_radars[] = {
+	/* Korea Type 1 */
+	{18,  1,  700, 700,  0, 4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 40},
+
+	/* Korea Type 2 */
+	{10,  1, 1800, 1800, 0, 4,  4,  0,  1, 18,  0, 3,  1, 5, 0, 41},
+
+	/* Korea Type 3 */
+	{70,  1,  330, 330,  0, 4, 20,  0,  2, 18,  0, 3,  1, 5, 0, 42},
+
+	/* Korea Type 4 */
+	{3,   1, 3003, 3003, 1, 7,  2,  0,  1, 18,  0, 0, 1,  1000, 0, 43},
+};
+
+#define RSSI_THERSH_AR900B    15
+
+/**
+ * dfs_assign_fcc_pulse_table() - Assign FCC pulse table
+ * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
+ * @target_type: Target type.
+ * @tx_ops: target tx ops.
+ */
+static inline void dfs_assign_fcc_pulse_table(
+		struct wlan_dfs_radar_tab_info *rinfo,
+		uint32_t target_type,
+		struct wlan_lmac_if_target_tx_ops *tx_ops)
+{
+	rinfo->dfs_radars = dfs_fcc_radars;
+	rinfo->numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
+
+	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
+			tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
+		rinfo->b5pulses = dfs_fcc_bin5pulses_ar900b;
+		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_ar900b);
+	} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
+			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
+		rinfo->b5pulses = dfs_fcc_bin5pulses_qca9984;
+		rinfo->numb5radars =
+			QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_qca9984);
+	} else {
+		rinfo->b5pulses = dfs_fcc_bin5pulses;
+		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
+	}
+}
+
+void dfs_get_po_radars(struct wlan_dfs *dfs)
+{
+	struct wlan_dfs_radar_tab_info rinfo;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_target_tx_ops *tx_ops;
+	int i;
+	uint32_t target_type;
+	int dfsdomain = DFS_FCC_DOMAIN;
+	uint16_t ch_freq;
+	uint16_t regdmn;
+
+	/* Fetch current radar patterns from the lmac */
+	qdf_mem_zero(&rinfo, sizeof(rinfo));
+
+	/*
+	 * Look up the current DFS regulatory domain and decide
+	 * which radar pulses to use.
+	 */
+	dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj);
+	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
+
+	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+	if (!psoc) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "psoc is NULL");
+		return;
+	}
+
+	tx_ops = &(psoc->soc_cb.tx_ops.target_tx_ops);
+	switch (dfsdomain) {
+	case DFS_FCC_DOMAIN:
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "FCC domain");
+		rinfo.dfsdomain = DFS_FCC_DOMAIN;
+		dfs_assign_fcc_pulse_table(&rinfo, target_type, tx_ops);
+		break;
+	case DFS_CN_DOMAIN:
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+				"FCC domain -- Country China(156) override FCC radar pattern"
+				);
+		rinfo.dfsdomain = DFS_FCC_DOMAIN;
+		/*
+		 * China uses a radar pattern that is similar to ETSI but it
+		 * follows FCC in all other respect like transmit power, CCA
+		 * threshold etc.
+		 */
+		rinfo.dfs_radars = dfs_china_radars;
+		rinfo.numradars = QDF_ARRAY_SIZE(dfs_china_radars);
+		rinfo.b5pulses = NULL;
+		rinfo.numb5radars = 0;
+		break;
+	case DFS_ETSI_DOMAIN:
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ETSI domain");
+		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
+
+		ch_freq = dfs->dfs_curchan->dfs_ch_freq;
+		regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj);
+
+		if ((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) &&
+				DFS_CURCHAN_IS_58GHz(ch_freq)) {
+			rinfo.dfs_radars = dfs_etsi_radars;
+			rinfo.numradars = QDF_ARRAY_SIZE(dfs_etsi_radars);
+		} else {
+			uint8_t offset = ETSI_LEGACY_PULSE_ARR_OFFSET;
+
+			rinfo.dfs_radars = &dfs_etsi_radars[offset];
+			rinfo.numradars =
+				QDF_ARRAY_SIZE(dfs_etsi_radars) - offset;
+		}
+		rinfo.b5pulses = NULL;
+		rinfo.numb5radars = 0;
+		break;
+	case DFS_KR_DOMAIN:
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+				"ETSI domain -- Korea(412)");
+		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
+
+		/*
+		 * So far we have treated Korea as part of ETSI and did not
+		 * support any radar patters specific to Korea other than
+		 * standard ETSI radar patterns. Ideally we would want to
+		 * treat Korea as a different domain. This is something that
+		 * we will address in the future. However, for now override
+		 * ETSI tables for Korea.
+		 */
+		rinfo.dfs_radars = dfs_korea_radars;
+		rinfo.numradars = QDF_ARRAY_SIZE(dfs_korea_radars);
+		rinfo.b5pulses = NULL;
+		rinfo.numb5radars = 0;
+		break;
+	case DFS_MKK4_DOMAIN:
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "MKK4 domain");
+		rinfo.dfsdomain = DFS_MKK4_DOMAIN;
+		rinfo.dfs_radars = dfs_mkk4_radars;
+		rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars);
+
+		if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
+				tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
+			rinfo.b5pulses = dfs_jpn_bin5pulses_ar900b;
+			rinfo.numb5radars = QDF_ARRAY_SIZE(
+					dfs_jpn_bin5pulses_ar900b);
+		} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
+				tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
+			rinfo.b5pulses = dfs_jpn_bin5pulses_qca9984;
+			rinfo.numb5radars = QDF_ARRAY_SIZE
+				(dfs_jpn_bin5pulses_qca9984);
+		} else {
+			rinfo.b5pulses = dfs_jpn_bin5pulses;
+			rinfo.numb5radars = QDF_ARRAY_SIZE(
+					dfs_jpn_bin5pulses);
+		}
+		break;
+	default:
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "UNINIT domain");
+		rinfo.dfsdomain = DFS_UNINIT_DOMAIN;
+		rinfo.dfs_radars = NULL;
+		rinfo.numradars = 0;
+		rinfo.b5pulses = NULL;
+		rinfo.numb5radars = 0;
+		break;
+	}
+
+	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
+			tx_ops->tgt_is_tgt_type_ipq4019(target_type) ||
+			tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
+			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
+		/* Beeliner WAR: lower RSSI threshold to improve detection of
+		 * certian radar types
+		 */
+		/* Cascade WAR:
+		 * Cascade can report lower RSSI near the channel boundary then
+		 * expected. It can also report significantly low RSSI at center
+		 * (as low as 16) at center. So we are lowering threshold for
+		 * all types of radar for * Cascade.
+		 * This may increase the possibility of false radar detection.
+		 * IR -- 083703, 083398, 083387
+		 */
+
+		for (i = 0; i < rinfo.numradars; i++)
+			rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B;
+	}
+
+	dfs_init_radar_filters(dfs, &rinfo);
+}

+ 21 - 22
umac/dfs/core/src/filtering/dfs_process_phyerr.c

@@ -23,6 +23,7 @@
  */
 
 #include "../dfs.h"
+#include "../dfs_zero_cac.h"
 #include "../dfs_channel.h"
 #include "wlan_dfs_mlme_api.h"
 #include "../dfs_internal.h"
@@ -479,28 +480,6 @@ static inline void dfs_filter_short_pulses(
 	}
 }
 
-/**
- * dfs_is_second_seg_radar_disabled() - Check for second segment radar disabled.
- * @dfs: Pointer to wlan_dfs structure.
- * @seg_id: Segment id.
- *
- * Return: true if the second segment RADAR is enabled else false.
- */
-static inline bool dfs_is_second_seg_radar_disabled(
-		struct wlan_dfs *dfs,
-		int seg_id)
-{
-	if ((seg_id == SEG_ID_SECONDARY) &&
-			!(dfs->dfs_proc_phyerr &
-				DFS_SECOND_SEGMENT_RADAR_EN)) {
-		dfs_debug(dfs, WLAN_DEBUG_DFS3,
-				"Do not process PHY error data from Second segment, DFS_SECOND_SEGMENT_RADAR_EN is not enabled");
-		return true;
-	}
-
-	return false;
-}
-
 /**
  * dfs_set_chan_index() - Set channel index.
  * @dfs: Pointer to wlan_dfs structure.
@@ -523,6 +502,26 @@ static inline void dfs_set_chan_index(
 	}
 }
 
+/**
+ * dfs_is_second_seg_radar_disabled() - Check for second segment radar disabled.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @seg_id: Segment id.
+ *
+ * Return: true if the second segment RADAR is enabled else false.
+ */
+static bool dfs_is_second_seg_radar_disabled(
+		struct wlan_dfs *dfs, int seg_id)
+{
+	if ((seg_id == SEG_ID_SECONDARY) &&
+			!(dfs->dfs_proc_phyerr & DFS_SECOND_SEGMENT_RADAR_EN)) {
+		dfs_debug(dfs, WLAN_DEBUG_DFS3,
+				"Second segment radar detection is disabled");
+		return true;
+	}
+
+	return false;
+}
+
 void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 		uint8_t r_rssi, uint8_t r_ext_rssi, uint32_t r_rs_tstamp,
 		uint64_t r_fulltsf)

+ 2 - 20
umac/dfs/core/src/filtering/dfs_process_radarevent.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2018 The Linux Foundation. All rights reserved.
  * Copyright (c) 2002-2010, Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
@@ -22,6 +22,7 @@
  */
 
 #include "../dfs.h"
+#include "../dfs_zero_cac.h"
 #include "../dfs_channel.h"
 #include "../dfs_internal.h"
 #include "../dfs_process_radar_found_ind.h"
@@ -498,25 +499,6 @@ static inline void dfs_radarfound_reset_vars(
 	}
 }
 
-int dfs_radarevent_basic_sanity(struct wlan_dfs *dfs,
-	struct dfs_channel *chan)
-{
-	if (!(dfs->dfs_second_segment_bangradar ||
-				dfs_is_precac_timer_running(dfs)))
-		if (!(WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(chan))) {
-			dfs_debug(dfs, WLAN_DEBUG_DFS2,
-					"radar event on non-DFS chan");
-			if (!(dfs->dfs_is_offload_enabled)) {
-				dfs_reset_radarq(dfs);
-				dfs_reset_alldelaylines(dfs);
-				dfs->dfs_bangradar = 0;
-			}
-			return 0;
-		}
-
-	return 1;
-}
-
 /**
  * dfs_handle_bangradar - Handle the case of bangradar
  * @dfs: Pointer to wlan_dfs structure.

+ 257 - 466
umac/dfs/core/src/filtering/dfs_radar.c

@@ -15,515 +15,306 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/**
- * DOC: This file has radar table and initialization function for Beeliner
- * family of chipsets.
- */
-
 #include "../dfs.h"
+#include "../dfs_zero_cac.h"
 #include "wlan_dfs_mlme_api.h"
-#include "wlan_dfs_utils_api.h"
 #include "wlan_dfs_lmac_api.h"
+#include "../dfs_partial_offload_radar.h"
+#include "../dfs_direct_attach_radar.h"
 #include "../dfs_internal.h"
 
-/**
- * struct dfs_pulse dfs_fcc_radars - FCC radar table for Offload chipsets.
- */
-struct dfs_pulse dfs_fcc_radars[] = {
-	/* FCC TYPE 1 */
-	{18,  1,  700, 700, 0,  4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 0},
-	{18,  1,  350, 350, 0,  4,  5,  0,  1, 18,  0, 3,  0, 5, 0, 0},
-
-	/* FCC TYPE 6 */
-	{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0,  1, 1000, 0, 1},
-
-	/* FCC TYPE 2 */
-	{23, 5, 4347, 6666, 0,  4, 11,  0,  7, 22,  0, 3,  0, 5, 0, 2},
-
-	/* FCC TYPE 3 */
-	{18, 10, 2000, 5000, 0,  4,  8,  6, 13, 22,  0, 3, 0, 5, 0, 5},
-
-	/* FCC TYPE 4 */
-	{16, 15, 2000, 5000, 0,  4,  7, 11, 23, 22,  0, 3, 0, 5, 0, 11},
-
-	/* FCC NEW TYPE 1 */
-	/* 518us to 938us pulses (min 56 pulses) */
-	{57, 1, 1066, 1930, 0, 4,  20,  0,  1, 22,  0, 3,  0, 5, 0, 21},
-
-	/* 938us to 2000 pulses (min 26 pulses) */
-	{27, 1,  500, 1066, 0, 4,  13,  0,  1, 22,  0, 3,  0, 5, 0, 22},
-
-	/* 2000 to 3067us pulses (min 17 pulses) */
-	{18, 1,  325,  500, 0, 4,  9,   0,  1, 22,  0, 3,  0, 5, 0, 23},
-};
-
-/**
- * struct dfs_pulse dfs_mkk4_radars - MKK4 radar table for Offload chipsets.
- */
-struct dfs_pulse dfs_mkk4_radars[] = {
-
-	/* following two filters are specific to Japan/MKK4 */
-	/* 1389 +/- 6 us */
-	{18,  1,  720,  720, 0,  4,  6,  0,  1, 18,  0, 3, 0, 5, 0, 17},
-
-	/* 4000 +/- 6 us */
-	{18,  4,  250,  250, 0,  4,  5,  1,  6, 18,  0, 3, 0, 5, 0, 18},
-
-	/* 3846 +/- 7 us */
-	{18,  5,  260,  260, 0,  4,  6,  1,  6, 18,  0, 3, 1, 5, 0, 19},
-
-	/* following filters are common to both FCC and JAPAN */
-
-	/* FCC TYPE 1 */
-	{18,  1,  700, 700, 0,  4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 0},
-	{18,  1,  350, 350, 0,  4,  5,  0,  1, 18,  0, 3,  0, 5, 0, 0},
+void dfs_get_radars(struct wlan_dfs *dfs)
+{
+	struct wlan_objmgr_psoc *psoc;
 
-	/* FCC TYPE 6 */
-	{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0, 1,  1000, 0, 1},
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
+		return;
+	}
 
-	/* FCC TYPE 2 */
-	{23, 5, 4347, 6666, 0,  4, 11,  0,  7, 22,  0, 3,  0, 5, 0, 2},
+	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+	if (!psoc) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "psoc is NULL");
+		return;
+	}
 
-	/* FCC TYPE 3 */
-	{18, 10, 2000, 5000, 0,  4,  8,  6, 13, 22,  0, 3, 0, 5, 0, 5},
+	if (wlan_objmgr_psoc_get_dev_type(psoc) == WLAN_DEV_OL) {
+		/* For Partial offload */
+		dfs_get_po_radars(dfs);
+	} else {
+		/* For Direct Attach (DA) */
+		dfs_get_da_radars(dfs);
+	}
+}
 
-	/* FCC TYPE 4 */
-	{16, 15, 2000, 5000, 0,  4,  7, 11, 23, 22,  0, 3, 0, 5, 0, 11},
-};
+int dfs_radar_disable(struct wlan_dfs *dfs)
+{
+	dfs->dfs_proc_phyerr &= ~DFS_AR_EN;
+	dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
 
-/**
- * struct dfs_bin5pulse dfs_fcc_bin5pulses - FCC BIN5 pulses for Offload
- *                                           chipsets.
- */
-struct dfs_bin5pulse dfs_fcc_bin5pulses[] = {
-	{6, 28, 105, 12, 18, 5},
-};
+	return 0;
+}
 
-/**
- * struct dfs_bin5pulse dfs_jpn_bin5pulses - JAPAN BIN5 pulses for Offload
- *                                           chipsets.
- */
-struct dfs_bin5pulse dfs_jpn_bin5pulses[] = {
-	{5, 28, 105, 12, 22, 5},
-};
+void dfs_phyerr_param_copy(struct wlan_dfs_phyerr_param *dst,
+		struct wlan_dfs_phyerr_param *src)
+{
+	qdf_mem_copy(dst, src, sizeof(*dst));
+}
 
-/**
- * dfs_bin5pulse dfs_fcc_bin5pulses_ar900b - FCC BIN5 pulses for AR9300
- *                                           chipsets.
- *
- * WAR : IR 42631
- * Beeliner 2 is tested at -65dbm as opposed to -62 dbm.
- * For FCC/JPN chirping pulses, HW reports RSSI value that is lower by 2dbm
- * when we enable noise floor claibration. This is specially true for
- * frequencies that are greater than center frequency and in VHT80 mode.
- */
+struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index,
+		int ext_chan_flag)
+{
+	struct dfs_state *rs = NULL;
+	struct dfs_channel *cmp_ch, cmp_ch1;
+	int i;
+	QDF_STATUS err;
 
-struct dfs_bin5pulse dfs_fcc_bin5pulses_ar900b[] = {
-	{5, 28, 105, 12, 20, 5},
-};
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
+		return NULL;
+	}
+	cmp_ch = &cmp_ch1;
+	if (ext_chan_flag) {
+		err = dfs_mlme_get_extchan(dfs->dfs_pdev_obj,
+				&(cmp_ch->dfs_ch_freq),
+				&(cmp_ch->dfs_ch_flags),
+				&(cmp_ch->dfs_ch_flagext),
+				&(cmp_ch->dfs_ch_ieee),
+				&(cmp_ch->dfs_ch_vhtop_ch_freq_seg1),
+				&(cmp_ch->dfs_ch_vhtop_ch_freq_seg2));
+
+		if (err == QDF_STATUS_SUCCESS) {
+			dfs_debug(dfs, WLAN_DEBUG_DFS2,
+					"Extension channel freq = %u flags=0x%x",
+					cmp_ch->dfs_ch_freq,
+					cmp_ch->dfs_ch_flagext);
+		} else
+			return NULL;
+	} else {
+		cmp_ch = dfs->dfs_curchan;
+		dfs_debug(dfs, WLAN_DEBUG_DFS2,
+				"Primary channel freq = %u flags=0x%x",
+				cmp_ch->dfs_ch_freq, cmp_ch->dfs_ch_flagext);
+	}
 
-/**
- * dfs_bin5pulse dfs_jpn_bin5pulses_ar900b - JAPAN BIN5 pulses for AR9300
- *                                           chipsets.
- */
-struct dfs_bin5pulse dfs_jpn_bin5pulses_ar900b[] = {
-	{5, 28, 105, 12, 20, 5},
-};
-
-/**
- * dfs_bin5pulse dfs_fcc_bin5pulses_qca9984 - FCC BIN5 pulses for QCA9984
- *                                            chipsets.
- * WAR : IR-83400
- * Cascade is tested at -65dbm as opposed to -62 dbm.
- * For FCC/JPN chirping pulses, HW reports RSSI value that is significantly
- * lower at left edge especially in HT80_80 mode. Also, duration may be
- * significantly low. This can result in false detection and we may have to
- * raise the threshold.
- */
-struct dfs_bin5pulse dfs_fcc_bin5pulses_qca9984[] = {
-	{5, 20, 105, 12, 20, 0},
-};
+	for (i = 0; i < DFS_NUM_RADAR_STATES; i++) {
+		if ((dfs->dfs_radar[i].rs_chan.dfs_ch_freq ==
+					cmp_ch->dfs_ch_freq) &&
+				(dfs->dfs_radar[i].rs_chan.dfs_ch_flags ==
+				 cmp_ch->dfs_ch_flags)
+		   ) {
+			if (index != NULL)
+				*index = (uint8_t)i;
+			return &(dfs->dfs_radar[i]);
+		}
+	}
+	/* No existing channel found, look for first free channel state entry.*/
+	for (i = 0; i < DFS_NUM_RADAR_STATES; i++) {
+		if (dfs->dfs_radar[i].rs_chan.dfs_ch_freq == 0) {
+			rs = &(dfs->dfs_radar[i]);
+			/* Found one, set channel info and default thresholds.*/
+			rs->rs_chan = *cmp_ch;
 
-/**
- * dfs_bin5pulse dfs_jpn_bin5pulses_qca9984 - JAPAN BIN5 pulses for QCA9984
- *                                            chipsets.
- */
-struct dfs_bin5pulse dfs_jpn_bin5pulses_qca9984[] = {
-	{5, 20, 105, 12, 20, 0},
-};
+			/* Copy the parameters from the default set. */
+			dfs_phyerr_param_copy(&rs->rs_param,
+					&dfs->dfs_defaultparams);
 
-/**
- * dfs_pulse dfs_etsi_radars - ETSI radar table.
- */
-struct dfs_pulse dfs_etsi_radars[] = {
-
-	/* EN 302 502 frequency hopping pulse */
-	/* PRF 3000, 1us duration, 9 pulses per burst */
-	{9,   1, 3000, 3000, 1,  4,  5,  0,  1, 18,  0, 0, 1,  1000, 0, 40},
-	/* PRF 4500, 20us duration, 9 pulses per burst */
-	{9,  20, 4500, 4500, 1,  4,  5, 19, 21, 18,  0, 0, 1,  1000, 0, 41},
-
-	/* TYPE staggered pulse */
-	/* Type 5*/
-	/* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */
-	{30,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 5, 0, 31},
-	/* Type 6 */
-	/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */
-	{30,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 5, 0, 32},
-
-	/* constant PRF based */
-	/* Type 1 */
-	/* 0.8-5us, 200  300 PRF, 10 pulses */
-	{10, 5,   200,  400, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 33},
-	{10, 5,   400,  600, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 37},
-	{10, 5,   600,  800, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 38},
-	{10, 5,   800, 1000, 0,  4,  5,  0,  8, 15, 0,   0, 2, 5, 0, 39},
-	/* {10, 5,   200, 1000, 0,  6,  5,  0,  8, 15, 0,   0, 2, 5, 33}, */
-
-	/* Type 2 */
-	/* 0.8-15us, 200-1600 PRF, 15 pulses */
-	{15, 15,  200, 1600, 0,  4, 8,  0, 18, 24, 0,   0, 0, 5, 0, 34},
-
-	/* Type 3 */
-	/* 0.8-15us, 2300-4000 PRF, 25 pulses*/
-	{25, 15, 2300, 4000, 0,  4, 10, 0, 18, 24, 0,   0, 0, 5, 0, 35},
-
-	/* Type 4 */
-	/* 20-30us, 2000-4000 PRF, 20 pulses*/
-	{20, 30, 2000, 4000, 0,  4, 6, 19, 33, 24, 0,   0, 0, 24,  1, 36},
-};
-
-/**
- * dfs_pulse dfs_china_radars - CHINA radar table.
- */
-struct dfs_pulse dfs_china_radars[] = {
-
-	/* TYPE staggered pulse */
-	/* Type 5*/
-	/* 0.8-2us, 2-3 bursts,300-400 PRF, 12 pulses each */
-	{36,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 51},
-	/* Type 6 */
-	/* 0.8-2us, 2-3 bursts, 400-1200 PRF, 16 pulses each */
-	{48,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 52},
-
-	/* constant PRF based */
-	/* Type 1 */
-	/* 0.5-5us, 200  1000 PRF, 12 pulses */
-	{12, 5,   200,  400, 0, 24,  5,  0,  8, 15, 0,   0, 2, 53},
-	{12, 5,   400,  600, 0, 24,  5,  0,  8, 15, 0,   0, 2, 57},
-	{12, 5,   600,  800, 0, 24,  5,  0,  8, 15, 0,   0, 2, 58},
-	{12, 5,   800, 1000, 0, 24,  5,  0,  8, 15, 0,   0, 2, 59},
-
-	/* Type 2 */
-	/* 0.5-15us, 200-1600 PRF, 16 pulses */
-	{16, 15,  200, 1600, 0, 24, 8,  0, 18, 24, 0,   0, 0, 54},
-
-	/* Type 3 */
-	/* 0.5-30us, 2300-4000 PRF, 24 pulses*/
-	{24, 15, 2300, 4000,  0, 24, 10, 0, 33, 24, 0,   0, 0, 55},
-
-	/* Type 4 */
-	/* 20-30us, 2000-4000 PRF, 20 pulses*/
-	{20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0,   0, 0, 56},
-
-	/* 1us, 1000 PRF, 20 pulses */
-	/* 1000 us PRI */
-	{20,  1, 1000, 1000, 0,  6,  6,  0,  1, 18,  0, 3, 0, 50},
-};
-
-/**
- * dfs_pulse dfs_korea_radars - KOREA radar table.
- */
-struct dfs_pulse dfs_korea_radars[] = {
-	/* Korea Type 1 */
-	{18,  1,  700, 700,  0, 4,  5,  0,  1, 18,  0, 3,  1, 5, 0, 40},
+			if (index != NULL)
+				*index = (uint8_t)i;
 
-	/* Korea Type 2 */
-	{10,  1, 1800, 1800, 0, 4,  4,  0,  1, 18,  0, 3,  1, 5, 0, 41},
+			return rs;
+		}
+	}
+	dfs_debug(dfs, WLAN_DEBUG_DFS2, "No more radar states left.");
 
-	/* Korea Type 3 */
-	{70,  1,  330, 330,  0, 4, 20,  0,  2, 18,  0, 3,  1, 5, 0, 42},
+	return NULL;
+}
 
-	/* Korea Type 4 */
-	{3,   1, 3003, 3003, 1, 7,  2,  0,  1, 18,  0, 0, 1,  1000, 0, 43},
-};
+void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode)
+{
+	int is_ext_ch;
+	int is_fastclk = 0;
+	struct dfs_channel *ext_ch, extchan;
+	QDF_STATUS err = QDF_STATUS_E_FAILURE;
 
-#define RSSI_THERSH_AR900B    15
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
+		return;
+	}
 
-/**
- * dfs_assign_fcc_pulse_table() - Assign FCC pulse table
- * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
- * @target_type: Target type.
- * @tx_ops: target tx ops.
- */
-static inline void dfs_assign_fcc_pulse_table(
-		struct wlan_dfs_radar_tab_info *rinfo,
-		uint32_t target_type,
-		struct wlan_lmac_if_target_tx_ops *tx_ops)
-{
-	rinfo->dfs_radars = dfs_fcc_radars;
-	rinfo->numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
-
-	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
-			tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
-		rinfo->b5pulses = dfs_fcc_bin5pulses_ar900b;
-		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_ar900b);
-	} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
-			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
-		rinfo->b5pulses = dfs_fcc_bin5pulses_qca9984;
-		rinfo->numb5radars =
-			QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_qca9984);
-	} else {
-		rinfo->b5pulses = dfs_fcc_bin5pulses;
-		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
+	is_ext_ch = WLAN_IS_CHAN_11N_HT40(dfs->dfs_curchan);
+	lmac_dfs_disable(dfs->dfs_pdev_obj, no_cac);
+	/*
+	 * In all modes, if the primary is DFS then we have to
+	 * enable radar detection. In HT80_80, we can have
+	 * primary non-DFS 80MHz with extension 80MHz DFS.
+	 */
+	if ((WLAN_IS_CHAN_DFS(dfs->dfs_curchan) ||
+				((WLAN_IS_CHAN_11AC_VHT160(dfs->dfs_curchan) ||
+				  WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan))
+				 &&
+				 WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan))) ||
+		(dfs_is_precac_timer_running(dfs))) {
+		struct dfs_state *rs_pri = NULL, *rs_ext = NULL;
+		uint8_t index_pri, index_ext;
+
+		dfs->dfs_proc_phyerr |= DFS_AR_EN;
+		dfs->dfs_proc_phyerr |= DFS_RADAR_EN;
+		dfs->dfs_proc_phyerr |= DFS_SECOND_SEGMENT_RADAR_EN;
+
+		ext_ch = &extchan;
+		if (is_ext_ch)
+			err = dfs_mlme_get_extchan(dfs->dfs_pdev_obj,
+					&(ext_ch->dfs_ch_freq),
+					&(ext_ch->dfs_ch_flags),
+					&(ext_ch->dfs_ch_flagext),
+					&(ext_ch->dfs_ch_ieee),
+					&(ext_ch->dfs_ch_vhtop_ch_freq_seg1),
+					&(ext_ch->dfs_ch_vhtop_ch_freq_seg2));
+
+
+		dfs_reset_alldelaylines(dfs);
+
+		rs_pri = dfs_getchanstate(dfs, &index_pri, 0);
+		if (err == QDF_STATUS_SUCCESS)
+			rs_ext = dfs_getchanstate(dfs, &index_ext, 1);
+
+		if (rs_pri != NULL && ((err == QDF_STATUS_E_FAILURE) ||
+					(rs_ext != NULL))) {
+			struct wlan_dfs_phyerr_param pe;
+
+			qdf_mem_set(&pe, sizeof(pe), '\0');
+
+			if (index_pri != dfs->dfs_curchan_radindex)
+				dfs_reset_alldelaylines(dfs);
+
+			dfs->dfs_curchan_radindex = (int16_t)index_pri;
+
+			if (rs_ext)
+				dfs->dfs_extchan_radindex = (int16_t)index_ext;
+
+			dfs_phyerr_param_copy(&pe, &rs_pri->rs_param);
+			dfs_debug(dfs, WLAN_DEBUG_DFS3,
+					"firpwr=%d, rssi=%d, height=%d, prssi=%d, inband=%d, relpwr=%d, relstep=%d, maxlen=%d",
+					pe.pe_firpwr,
+					pe.pe_rrssi, pe.pe_height,
+					pe.pe_prssi, pe.pe_inband,
+					pe.pe_relpwr, pe.pe_relstep,
+					pe.pe_maxlen);
+
+			lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk,
+					&pe, dfs->dfsdomain);
+			dfs_debug(dfs, WLAN_DEBUG_DFS,
+					"Enabled radar detection on channel %d",
+					dfs->dfs_curchan->dfs_ch_freq);
+
+			dfs->dur_multiplier = is_fastclk ?
+				DFS_FAST_CLOCK_MULTIPLIER :
+				DFS_NO_FAST_CLOCK_MULTIPLIER;
+
+			dfs_debug(dfs, WLAN_DEBUG_DFS3,
+					"duration multiplier is %d",
+					dfs->dur_multiplier);
+		} else
+			dfs_debug(dfs, WLAN_DEBUG_DFS,
+					"No more radar states left");
 	}
 }
-void ol_if_dfs_configure(struct wlan_dfs *dfs)
-{
-	struct wlan_dfs_radar_tab_info rinfo;
-	struct wlan_objmgr_psoc *psoc;
-	struct wlan_lmac_if_target_tx_ops *tx_ops;
-	int i;
-	uint32_t target_type;
-	int dfsdomain = DFS_FCC_DOMAIN;
-	uint16_t ch_freq;
-	uint16_t regdmn;
 
-	/* Fetch current radar patterns from the lmac */
-	qdf_mem_zero(&rinfo, sizeof(rinfo));
+int dfs_set_thresholds(struct wlan_dfs *dfs, const uint32_t threshtype,
+		const uint32_t value)
+{
+	int16_t chanindex;
+	struct dfs_state *rs;
+	struct wlan_dfs_phyerr_param pe;
+	int is_fastclk = 0;
 
-	/*
-	 * Look up the current DFS regulatory domain and decide
-	 * which radar pulses to use.
-	 */
-	dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj);
-	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
+		return 0;
+	}
 
-	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
-	if (!psoc) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "psoc is NULL");
-		return;
+	chanindex = dfs->dfs_curchan_radindex;
+	if ((chanindex < 0) || (chanindex >= DFS_NUM_RADAR_STATES)) {
+		dfs_debug(dfs, WLAN_DEBUG_DFS1,
+				"%s: chanindex = %d, DFS_NUM_RADAR_STATES=%d\n",
+				__func__,
+				chanindex,
+				DFS_NUM_RADAR_STATES);
+		return 0;
 	}
 
-	tx_ops = &(psoc->soc_cb.tx_ops.target_tx_ops);
-	switch (dfsdomain) {
-	case DFS_FCC_DOMAIN:
-		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "FCC domain");
-		rinfo.dfsdomain = DFS_FCC_DOMAIN;
-		dfs_assign_fcc_pulse_table(&rinfo, target_type, tx_ops);
+	dfs_debug(dfs, WLAN_DEBUG_DFS,
+			"threshtype=%d, value=%d", threshtype, value);
+
+	wlan_dfs_phyerr_init_noval(&pe);
+
+	rs = &(dfs->dfs_radar[chanindex]);
+	switch (threshtype) {
+	case DFS_PARAM_FIRPWR:
+		rs->rs_param.pe_firpwr = (int32_t) value;
+		pe.pe_firpwr = value;
 		break;
-	case DFS_CN_DOMAIN:
-		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
-				"FCC domain -- Country China(156) override FCC radar pattern"
-				);
-		rinfo.dfsdomain = DFS_FCC_DOMAIN;
-		/*
-		 * China uses a radar pattern that is similar to ETSI but it
-		 * follows FCC in all other respect like transmit power, CCA
-		 * threshold etc.
-		 */
-		rinfo.dfs_radars = dfs_china_radars;
-		rinfo.numradars = QDF_ARRAY_SIZE(dfs_china_radars);
-		rinfo.b5pulses = NULL;
-		rinfo.numb5radars = 0;
+	case DFS_PARAM_RRSSI:
+		rs->rs_param.pe_rrssi = value;
+		pe.pe_rrssi = value;
 		break;
-	case DFS_ETSI_DOMAIN:
-		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ETSI domain");
-		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
-
-		ch_freq = dfs->dfs_curchan->dfs_ch_freq;
-		regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj);
-
-		if ((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) &&
-				DFS_CURCHAN_IS_58GHz(ch_freq)) {
-			rinfo.dfs_radars = dfs_etsi_radars;
-			rinfo.numradars = QDF_ARRAY_SIZE(dfs_etsi_radars);
-		} else {
-			uint8_t offset = ETSI_LEGACY_PULSE_ARR_OFFSET;
-
-			rinfo.dfs_radars = &dfs_etsi_radars[offset];
-			rinfo.numradars =
-				QDF_ARRAY_SIZE(dfs_etsi_radars) - offset;
-		}
-		rinfo.b5pulses = NULL;
-		rinfo.numb5radars = 0;
+	case DFS_PARAM_HEIGHT:
+		rs->rs_param.pe_height = value;
+		pe.pe_height = value;
 		break;
-	case DFS_KR_DOMAIN:
-		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
-				"ETSI domain -- Korea(412)");
-		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
-
-		/*
-		 * So far we have treated Korea as part of ETSI and did not
-		 * support any radar patters specific to Korea other than
-		 * standard ETSI radar patterns. Ideally we would want to
-		 * treat Korea as a different domain. This is something that
-		 * we will address in the future. However, for now override
-		 * ETSI tables for Korea.
-		 */
-		rinfo.dfs_radars = dfs_korea_radars;
-		rinfo.numradars = QDF_ARRAY_SIZE(dfs_korea_radars);
-		rinfo.b5pulses = NULL;
-		rinfo.numb5radars = 0;
+	case DFS_PARAM_PRSSI:
+		rs->rs_param.pe_prssi = value;
+		pe.pe_prssi = value;
 		break;
-	case DFS_MKK4_DOMAIN:
-		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "MKK4 domain");
-		rinfo.dfsdomain = DFS_MKK4_DOMAIN;
-		rinfo.dfs_radars = dfs_mkk4_radars;
-		rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars);
-
-		if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
-				tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
-			rinfo.b5pulses = dfs_jpn_bin5pulses_ar900b;
-			rinfo.numb5radars = QDF_ARRAY_SIZE(
-					dfs_jpn_bin5pulses_ar900b);
-		} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
-				tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
-			rinfo.b5pulses = dfs_jpn_bin5pulses_qca9984;
-			rinfo.numb5radars = QDF_ARRAY_SIZE
-				(dfs_jpn_bin5pulses_qca9984);
-		} else {
-			rinfo.b5pulses = dfs_jpn_bin5pulses;
-			rinfo.numb5radars = QDF_ARRAY_SIZE(
-					dfs_jpn_bin5pulses);
-		}
+	case DFS_PARAM_INBAND:
+		rs->rs_param.pe_inband = value;
+		pe.pe_inband = value;
+		break;
+		/* 5413 specific */
+	case DFS_PARAM_RELPWR:
+		rs->rs_param.pe_relpwr = value;
+		pe.pe_relpwr = value;
+		break;
+	case DFS_PARAM_RELSTEP:
+		rs->rs_param.pe_relstep = value;
+		pe.pe_relstep = value;
+		break;
+	case DFS_PARAM_MAXLEN:
+		rs->rs_param.pe_maxlen = value;
+		pe.pe_maxlen = value;
 		break;
 	default:
-		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "UNINIT domain");
-		rinfo.dfsdomain = DFS_UNINIT_DOMAIN;
-		rinfo.dfs_radars = NULL;
-		rinfo.numradars = 0;
-		rinfo.b5pulses = NULL;
-		rinfo.numb5radars = 0;
+		dfs_debug(dfs, WLAN_DEBUG_DFS1,
+				"unknown threshtype (%d)", threshtype);
 		break;
 	}
 
-	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
-			tx_ops->tgt_is_tgt_type_ipq4019(target_type) ||
-			tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
-			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
-		/* Beeliner WAR: lower RSSI threshold to improve detection of
-		 * certian radar types
-		 */
-		/* Cascade WAR:
-		 * Cascade can report lower RSSI near the channel boundary then
-		 * expected. It can also report significantly low RSSI at center
-		 * (as low as 16) at center. So we are lowering threshold for
-		 * all types of radar for * Cascade.
-		 * This may increase the possibility of false radar detection.
-		 * IR -- 083703, 083398, 083387
-		 */
-
-		for (i = 0; i < rinfo.numradars; i++)
-			rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B;
-	}
 
-	dfs_init_radar_filters(dfs, &rinfo);
+	/*
+	 * The driver layer dfs_enable routine is tasked with translating
+	 * values from the global format to the per-device (HAL, offload)
+	 * format.
+	 */
+	lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk,
+			&pe, dfs->dfsdomain);
+
+	return 1;
 }
 
-void dfs_get_radars(struct wlan_dfs *dfs)
+int dfs_get_thresholds(struct wlan_dfs *dfs,
+		struct wlan_dfs_phyerr_param *param)
 {
-#define AR5212_DEVID_IBM            0x1014 /* IBM minipci ID */
-#define AR5212_AR2413               0x001a /* AR2413 aka Griffin-lite */
-#define AR5212_AR2413               0x001a /* AR2413 aka Griffin-lite */
-#define AR5212_AR5413               0x001b /* Eagle */
-#define AR5212_AR5424               0x001c /* Condor (PCI express) */
-#define AR5212_DEVID_FF19           0xff19 /* PCI express */
-#define AR5212_AR2417               0x001d /* Nala, PCI */
-#define AR5212_DEVID                0x0013 /* Final ar5212 devid */
-#define AR5212_FPGA                 0xf013 /* Emulation board */
-#define AR5212_DEFAULT              0x1113 /* No eeprom HW default */
-
-#define AR5416_DEVID_PCI            0x0023 /* AR5416 PCI (CB/MB) (Owl)*/
-#define AR5416_DEVID_PCIE           0x0024 /* AR5416 PCI-E (XB) (Owl) */
-#define AR5416_DEVID_AR9160_PCI     0x0027 /* AR9160 PCI (Sowl) */
-#define AR5416_AR9100_DEVID         0x000b /* AR9100 (Howl)    */
-#define AR5416_DEVID_AR9280_PCI     0x0029 /* PCI (Merlin) */
-#define AR5416_DEVID_AR9280_PCIE    0x002a /* PCIE (Merlin) */
-#define AR5416_DEVID_AR9285_PCIE    0x002b /* PCIE (Kite) */
-#define AR5416_DEVID_AR9285G_PCIE   0x002c /* PCIE (Kite G only) */
-#define AR5416_DEVID_AR9287_PCI     0x002d /* PCI (Kiwi) */
-#define AR5416_DEVID_AR9287_PCIE    0x002e /* PCIE (Kiwi) */
-
-#define AR9300_DEVID_AR9380_PCIE    0x0030 /* PCIE (Osprey) */
-#define AR9300_DEVID_AR9340         0x0031 /* Wasp */
-#define AR9300_DEVID_AR9485_PCIE    0x0032 /* Poseidon */
-#define AR9300_DEVID_AR9580_PCIE    0x0033 /* Peacock */
-#define AR9300_DEVID_AR1111_PCIE    0x0037 /* AR1111 */
-#define AR9300_DEVID_AR946X_PCIE    0x0034 /* Jupiter: 2x2 DB + BT - AR9462 */
-#define AR9300_DEVID_AR955X         0x0039 /* Scorpion */
-#define AR9300_DEVID_AR953X         0x003d /* Honey Bee */
-#define AR9300_DEVID_AR956X         0x003f /* Dragonfly */
-#define AR9300_DEVID_AR956X_PCIE    0x0036 /* Aphrodite: 1x1 DB + BT - AR9564 */
-#define AR9300_DEVID_EMU_PCIE       0xabcd
-
-	struct wlan_objmgr_psoc *psoc;
-
-	if (!dfs) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
-		return;
-	}
-
-	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
-	if (!psoc) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "psoc is NULL");
-		return;
-	}
+	qdf_mem_zero(param, sizeof(*param));
+	lmac_dfs_get_thresholds(dfs->dfs_pdev_obj, param);
 
-	if (wlan_objmgr_psoc_get_dev_type(psoc) == WLAN_DEV_OL) {
-		/* For offload chip */
-		ol_if_dfs_configure(dfs);
-	} else {
-		uint16_t devid = lmac_get_ah_devid(dfs->dfs_pdev_obj);
-		/* For DA chip*/
-
-		switch (devid) {
-		case AR5212_DEVID_IBM:
-		case AR5212_AR2413:
-		case AR5212_AR5413:
-		case AR5212_AR5424:
-		case AR5212_DEVID_FF19:
-			devid = AR5212_DEVID;
-		case AR5212_AR2417:
-		case AR5212_DEVID:
-		case AR5212_FPGA:
-		case AR5212_DEFAULT:
-			dfs_get_radars_for_ar5212(dfs);
-			break;
-		case AR5416_DEVID_PCI:
-		case AR5416_DEVID_PCIE:
-		case AR5416_DEVID_AR9160_PCI:
-		case AR5416_AR9100_DEVID:
-		case AR5416_DEVID_AR9280_PCI:
-		case AR5416_DEVID_AR9280_PCIE:
-		case AR5416_DEVID_AR9285_PCIE:
-		case AR5416_DEVID_AR9285G_PCIE:
-		case AR5416_DEVID_AR9287_PCI:
-		case AR5416_DEVID_AR9287_PCIE:
-			dfs_get_radars_for_ar5416(dfs);
-			break;
-		case AR9300_DEVID_AR9380_PCIE:
-		case AR9300_DEVID_AR9340:
-		case AR9300_DEVID_AR9485_PCIE:
-		case AR9300_DEVID_AR9580_PCIE:
-		case AR9300_DEVID_AR1111_PCIE:
-		case AR9300_DEVID_AR946X_PCIE:
-		case AR9300_DEVID_AR955X:
-		case AR9300_DEVID_AR953X:
-		case AR9300_DEVID_AR956X:
-		case AR9300_DEVID_AR956X_PCIE:
-		case AR9300_DEVID_EMU_PCIE:
-			dfs_get_radars_for_ar9300(dfs);
-			break;
-		}
-	}
+	return 1;
 }
 
-void dfs_send_csa_to_current_chan(struct wlan_dfs *dfs)
+uint16_t dfs_chan2freq(struct dfs_channel *chan)
 {
-	qdf_timer_stop(&dfs->wlan_dfstesttimer);
-	dfs->wlan_dfstest = 1;
-	dfs->wlan_dfstest_ieeechan = dfs->dfs_curchan->dfs_ch_ieee;
-	dfs->wlan_dfstesttime = 1;   /* 1ms */
-	qdf_timer_mod(&dfs->wlan_dfstesttimer, dfs->wlan_dfstesttime);
+	if (!chan)
+		return 0;
+
+	return chan == WLAN_CHAN_ANYC ? WLAN_CHAN_ANY : chan->dfs_ch_freq;
 }

+ 12 - 576
umac/dfs/core/src/misc/dfs.c

@@ -27,34 +27,9 @@
 #include "wlan_dfs_mlme_api.h"
 #include "wlan_dfs_tgt_api.h"
 #include "../dfs_internal.h"
+#include "../dfs_filter_init.h"
+#include "../dfs_full_offload.h"
 
-/*
- * Channel switch announcement (CSA)
- * usenol=1 (default) make CSA and switch to a new channel on radar detect
- * usenol=0, make CSA with next channel same as current on radar detect
- * usenol=2, no CSA and stay on the same channel on radar detect
- */
-
-static int usenol = 1;
-
-/**
- * dfs_task() - The timer function to process the radar pulses.
- */
-static os_timer_func(dfs_task)
-{
-	struct wlan_dfs *dfs = NULL;
-
-	OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
-
-	if (!dfs) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
-		return;
-	}
-
-	dfs_process_radarevent(dfs, dfs->dfs_curchan);
-
-	dfs->wlan_radar_tasksched = 0;
-}
 
 /**
  * dfs_testtimer_task() - Sends CSA in the current channel.
@@ -83,29 +58,6 @@ static os_timer_func(dfs_testtimer_task)
 			dfs->dfs_curchan->dfs_ch_flags);
 }
 
-static inline int dfs_fill_emulate_bang_radar_test(struct wlan_dfs *dfs,
-		uint32_t segid,
-		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
-{
-	/*
-	 * More parameters are to be added later indicating
-	 * seg id, chirp and sidx values to be sent to fw.
-	 */
-	dfs_unit_test->num_args = DFS_UNIT_TEST_NUM_ARGS;
-	dfs_unit_test->args[IDX_CMD_ID] =
-			DFS_PHYERR_OFFLOAD_TEST_SET_RADAR;
-	dfs_unit_test->args[IDX_PDEV_ID] =
-			wlan_objmgr_pdev_get_pdev_id(dfs->dfs_pdev_obj);
-	dfs_unit_test->args[IDX_SEG_ID] = segid;
-
-	if (tgt_dfs_process_emulate_bang_radar_cmd(dfs->dfs_pdev_obj,
-				dfs_unit_test) == QDF_STATUS_E_FAILURE) {
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 int dfs_get_debug_info(struct wlan_dfs *dfs, void *data)
 {
 	if (data)
@@ -114,15 +66,6 @@ int dfs_get_debug_info(struct wlan_dfs *dfs, void *data)
 	return (int)dfs->dfs_proc_phyerr;
 }
 
-void dfs_main_task_timer_init(struct wlan_dfs *dfs)
-{
-	qdf_timer_init(NULL,
-			&(dfs->wlan_dfs_task_timer),
-			dfs_task,
-			(void *)(dfs),
-			QDF_TIMER_TYPE_WAKE_APPS);
-}
-
 void dfs_main_task_testtimer_init(struct wlan_dfs *dfs)
 {
 	qdf_timer_init(NULL,
@@ -152,153 +95,6 @@ int dfs_create_object(struct wlan_dfs **dfs)
 	return 0;
 }
 
-int dfs_main_attach(struct wlan_dfs *dfs)
-{
-	int i, n;
-	struct wlan_dfs_radar_tab_info radar_info;
-
-	if (!dfs) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
-		return 0;
-	}
-
-	/* If ignore_dfs is set to 1 then Radar detection is disabled. */
-	if (dfs->dfs_ignore_dfs) {
-		dfs_debug(dfs, WLAN_DEBUG_DFS1, "ignoring dfs");
-		return 0;
-	}
-
-	/*
-	 * Zero out radar_info. It's possible that the attach function
-	 * won't fetch an initial regulatory configuration; you really
-	 * do want to ensure that the contents indicates there aren't
-	 * any filters.
-	 */
-	qdf_mem_zero(&radar_info, sizeof(radar_info));
-
-	lmac_get_caps(dfs->dfs_pdev_obj, &(dfs->dfs_caps));
-
-	dfs_clear_stats(dfs);
-	dfs->dfs_event_log_on = 1;
-	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "event log enabled by default");
-
-	dfs->dfs_enable = 1;
-
-	/*Verify : Passing NULL to qdf_timer_init().*/
-	dfs_main_task_timer_init(dfs);
-
-	WLAN_DFSQ_LOCK_CREATE(dfs);
-	STAILQ_INIT(&dfs->dfs_radarq);
-	WLAN_ARQ_LOCK_CREATE(dfs);
-	STAILQ_INIT(&dfs->dfs_arq);
-	STAILQ_INIT(&(dfs->dfs_eventq));
-	WLAN_DFSEVENTQ_LOCK_CREATE(dfs);
-
-	dfs->events = (struct dfs_event *)qdf_mem_malloc(
-			sizeof(struct dfs_event)*DFS_MAX_EVENTS);
-	if (!(dfs->events)) {
-		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "events allocation failed");
-		return 1;
-	}
-	for (i = 0; i < DFS_MAX_EVENTS; i++)
-		STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), &dfs->events[i],
-				re_list);
-
-	dfs->pulses = (struct dfs_pulseline *)qdf_mem_malloc(
-			sizeof(struct dfs_pulseline));
-	if (!(dfs->pulses)) {
-		qdf_mem_free(dfs->events);
-		dfs->events = NULL;
-		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "Pulse buffer allocation failed");
-		return 1;
-	}
-
-	dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
-
-	/* Allocate memory for radar filters. */
-	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
-		dfs->dfs_radarf[n] = (struct dfs_filtertype *)
-			qdf_mem_malloc(sizeof(struct dfs_filtertype));
-		if (!(dfs->dfs_radarf[n])) {
-			dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
-					"cannot allocate memory for radar filter types");
-			goto bad1;
-		}
-		qdf_mem_zero(dfs->dfs_radarf[n], sizeof(struct dfs_filtertype));
-	}
-
-	/* Allocate memory for radar table. */
-	dfs->dfs_ftindextable = (int8_t **)qdf_mem_malloc(256*sizeof(int8_t *));
-	if (!(dfs->dfs_ftindextable)) {
-		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "Cannot allocate memory for radar table");
-		goto bad1;
-	}
-	for (n = 0; n < 256; n++) {
-		dfs->dfs_ftindextable[n] = qdf_mem_malloc(
-				DFS_MAX_RADAR_OVERLAP*sizeof(int8_t));
-		if (!(dfs->dfs_ftindextable[n])) {
-			dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
-					"cannot allocate memory for radar table entry");
-			goto bad2;
-		}
-	}
-
-	if (usenol == 0)
-		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "NOL disabled");
-	else if (usenol == 2)
-		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "NOL disabled; no CSA");
-
-	dfs->dfs_use_nol = usenol;
-
-	/* Init the cached extension channel busy for false alarm reduction */
-	dfs->dfs_rinfo.ext_chan_busy_ts = lmac_get_tsf64(dfs->dfs_pdev_obj);
-	dfs->dfs_rinfo.dfs_ext_chan_busy = 0;
-	/* Init the Bin5 chirping related data */
-	dfs->dfs_rinfo.dfs_bin5_chirp_ts = dfs->dfs_rinfo.ext_chan_busy_ts;
-	dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR;
-	dfs->dfs_b5radars = NULL;
-
-	/*
-	 * If dfs_init_radar_filters() fails, we can abort here and
-	 * reconfigure when the first valid channel + radar config
-	 * is available.
-	 */
-	if (dfs_init_radar_filters(dfs, &radar_info)) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "Radar Filter Intialization Failed");
-		return 1;
-	}
-
-	dfs->wlan_dfs_false_rssi_thres = RSSI_POSSIBLY_FALSE;
-	dfs->wlan_dfs_peak_mag = SEARCH_FFT_REPORT_PEAK_MAG_THRSH;
-	dfs->dfs_phyerr_freq_min     = 0x7fffffff;
-	dfs->dfs_phyerr_freq_max     = 0;
-	dfs->dfs_phyerr_queued_count = 0;
-	dfs->dfs_phyerr_w53_counter  = 0;
-	dfs->dfs_pri_multiplier      = 2;
-	dfs_get_radars(dfs);
-
-	return 0;
-
-bad2:
-	qdf_mem_free(dfs->dfs_ftindextable);
-	dfs->dfs_ftindextable = NULL;
-bad1:
-	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
-		if (dfs->dfs_radarf[n] != NULL) {
-			qdf_mem_free(dfs->dfs_radarf[n]);
-			dfs->dfs_radarf[n] = NULL;
-		}
-	}
-	if (dfs->pulses) {
-		qdf_mem_free(dfs->pulses);
-		dfs->pulses = NULL;
-	}
-	qdf_mem_free(dfs->events);
-	dfs->events = NULL;
-
-	return 1;
-}
-
 int dfs_attach(struct wlan_dfs *dfs)
 {
 	int ret;
@@ -306,13 +102,14 @@ int dfs_attach(struct wlan_dfs *dfs)
 	if (!dfs->dfs_is_offload_enabled) {
 		ret = dfs_main_attach(dfs);
 
-	/*
-	 * For full offload we have a wmi handler registered to process a radar
-	 * event from firmware in the event of a radar detect.So ,init of timer,
-	 * dfs_task is not required for full offload. dfs_task timer is called
-	 * in dfs_main_timer_init within dfs_main_attach for partial offload
-	 * in the event of radar detect.
-	 */
+		/*
+		 * For full offload we have a wmi handler registered to process
+		 * a radar event from firmware in the event of a radar detect.
+		 * So, init of timer, dfs_task is not required for
+		 * full-offload. dfs_task timer is called in
+		 * dfs_main_timer_init within dfs_main_attach for
+		 * partial-offload in the event of radar detect.
+		 */
 		if (ret) {
 			dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs_main_attach failed");
 			return ret;
@@ -337,19 +134,6 @@ void dfs_stop(struct wlan_dfs *dfs)
 	dfs_clear_nolhistory(dfs);
 }
 
-void dfs_main_timer_reset(struct wlan_dfs *dfs)
-{
-	if (dfs->wlan_radar_tasksched) {
-		qdf_timer_stop(&dfs->wlan_dfs_task_timer);
-		dfs->wlan_radar_tasksched = 0;
-	}
-
-	if (dfs->wlan_dfstest) {
-		qdf_timer_stop(&dfs->wlan_dfstesttimer);
-		dfs->wlan_dfstest = 0;
-	}
-}
-
 void dfs_reset(struct wlan_dfs *dfs)
 {
 	if (!dfs) {
@@ -363,70 +147,6 @@ void dfs_reset(struct wlan_dfs *dfs)
 		dfs_main_timer_reset(dfs);
 }
 
-void dfs_main_detach(struct wlan_dfs *dfs)
-{
-	int n, empty;
-
-	if (!dfs->dfs_enable)
-		return;
-
-	dfs->dfs_enable = 0;
-
-	if (dfs->dfs_curchan != NULL) {
-		qdf_mem_free(dfs->dfs_curchan);
-		dfs->dfs_curchan = NULL;
-	}
-
-	dfs_reset_radarq(dfs);
-	dfs_reset_alldelaylines(dfs);
-
-	if (dfs->pulses != NULL) {
-		qdf_mem_free(dfs->pulses);
-		dfs->pulses = NULL;
-	}
-
-	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
-		if (dfs->dfs_radarf[n] != NULL) {
-			qdf_mem_free(dfs->dfs_radarf[n]);
-			dfs->dfs_radarf[n] = NULL;
-		}
-	}
-
-	if (dfs->dfs_ftindextable != NULL) {
-		for (n = 0; n < 256; n++) {
-			if (dfs->dfs_ftindextable[n] != NULL) {
-				qdf_mem_free(dfs->dfs_ftindextable[n]);
-				dfs->dfs_ftindextable[n] = NULL;
-			}
-		}
-		qdf_mem_free(dfs->dfs_ftindextable);
-		dfs->dfs_ftindextable = NULL;
-		dfs->wlan_dfs_isdfsregdomain = 0;
-	}
-
-	if (dfs->dfs_b5radars != NULL) {
-		qdf_mem_free(dfs->dfs_b5radars);
-		dfs->dfs_b5radars = NULL;
-	}
-
-	dfs_reset_ar(dfs);
-
-	WLAN_ARQ_LOCK(dfs);
-	empty = STAILQ_EMPTY(&(dfs->dfs_arq));
-	WLAN_ARQ_UNLOCK(dfs);
-	if (!empty)
-		dfs_reset_arq(dfs);
-
-	if (dfs->events != NULL) {
-		qdf_mem_free(dfs->events);
-		dfs->events = NULL;
-	}
-
-	WLAN_DFSQ_LOCK_DESTROY(dfs);
-	WLAN_ARQ_LOCK_DESTROY(dfs);
-	WLAN_DFSEVENTQ_LOCK_DESTROY(dfs);
-}
-
 void dfs_detach(struct wlan_dfs *dfs)
 {
 	if (!dfs->dfs_is_offload_enabled)
@@ -441,189 +161,6 @@ void dfs_destroy_object(struct wlan_dfs *dfs)
 	qdf_mem_free(dfs);
 }
 
-int dfs_radar_disable(struct wlan_dfs *dfs)
-{
-	dfs->dfs_proc_phyerr &= ~DFS_AR_EN;
-	dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
-
-	return 0;
-}
-
-int dfs_second_segment_radar_disable(struct wlan_dfs *dfs)
-{
-	dfs->dfs_proc_phyerr &= ~DFS_SECOND_SEGMENT_RADAR_EN;
-
-	return 0;
-}
-
-void dfs_phyerr_param_copy(struct wlan_dfs_phyerr_param *dst,
-		struct wlan_dfs_phyerr_param *src)
-{
-	memcpy(dst, src, sizeof(*dst));
-}
-
-struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index,
-		int ext_chan_flag)
-{
-	struct dfs_state *rs = NULL;
-	struct dfs_channel *cmp_ch, cmp_ch1;
-	int i;
-	QDF_STATUS err;
-
-	if (!dfs) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
-		return NULL;
-	}
-
-	cmp_ch = &cmp_ch1;
-	if (ext_chan_flag) {
-		err = dfs_mlme_get_extchan(dfs->dfs_pdev_obj,
-				&(cmp_ch->dfs_ch_freq),
-				&(cmp_ch->dfs_ch_flags),
-				&(cmp_ch->dfs_ch_flagext),
-				&(cmp_ch->dfs_ch_ieee),
-				&(cmp_ch->dfs_ch_vhtop_ch_freq_seg1),
-				&(cmp_ch->dfs_ch_vhtop_ch_freq_seg2));
-
-		if (err == QDF_STATUS_SUCCESS) {
-			dfs_debug(dfs, WLAN_DEBUG_DFS2,
-					"Extension channel freq = %u flags=0x%x",
-					cmp_ch->dfs_ch_freq,
-					cmp_ch->dfs_ch_flagext);
-		} else
-			return NULL;
-	} else {
-		cmp_ch = dfs->dfs_curchan;
-		dfs_debug(dfs, WLAN_DEBUG_DFS2,
-				"Primary channel freq = %u flags=0x%x",
-				cmp_ch->dfs_ch_freq, cmp_ch->dfs_ch_flagext);
-	}
-
-	for (i = 0; i < DFS_NUM_RADAR_STATES; i++) {
-		if ((dfs->dfs_radar[i].rs_chan.dfs_ch_freq ==
-					cmp_ch->dfs_ch_freq) &&
-			(dfs->dfs_radar[i].rs_chan.dfs_ch_flags ==
-			 cmp_ch->dfs_ch_flags)
-				) {
-			if (index != NULL)
-				*index = (uint8_t)i;
-			return &(dfs->dfs_radar[i]);
-		}
-	}
-	/* No existing channel found, look for first free channel state entry.*/
-	for (i = 0; i < DFS_NUM_RADAR_STATES; i++) {
-		if (dfs->dfs_radar[i].rs_chan.dfs_ch_freq == 0) {
-			rs = &(dfs->dfs_radar[i]);
-			/* Found one, set channel info and default thresholds.*/
-			rs->rs_chan = *cmp_ch;
-
-			/* Copy the parameters from the default set. */
-			dfs_phyerr_param_copy(&rs->rs_param,
-					&dfs->dfs_defaultparams);
-
-			if (index != NULL)
-				*index = (uint8_t)i;
-
-			return rs;
-		}
-	}
-	dfs_debug(dfs, WLAN_DEBUG_DFS2, "No more radar states left.");
-
-	return NULL;
-}
-
-void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode)
-{
-	int is_ext_ch;
-	int is_fastclk = 0;
-	struct dfs_channel *ext_ch, extchan;
-	QDF_STATUS err = QDF_STATUS_E_FAILURE;
-
-	if (!dfs) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
-		return;
-	}
-
-	is_ext_ch = WLAN_IS_CHAN_11N_HT40(dfs->dfs_curchan);
-	lmac_dfs_disable(dfs->dfs_pdev_obj, no_cac);
-
-	/*
-	 * In all modes, if the primary is DFS then we have to
-	 * enable radar detection. In HT80_80, we can have
-	 * primary non-DFS 80MHz with extension 80MHz DFS.
-	 */
-	if ((WLAN_IS_CHAN_DFS(dfs->dfs_curchan) ||
-			((WLAN_IS_CHAN_11AC_VHT160(dfs->dfs_curchan) ||
-		  WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) &&
-		 WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan))) ||
-			(dfs_is_precac_timer_running(dfs))) {
-		struct dfs_state *rs_pri = NULL, *rs_ext = NULL;
-		uint8_t index_pri, index_ext;
-
-		dfs->dfs_proc_phyerr |= DFS_AR_EN;
-		dfs->dfs_proc_phyerr |= DFS_RADAR_EN;
-		dfs->dfs_proc_phyerr |= DFS_SECOND_SEGMENT_RADAR_EN;
-
-		ext_ch = &extchan;
-		if (is_ext_ch)
-			err = dfs_mlme_get_extchan(dfs->dfs_pdev_obj,
-					&(ext_ch->dfs_ch_freq),
-					&(ext_ch->dfs_ch_flags),
-					&(ext_ch->dfs_ch_flagext),
-					&(ext_ch->dfs_ch_ieee),
-					&(ext_ch->dfs_ch_vhtop_ch_freq_seg1),
-					&(ext_ch->dfs_ch_vhtop_ch_freq_seg2));
-
-
-		dfs_reset_alldelaylines(dfs);
-
-		rs_pri = dfs_getchanstate(dfs, &index_pri, 0);
-		if (err == QDF_STATUS_SUCCESS) {
-			rs_ext = dfs_getchanstate(dfs, &index_ext, 1);
-		}
-
-		if (rs_pri != NULL && ((err == QDF_STATUS_E_FAILURE) ||
-			    (rs_ext != NULL))) {
-			struct wlan_dfs_phyerr_param pe;
-
-			qdf_mem_set(&pe, sizeof(pe), '\0');
-
-			if (index_pri != dfs->dfs_curchan_radindex)
-				dfs_reset_alldelaylines(dfs);
-
-			dfs->dfs_curchan_radindex = (int16_t)index_pri;
-
-			if (rs_ext)
-				dfs->dfs_extchan_radindex = (int16_t)index_ext;
-
-			dfs_phyerr_param_copy(&pe, &rs_pri->rs_param);
-			dfs_debug(dfs, WLAN_DEBUG_DFS3,
-					"firpwr=%d, rssi=%d, height=%d, prssi=%d, inband=%d, relpwr=%d, relstep=%d, maxlen=%d",
-					 pe.pe_firpwr,
-					pe.pe_rrssi, pe.pe_height,
-					pe.pe_prssi, pe.pe_inband,
-					pe.pe_relpwr, pe.pe_relstep,
-					pe.pe_maxlen);
-
-			lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk,
-					&pe, dfs->dfsdomain);
-			dfs_debug(dfs, WLAN_DEBUG_DFS,
-					"Enabled radar detection on channel %d",
-					dfs->dfs_curchan->dfs_ch_freq);
-
-			dfs->dur_multiplier = is_fastclk ?
-				DFS_FAST_CLOCK_MULTIPLIER :
-				DFS_NO_FAST_CLOCK_MULTIPLIER;
-
-			dfs_debug(dfs, WLAN_DEBUG_DFS3,
-					"duration multiplier is %d",
-					 dfs->dur_multiplier);
-		} else
-			dfs_debug(dfs, WLAN_DEBUG_DFS,
-					"No more radar states left");
-	}
-}
-
 int dfs_control(struct wlan_dfs *dfs,
 		u_int id,
 		void *indata,
@@ -923,9 +460,7 @@ int dfs_control(struct wlan_dfs *dfs,
 					&dfs_unit_test);
 		} else {
 			dfs->dfs_bangradar = 1;
-			dfs->wlan_radar_tasksched = 1;
-			qdf_timer_mod(&dfs->wlan_dfs_task_timer, 0);
-			error = 0;
+			error = dfs_start_host_based_bangradar(dfs);
 		}
 		break;
 	case DFS_SHOW_PRECAC_LISTS:
@@ -941,9 +476,7 @@ int dfs_control(struct wlan_dfs *dfs,
 					&dfs_unit_test);
 		} else {
 			dfs->dfs_second_segment_bangradar = 1;
-			dfs->wlan_radar_tasksched = 1;
-			qdf_timer_mod(&dfs->wlan_dfs_task_timer, 0);
-			error = 0;
+			error = dfs_start_host_based_bangradar(dfs);
 		}
 		break;
 	default:
@@ -954,94 +487,6 @@ bad:
 	return error;
 }
 
-int dfs_set_thresholds(struct wlan_dfs *dfs, const uint32_t threshtype,
-		const uint32_t value)
-{
-	int16_t chanindex;
-	struct dfs_state *rs;
-	struct wlan_dfs_phyerr_param pe;
-	int is_fastclk = 0;
-
-	if (!dfs) {
-		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
-		return 0;
-	}
-
-	chanindex = dfs->dfs_curchan_radindex;
-	if ((chanindex < 0) || (chanindex >= DFS_NUM_RADAR_STATES)) {
-		dfs_debug(dfs, WLAN_DEBUG_DFS1,
-				"chanindex = %d, DFS_NUM_RADAR_STATES=%d",
-				 chanindex, DFS_NUM_RADAR_STATES);
-		return 0;
-	}
-
-	dfs_debug(dfs, WLAN_DEBUG_DFS,
-			"threshtype=%d, value=%d", threshtype, value);
-
-	wlan_dfs_phyerr_init_noval(&pe);
-
-	rs = &(dfs->dfs_radar[chanindex]);
-	switch (threshtype) {
-	case DFS_PARAM_FIRPWR:
-		rs->rs_param.pe_firpwr = (int32_t) value;
-		pe.pe_firpwr = value;
-		break;
-	case DFS_PARAM_RRSSI:
-		rs->rs_param.pe_rrssi = value;
-		pe.pe_rrssi = value;
-		break;
-	case DFS_PARAM_HEIGHT:
-		rs->rs_param.pe_height = value;
-		pe.pe_height = value;
-		break;
-	case DFS_PARAM_PRSSI:
-		rs->rs_param.pe_prssi = value;
-		pe.pe_prssi = value;
-		break;
-	case DFS_PARAM_INBAND:
-		rs->rs_param.pe_inband = value;
-		pe.pe_inband = value;
-		break;
-		/* 5413 specific */
-	case DFS_PARAM_RELPWR:
-		rs->rs_param.pe_relpwr = value;
-		pe.pe_relpwr = value;
-		break;
-	case DFS_PARAM_RELSTEP:
-		rs->rs_param.pe_relstep = value;
-		pe.pe_relstep = value;
-		break;
-	case DFS_PARAM_MAXLEN:
-		rs->rs_param.pe_maxlen = value;
-		pe.pe_maxlen = value;
-		break;
-	default:
-		dfs_debug(dfs, WLAN_DEBUG_DFS1,
-				"unknown threshtype (%d)", threshtype);
-		break;
-	}
-
-	/*
-	 * The driver layer dfs_enable routine is tasked with translating
-	 * values from the global format to the per-device (HAL, offload)
-	 * format.
-	 */
-	lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk,
-			&pe, dfs->dfsdomain);
-
-	return 1;
-}
-
-int dfs_get_thresholds(struct wlan_dfs *dfs,
-		struct wlan_dfs_phyerr_param *param)
-{
-	qdf_mem_zero(param, sizeof(*param));
-
-	lmac_dfs_get_thresholds(dfs->dfs_pdev_obj, param);
-
-	return 1;
-}
-
 void dfs_set_current_channel(struct wlan_dfs *dfs,
 		uint16_t dfs_ch_freq,
 		uint64_t dfs_ch_flags,
@@ -1063,15 +508,6 @@ void dfs_set_current_channel(struct wlan_dfs *dfs,
 	dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2 = dfs_ch_vhtop_ch_freq_seg2;
 }
 
-uint16_t dfs_chan2freq(struct dfs_channel *chan)
-{
-	if (!chan)
-		return 0;
-
-	return chan == WLAN_CHAN_ANYC ?
-		WLAN_CHAN_ANY : chan->dfs_ch_freq;
-}
-
 void dfs_update_cur_chan_flags(struct wlan_dfs *dfs,
 		uint64_t flags,
 		uint16_t flagext)

+ 301 - 0
umac/dfs/core/src/misc/dfs_filter_init.c

@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2002-2006, Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: This file contains the dfs_attach() and dfs_detach() functions as well
+ * as the dfs_control() function which is used to process ioctls related to DFS.
+ * For Linux/Mac,  "radartool" is the command line tool that can be used to call
+ * various ioctls to set and get radar detection thresholds.
+ */
+
+#include "../dfs_zero_cac.h"
+#include "wlan_dfs_lmac_api.h"
+#include "wlan_dfs_mlme_api.h"
+#include "wlan_dfs_tgt_api.h"
+#include "../dfs_internal.h"
+#include "../dfs_filter_init.h"
+
+/*
+ * Channel switch announcement (CSA)
+ * usenol=1 (default) make CSA and switch to a new channel on radar detect
+ * usenol=0, make CSA with next channel same as current on radar detect
+ * usenol=2, no CSA and stay on the same channel on radar detect
+ */
+
+/**
+ * dfs_task() - The timer function to process the radar pulses.
+ */
+static os_timer_func(dfs_task)
+{
+	struct wlan_dfs *dfs = NULL;
+
+	OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
+
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
+		return;
+	}
+
+	dfs_process_radarevent(dfs, dfs->dfs_curchan);
+
+	dfs->wlan_radar_tasksched = 0;
+}
+
+/**
+ * dfs_main_task_timer_init() - Initialize dfs task timer.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+static void dfs_main_task_timer_init(struct wlan_dfs *dfs)
+{
+	qdf_timer_init(NULL,
+			&(dfs->wlan_dfs_task_timer),
+			dfs_task,
+			(void *)(dfs),
+			QDF_TIMER_TYPE_WAKE_APPS);
+}
+
+int dfs_main_attach(struct wlan_dfs *dfs)
+{
+	int i, n;
+	struct wlan_dfs_radar_tab_info radar_info;
+
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
+		return 0;
+	}
+
+	/* If ignore_dfs is set to 1 then Radar detection is disabled. */
+	if (dfs->dfs_ignore_dfs) {
+		dfs_debug(dfs, WLAN_DEBUG_DFS1, "ignoring dfs");
+		return 0;
+	}
+
+	/*
+	 * Zero out radar_info. It's possible that the attach function
+	 * won't fetch an initial regulatory configuration; you really
+	 * do want to ensure that the contents indicates there aren't
+	 * any filters.
+	 */
+	qdf_mem_zero(&radar_info, sizeof(radar_info));
+
+	lmac_get_caps(dfs->dfs_pdev_obj, &(dfs->dfs_caps));
+
+	dfs_clear_stats(dfs);
+	dfs->dfs_event_log_on = 1;
+	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "event log enabled by default");
+
+	dfs->dfs_enable = 1;
+
+	/*Verify : Passing NULL to qdf_timer_init().*/
+	dfs_main_task_timer_init(dfs);
+
+	WLAN_DFSQ_LOCK_CREATE(dfs);
+	STAILQ_INIT(&dfs->dfs_radarq);
+	WLAN_ARQ_LOCK_CREATE(dfs);
+	STAILQ_INIT(&dfs->dfs_arq);
+	STAILQ_INIT(&(dfs->dfs_eventq));
+	WLAN_DFSEVENTQ_LOCK_CREATE(dfs);
+
+	dfs->events = (struct dfs_event *)qdf_mem_malloc(
+			sizeof(struct dfs_event)*DFS_MAX_EVENTS);
+	if (!(dfs->events)) {
+		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "events allocation failed");
+		return 1;
+	}
+	for (i = 0; i < DFS_MAX_EVENTS; i++)
+		STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), &dfs->events[i],
+				re_list);
+
+	dfs->pulses = (struct dfs_pulseline *)qdf_mem_malloc(
+			sizeof(struct dfs_pulseline));
+	if (!(dfs->pulses)) {
+		qdf_mem_free(dfs->events);
+		dfs->events = NULL;
+		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "Pulse buffer allocation failed");
+		return 1;
+	}
+
+	dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
+
+	/* Allocate memory for radar filters. */
+	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+		dfs->dfs_radarf[n] = (struct dfs_filtertype *)
+			qdf_mem_malloc(sizeof(struct dfs_filtertype));
+		if (!(dfs->dfs_radarf[n])) {
+			dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
+					"cannot allocate memory for radar filter types");
+			goto bad1;
+		}
+		qdf_mem_zero(dfs->dfs_radarf[n], sizeof(struct dfs_filtertype));
+	}
+
+	/* Allocate memory for radar table. */
+	dfs->dfs_ftindextable = (int8_t **)qdf_mem_malloc(
+			DFS_NUM_FT_IDX_TBL_ROWS*sizeof(int8_t *));
+	if (!(dfs->dfs_ftindextable)) {
+		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "Cannot allocate memory for radar table");
+		goto bad1;
+	}
+	for (n = 0; n < DFS_NUM_FT_IDX_TBL_ROWS; n++) {
+		dfs->dfs_ftindextable[n] = qdf_mem_malloc(
+				DFS_MAX_RADAR_OVERLAP*sizeof(int8_t));
+		if (!(dfs->dfs_ftindextable[n])) {
+			dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
+					"cannot allocate memory for radar table entry");
+			goto bad2;
+		}
+	}
+
+	dfs->dfs_use_nol = 1;
+
+	/* Init the cached extension channel busy for false alarm reduction */
+	dfs->dfs_rinfo.ext_chan_busy_ts = lmac_get_tsf64(dfs->dfs_pdev_obj);
+	dfs->dfs_rinfo.dfs_ext_chan_busy = 0;
+	/* Init the Bin5 chirping related data */
+	dfs->dfs_rinfo.dfs_bin5_chirp_ts = dfs->dfs_rinfo.ext_chan_busy_ts;
+	dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR;
+	dfs->dfs_b5radars = NULL;
+
+	/*
+	 * If dfs_init_radar_filters() fails, we can abort here and
+	 * reconfigure when the first valid channel + radar config
+	 * is available.
+	 */
+	if (dfs_init_radar_filters(dfs, &radar_info)) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "Radar Filter Intialization Failed");
+		return 1;
+	}
+
+	dfs->wlan_dfs_false_rssi_thres = RSSI_POSSIBLY_FALSE;
+	dfs->wlan_dfs_peak_mag = SEARCH_FFT_REPORT_PEAK_MAG_THRSH;
+	dfs->dfs_phyerr_freq_min     = 0x7fffffff;
+	dfs->dfs_phyerr_freq_max     = 0;
+	dfs->dfs_phyerr_queued_count = 0;
+	dfs->dfs_phyerr_w53_counter  = 0;
+	dfs->dfs_pri_multiplier      = 2;
+	dfs_get_radars(dfs);
+
+	return 0;
+
+bad2:
+	qdf_mem_free(dfs->dfs_ftindextable);
+	dfs->dfs_ftindextable = NULL;
+bad1:
+	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+		if (dfs->dfs_radarf[n] != NULL) {
+			qdf_mem_free(dfs->dfs_radarf[n]);
+			dfs->dfs_radarf[n] = NULL;
+		}
+	}
+	if (dfs->pulses) {
+		qdf_mem_free(dfs->pulses);
+		dfs->pulses = NULL;
+	}
+	if (dfs->events) {
+		qdf_mem_free(dfs->events);
+		dfs->events = NULL;
+	}
+
+	return 1;
+}
+
+void dfs_main_timer_reset(struct wlan_dfs *dfs)
+{
+	if (dfs->wlan_radar_tasksched) {
+		qdf_timer_stop(&dfs->wlan_dfs_task_timer);
+		dfs->wlan_radar_tasksched = 0;
+	}
+
+	if (dfs->wlan_dfstest) {
+		qdf_timer_stop(&dfs->wlan_dfstesttimer);
+		dfs->wlan_dfstest = 0;
+	}
+}
+
+void dfs_main_detach(struct wlan_dfs *dfs)
+{
+	int n, empty;
+
+	if (!dfs->dfs_enable) {
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Already detached");
+		return;
+	}
+
+	dfs->dfs_enable = 0;
+
+	if (dfs->dfs_curchan != NULL) {
+		qdf_mem_free(dfs->dfs_curchan);
+		dfs->dfs_curchan = NULL;
+	}
+
+	dfs_reset_radarq(dfs);
+	dfs_reset_alldelaylines(dfs);
+
+	if (dfs->pulses != NULL) {
+		qdf_mem_free(dfs->pulses);
+		dfs->pulses = NULL;
+	}
+
+	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+		if (dfs->dfs_radarf[n] != NULL) {
+			qdf_mem_free(dfs->dfs_radarf[n]);
+			dfs->dfs_radarf[n] = NULL;
+		}
+	}
+
+	if (dfs->dfs_ftindextable != NULL) {
+		for (n = 0; n < DFS_NUM_FT_IDX_TBL_ROWS; n++) {
+			if (dfs->dfs_ftindextable[n] != NULL) {
+				qdf_mem_free(dfs->dfs_ftindextable[n]);
+				dfs->dfs_ftindextable[n] = NULL;
+			}
+		}
+		qdf_mem_free(dfs->dfs_ftindextable);
+		dfs->dfs_ftindextable = NULL;
+		dfs->wlan_dfs_isdfsregdomain = 0;
+	}
+
+	if (dfs->dfs_b5radars != NULL) {
+		qdf_mem_free(dfs->dfs_b5radars);
+		dfs->dfs_b5radars = NULL;
+	}
+
+	dfs_reset_ar(dfs);
+
+	WLAN_ARQ_LOCK(dfs);
+	empty = STAILQ_EMPTY(&(dfs->dfs_arq));
+	WLAN_ARQ_UNLOCK(dfs);
+	if (!empty)
+		dfs_reset_arq(dfs);
+
+	if (dfs->events != NULL) {
+		qdf_mem_free(dfs->events);
+		dfs->events = NULL;
+	}
+
+	WLAN_DFSQ_LOCK_DESTROY(dfs);
+	WLAN_ARQ_LOCK_DESTROY(dfs);
+	WLAN_DFSEVENTQ_LOCK_DESTROY(dfs);
+}
+
+int dfs_start_host_based_bangradar(struct wlan_dfs *dfs)
+{
+	dfs->wlan_radar_tasksched = 1;
+	qdf_timer_mod(&dfs->wlan_dfs_task_timer, 0);
+
+	return 0;
+}

+ 51 - 0
umac/dfs/core/src/misc/dfs_full_offload.c

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2002-2006, Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: This file contains the dfs_fill_emulate_bang_radar_test() which is used
+ * to send command to firmware to emulate RADAR found event.
+ */
+
+#include "../dfs_zero_cac.h"
+#include "wlan_dfs_lmac_api.h"
+#include "wlan_dfs_mlme_api.h"
+#include "wlan_dfs_tgt_api.h"
+#include "../dfs_internal.h"
+#include "../dfs_full_offload.h"
+
+int dfs_fill_emulate_bang_radar_test(struct wlan_dfs *dfs,
+		uint32_t segid,
+		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
+{
+	/*
+	 * More parameters are to be added later indicating
+	 * seg id, chirp and sidx values to be sent to fw.
+	 */
+	dfs_unit_test->num_args = DFS_UNIT_TEST_NUM_ARGS;
+	dfs_unit_test->args[IDX_CMD_ID] =
+			DFS_PHYERR_OFFLOAD_TEST_SET_RADAR;
+	dfs_unit_test->args[IDX_PDEV_ID] =
+			wlan_objmgr_pdev_get_pdev_id(dfs->dfs_pdev_obj);
+	dfs_unit_test->args[IDX_SEG_ID] = segid;
+
+	if (tgt_dfs_process_emulate_bang_radar_cmd(dfs->dfs_pdev_obj,
+				dfs_unit_test) == QDF_STATUS_E_FAILURE) {
+		return -EINVAL;
+	}
+
+	return 0;
+}

+ 43 - 0
umac/dfs/core/src/misc/dfs_process_radar_found_ind.c

@@ -22,6 +22,7 @@
  */
 
 #include "../dfs.h"
+#include "../dfs_zero_cac.h"
 #include "../dfs_process_radar_found_ind.h"
 #include <wlan_reg_services_api.h>
 #include <wlan_dfs_utils_api.h>
@@ -407,6 +408,48 @@ static uint8_t dfs_get_bonding_channels(struct dfs_channel *curchan,
 	return nchannels;
 }
 
+int dfs_radarevent_basic_sanity(struct wlan_dfs *dfs,
+		struct dfs_channel *chan)
+{
+	if (!(dfs->dfs_second_segment_bangradar ||
+				dfs_is_precac_timer_running(dfs)))
+		if (!(WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(chan))) {
+			dfs_debug(dfs, WLAN_DEBUG_DFS2,
+					"radar event on non-DFS chan");
+			if (!(dfs->dfs_is_offload_enabled)) {
+				dfs_reset_radarq(dfs);
+				dfs_reset_alldelaylines(dfs);
+				dfs->dfs_bangradar = 0;
+			}
+			return 0;
+		}
+
+	return 1;
+}
+
+/**
+ * dfs_send_csa_to_current_chan() - Send CSA to current channel
+ * @dfs: Pointer to wlan_dfs structure.
+ *
+ * For the test mode(usenol = 0), don't do a CSA; but setup the test timer so
+ * we get a CSA _back_ to the current operating channel.
+ */
+static inline void dfs_send_csa_to_current_chan(struct wlan_dfs *dfs)
+{
+	qdf_timer_stop(&dfs->wlan_dfstesttimer);
+	dfs->wlan_dfstest = 1;
+	dfs->wlan_dfstest_ieeechan = dfs->dfs_curchan->dfs_ch_ieee;
+	dfs->wlan_dfstesttime = 1;   /* 1ms */
+	qdf_timer_mod(&dfs->wlan_dfstesttimer, dfs->wlan_dfstesttime);
+}
+
+int dfs_second_segment_radar_disable(struct wlan_dfs *dfs)
+{
+	dfs->dfs_proc_phyerr &= ~DFS_SECOND_SEGMENT_RADAR_EN;
+
+	return 0;
+}
+
 QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs,
 				 struct radar_found_info *radar_found)
 {