diff --git a/target_if/dfs/inc/target_if_dfs.h b/target_if/dfs/inc/target_if_dfs.h index bbc0608cfe..2e7b95a843 100644 --- a/target_if/dfs/inc/target_if_dfs.h +++ b/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; +} + diff --git a/target_if/dfs/inc/target_if_dfs_full_offload.h b/target_if/dfs/inc/target_if_dfs_full_offload.h new file mode 100644 index 0000000000..bc1dc5808f --- /dev/null +++ b/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_ */ + diff --git a/target_if/dfs/inc/target_if_dfs_partial_offload.h b/target_if/dfs/inc/target_if_dfs_partial_offload.h new file mode 100644 index 0000000000..2a1b9c96ba --- /dev/null +++ b/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_ */ diff --git a/target_if/dfs/src/target_if_dfs.c b/target_if/dfs/src/target_if_dfs.c index 3cfcf779ad..72c64803e5 100644 --- a/target_if/dfs/src/target_if_dfs.c +++ b/target_if/dfs/src/target_if_dfs.c @@ -37,12 +37,8 @@ #include "target_type.h" #include #include - -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 +#include /** * 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) { diff --git a/target_if/dfs/src/target_if_dfs_full_offload.c b/target_if/dfs/src/target_if_dfs_full_offload.c new file mode 100644 index 0000000000..31e52235cc --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +/** + * 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 diff --git a/target_if/dfs/src/target_if_dfs_partial_offload.c b/target_if/dfs/src/target_if_dfs_partial_offload.c new file mode 100644 index 0000000000..fbe9a5edc8 --- /dev/null +++ b/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 +#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; +} diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 8cf94f0175..0975bdec50 100644 --- a/umac/dfs/core/src/dfs.h +++ b/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_ */ diff --git a/umac/dfs/core/src/dfs_direct_attach_radar.h b/umac/dfs/core/src/dfs_direct_attach_radar.h new file mode 100644 index 0000000000..283f055961 --- /dev/null +++ b/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_ */ diff --git a/umac/dfs/core/src/dfs_filter_init.h b/umac/dfs/core/src/dfs_filter_init.h new file mode 100644 index 0000000000..e8cbf71e79 --- /dev/null +++ b/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_ */ diff --git a/umac/dfs/core/src/dfs_full_offload.h b/umac/dfs/core/src/dfs_full_offload.h new file mode 100644 index 0000000000..e44be42acf --- /dev/null +++ b/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_ */ diff --git a/umac/dfs/core/src/dfs_partial_offload_radar.h b/umac/dfs/core/src/dfs_partial_offload_radar.h new file mode 100644 index 0000000000..7cc408ca54 --- /dev/null +++ b/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_ */ diff --git a/umac/dfs/core/src/dfs_zero_cac.h b/umac/dfs/core/src/dfs_zero_cac.h index 7a73c0d463..635412cb6f 100644 --- a/umac/dfs/core/src/dfs_zero_cac.h +++ b/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_ */ diff --git a/umac/dfs/core/src/filtering/dfs_direct_attach_radar.c b/umac/dfs/core/src/filtering/dfs_direct_attach_radar.c new file mode 100644 index 0000000000..f295e5df13 --- /dev/null +++ b/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; + } +} diff --git a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c b/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c new file mode 100644 index 0000000000..394f8f6754 --- /dev/null +++ b/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); +} diff --git a/umac/dfs/core/src/filtering/dfs_process_phyerr.c b/umac/dfs/core/src/filtering/dfs_process_phyerr.c index bf9da70381..f49e0dee9c 100644 --- a/umac/dfs/core/src/filtering/dfs_process_phyerr.c +++ b/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) diff --git a/umac/dfs/core/src/filtering/dfs_process_radarevent.c b/umac/dfs/core/src/filtering/dfs_process_radarevent.c index 643f39412e..c8d54b440b 100644 --- a/umac/dfs/core/src/filtering/dfs_process_radarevent.c +++ b/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. diff --git a/umac/dfs/core/src/filtering/dfs_radar.c b/umac/dfs/core/src/filtering/dfs_radar.c index 1b8a0accd3..d128dfe709 100644 --- a/umac/dfs/core/src/filtering/dfs_radar.c +++ b/umac/dfs/core/src/filtering/dfs_radar.c @@ -15,448 +15,16 @@ * 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}, - - /* 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. - */ -struct dfs_bin5pulse dfs_fcc_bin5pulses[] = { - {6, 28, 105, 12, 18, 5}, -}; - -/** - * struct dfs_bin5pulse dfs_jpn_bin5pulses - JAPAN BIN5 pulses for Offload - * chipsets. - */ -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. - */ - -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. - */ -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}, -}; - -/** - * 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}, -}; - -/** - * 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}, - - /* 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 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)); - - /* - * 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); -} - void dfs_get_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 - struct wlan_objmgr_psoc *psoc; if (!dfs) { @@ -471,59 +39,282 @@ void dfs_get_radars(struct wlan_dfs *dfs) } if (wlan_objmgr_psoc_get_dev_type(psoc) == WLAN_DEV_OL) { - /* For offload chip */ - ol_if_dfs_configure(dfs); + /* For Partial offload */ + dfs_get_po_radars(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; - } + /* For Direct Attach (DA) */ + dfs_get_da_radars(dfs); } } -void dfs_send_csa_to_current_chan(struct wlan_dfs *dfs) +int dfs_radar_disable(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); + dfs->dfs_proc_phyerr &= ~DFS_AR_EN; + dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; + + return 0; +} + +void dfs_phyerr_param_copy(struct wlan_dfs_phyerr_param *dst, + struct wlan_dfs_phyerr_param *src) +{ + qdf_mem_copy(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_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, + "%s: chanindex = %d, DFS_NUM_RADAR_STATES=%d\n", + __func__, + 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; +} + +uint16_t dfs_chan2freq(struct dfs_channel *chan) +{ + if (!chan) + return 0; + + return chan == WLAN_CHAN_ANYC ? WLAN_CHAN_ANY : chan->dfs_ch_freq; } diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index 2332eae7e8..e148032bfc 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/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) diff --git a/umac/dfs/core/src/misc/dfs_filter_init.c b/umac/dfs/core/src/misc/dfs_filter_init.c new file mode 100644 index 0000000000..e03f6ad119 --- /dev/null +++ b/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; +} diff --git a/umac/dfs/core/src/misc/dfs_full_offload.c b/umac/dfs/core/src/misc/dfs_full_offload.c new file mode 100644 index 0000000000..fbe628e73a --- /dev/null +++ b/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; +} diff --git a/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c b/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c index 8ea29ffb75..7df8aafbcc 100644 --- a/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c +++ b/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 #include @@ -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) {