From d3dc1a400d1523b01df1e3e8257de3826c8a6518 Mon Sep 17 00:00:00 2001 From: Vijay Krishnan Date: Wed, 9 Dec 2020 16:43:30 +0530 Subject: [PATCH] qca-wifi: Move DFS_BANGRADAR from common code to WIN code Bangradar is used to simulate actual radar. For partial-offlload the simulation happens within the host itself. For full-offload a WMI command is sent to the FW and it responds with radar found event. CRs-Fixed: 2829436 Change-Id: I5a2c7e50df2ee06d236e45a47608c9c53f57ba99 --- umac/dfs/core/src/misc/dfs_bangradar.c | 208 +++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 umac/dfs/core/src/misc/dfs_bangradar.c diff --git a/umac/dfs/core/src/misc/dfs_bangradar.c b/umac/dfs/core/src/misc/dfs_bangradar.c new file mode 100644 index 0000000000..ecfc61328a --- /dev/null +++ b/umac/dfs/core/src/misc/dfs_bangradar.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2016-2020 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 Bangradar functionality. + * + */ + +#include "dfs.h" +#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" + +/** + * dfs_check_bangradar_sanity() - Check the sanity of bangradar + * @dfs: Pointer to wlan_dfs structure. + * @bangradar_params: Parameters of the radar to be simulated. + */ +static QDF_STATUS +dfs_check_bangradar_sanity(struct wlan_dfs *dfs, + struct dfs_bangradar_params *bangradar_params) +{ + if (!bangradar_params) { + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "bangradar params is NULL"); + return -EINVAL; + } + if (dfs_is_true_160mhz_supported(dfs)) { + if (abs(bangradar_params->freq_offset) > + FREQ_OFFSET_BOUNDARY_FOR_160MHZ) { + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Frequency Offset out of bound"); + return -EINVAL; + } + } else if (abs(bangradar_params->freq_offset) > + FREQ_OFFSET_BOUNDARY_FOR_80MHZ) { + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Frequency Offset out of bound"); + return -EINVAL; + } + if (bangradar_params->seg_id > SEG_ID_SECONDARY) { + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "Invalid segment ID"); + return -EINVAL; + } + if ((bangradar_params->detector_id > dfs_get_agile_detector_id(dfs)) || + ((bangradar_params->detector_id == + dfs_get_agile_detector_id(dfs)) && + !dfs->dfs_is_offload_enabled)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "Invalid detector ID"); + return -EINVAL; + } + return QDF_STATUS_SUCCESS; +} + +/** + * dfs_start_host_based_bangradar() - Mark as bangradar and start + * wlan_dfs_task_timer. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) +static 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; +} +#else +static inline int dfs_start_host_based_bangradar(struct wlan_dfs *dfs) +{ + return 0; +} +#endif + +/** + * dfs_fill_emulate_bang_radar_test() - Update dfs unit test arguments and + * send bangradar command to firmware. + * @dfs: Pointer to wlan_dfs structure. + * @bangradar_params: Parameters of the radar to be simulated. + * + * Return: If the event is received return 0. + */ +#if defined(WLAN_DFS_FULL_OFFLOAD) +#define ADD_TO_32BYTE(_arg, _shift, _mask) (((_arg) & (_mask)) << (_shift)) +static int +dfs_fill_emulate_bang_radar_test(struct wlan_dfs *dfs, + struct dfs_bangradar_params *bangradar_params) +{ + struct dfs_emulate_bang_radar_test_cmd dfs_unit_test; + uint32_t packed_args = 0; + + if (!(WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(dfs->dfs_curchan))) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Ignore bangradar on a NON-DFS channel"); + return -EINVAL; + } + + packed_args = + ADD_TO_32BYTE(bangradar_params->seg_id, + SEG_ID_SHIFT, + SEG_ID_MASK) | + ADD_TO_32BYTE(bangradar_params->is_chirp, + IS_CHIRP_SHIFT, + IS_CHIRP_MASK) | + ADD_TO_32BYTE(bangradar_params->freq_offset, + FREQ_OFF_SHIFT, + FREQ_OFFSET_MASK) | + ADD_TO_32BYTE(bangradar_params->detector_id, + DET_ID_SHIFT, + DET_ID_MASK); + + qdf_mem_zero(&dfs_unit_test, sizeof(dfs_unit_test)); + 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_RADAR_PARAM1_ID] = packed_args; + + if (tgt_dfs_process_emulate_bang_radar_cmd(dfs->dfs_pdev_obj, + &dfs_unit_test) == + QDF_STATUS_E_FAILURE) { + return -EINVAL; + } + + return 0; +} +#else +static inline int +dfs_fill_emulate_bang_radar_test(struct wlan_dfs *dfs, + struct dfs_bangradar_params *bangradar_params) +{ + return 0; +} +#endif + +/* + * Handle all types of Bangradar here. + * Bangradar arguments: + * seg_id : Segment ID where radar should be injected. + * is_chirp : Is chirp radar or non chirp radar. + * freq_offset : Frequency offset from center frequency. + * + * Type 1 (DFS_BANGRADAR_FOR_ALL_SUBCHANS): To add all subchans. + * Type 2 (DFS_BANGRADAR_FOR_ALL_SUBCHANS_OF_SEGID): To add all + * subchans of given segment_id. + * Type 3 (DFS_BANGRADAR_FOR_SPECIFIC_SUBCHANS): To add specific + * subchans based on the arguments. + * + * The arguments will already be filled in the indata structure + * based on the type. + * If an argument is not specified by user, it will be set to + * default (0) in the indata already and correspondingly, + * the type will change. + */ + +int dfs_bang_radar(struct wlan_dfs *dfs, void *indata, uint32_t insize) +{ + struct dfs_bangradar_params *bangradar_params; + int error = -EINVAL; + + if (!dfs) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return error; + } + + if (insize < sizeof(struct dfs_bangradar_params) || !indata) { + dfs_debug(dfs, WLAN_DEBUG_DFS1, + "insize = %d, expected = %zu bytes, indata = %pK", + insize, + sizeof(struct dfs_bangradar_params), + indata); + return error; + } + bangradar_params = (struct dfs_bangradar_params *)indata; + error = dfs_check_bangradar_sanity(dfs, bangradar_params); + if (error != QDF_STATUS_SUCCESS) + return error; + dfs->dfs_bangradar_type = bangradar_params->bangradar_type; + dfs->dfs_seg_id = bangradar_params->seg_id; + dfs->dfs_is_chirp = bangradar_params->is_chirp; + dfs->dfs_freq_offset = bangradar_params->freq_offset; + + if (dfs->dfs_is_offload_enabled) { + error = dfs_fill_emulate_bang_radar_test( + dfs, + bangradar_params); + } else { + error = dfs_start_host_based_bangradar(dfs); + } + return error; +}