diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 99ac566faf..4dc9c14776 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -1031,8 +1031,13 @@ struct dfs_event_log { * @dfs_nol_ie_bitmap: The bitmap of radar affected subchannels * in the current channel list * to be sent in NOL IE with RCSA. - * @dfs_is_rcsa_ie_sent To send or to not send RCSA IE. - * @dfs_is_nol_ie_sent To send or to not send NOL IE. + * @dfs_is_rcsa_ie_sent: To send or to not send RCSA IE. + * @dfs_is_nol_ie_sent: To send or to not send NOL IE. + * @dfs_allow_hw_pulses: Allow/Block HW pulses. When synthetic + * pulses are injected, the HW pulses should + * be blocked and this variable should be + * false so that HW pulses and synthetic + * pulses do not get mixed up. */ struct wlan_dfs { uint32_t dfs_debug_mask; @@ -1174,6 +1179,9 @@ struct wlan_dfs { bool dfs_is_rcsa_ie_sent; bool dfs_is_nol_ie_sent; bool dfs_agile_precac_enable; +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) + bool dfs_allow_hw_pulses; +#endif }; #if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS) diff --git a/umac/dfs/core/src/dfs_partial_offload_radar.h b/umac/dfs/core/src/dfs_partial_offload_radar.h index 40b94f6a8b..4fb8f7ec0d 100644 --- a/umac/dfs/core/src/dfs_partial_offload_radar.h +++ b/umac/dfs/core/src/dfs_partial_offload_radar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -197,4 +197,56 @@ static inline void dfs_false_radarfound_reset_vars(struct wlan_dfs *dfs) { } #endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +/** + * dfs_allow_hw_pulses() - Set or unset dfs_allow_hw_pulses + * which allow or disallow HW pulses. + * @dfs: Pointer to DFS pdev object. + * @allow_hw_pulses: allow/disallow synthetic pulse detection true/false. + * + * Return: void + */ +void dfs_allow_hw_pulses(struct wlan_dfs *dfs, bool allow_hw_pulses); +#else +static inline void dfs_allow_hw_pulses(struct wlan_dfs *dfs, + bool allow_hw_pulses) +{ +} +#endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +/** + * dfs_is_hw_pulses_allowed() - Check if HW pulses are allowed or not. + * @pdev: Pointer to DFS pdev object. + * + * Return: bool + */ +bool dfs_is_hw_pulses_allowed(struct wlan_dfs *dfs); +#else +static inline bool dfs_is_hw_pulses_allowed(struct wlan_dfs *dfs) +{ + return true; +} +#endif + +/** + * dfs_inject_synthetic_pulse_sequence() - Inject the synthetic pulse to the + * phyerror processing algorithm. + * @dfs: Pointer to wlan_dfs structure. + * @buf: Pointer to buffer of pulses. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +QDF_STATUS dfs_inject_synthetic_pulse_sequence(struct wlan_dfs *dfs, + unsigned char *buf); +#else +static inline +QDF_STATUS dfs_inject_synthetic_pulse_sequence(struct wlan_dfs *dfs, + unsigned char *buf) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_DFS_PARTIAL_OFFLOAD && WLAN_DFS_SYNTHETIC_RADAR */ #endif /* _DFS_PARTIAL_OFFLOAD_RADAR_H_ */ diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index 9420f39d52..0c2a3a0c66 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/umac/dfs/core/src/misc/dfs.c @@ -705,6 +705,20 @@ int dfs_control(struct wlan_dfs *dfs, dfs_reset_precac_lists(dfs); dfs_reset_etsi_precac_lists(dfs); break; + case DFS_INJECT_SEQUENCE: + error = dfs_inject_synthetic_pulse_sequence(dfs, indata); + if (error) + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Not injected Synthetic pulse"); + break; + + case DFS_ALLOW_HW_PULSES: + if (insize < sizeof(u_int8_t) || !indata) { + error = -EINVAL; + break; + } + dfs_allow_hw_pulses(dfs, !!(*(u_int8_t *)indata)); + break; default: error = -EINVAL; } diff --git a/umac/dfs/core/src/misc/dfs_filter_init.c b/umac/dfs/core/src/misc/dfs_filter_init.c index 7a7ba25583..01f3b821d3 100644 --- a/umac/dfs/core/src/misc/dfs_filter_init.c +++ b/umac/dfs/core/src/misc/dfs_filter_init.c @@ -218,6 +218,7 @@ int dfs_main_attach(struct wlan_dfs *dfs) /*Verify : Passing NULL to qdf_timer_init().*/ dfs_main_task_timer_init(dfs); + dfs_allow_hw_pulses(dfs, true); dfs_host_wait_timer_init(dfs); WLAN_DFSQ_LOCK_CREATE(dfs); diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h b/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h index a1f11c215f..9cc33443dc 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h @@ -53,12 +53,15 @@ #define DFS_SET_DISABLE_RADAR_MARKING 25 #define DFS_GET_DISABLE_RADAR_MARKING 26 +#define DFS_INJECT_SEQUENCE 27 +#define DFS_ALLOW_HW_PULSES 28 + /* * Spectral IOCTLs use DFS_LAST_IOCTL as the base. * This must always be the last IOCTL in DFS and have * the highest value. */ -#define DFS_LAST_IOCTL 27 +#define DFS_LAST_IOCTL 29 #ifndef DFS_CHAN_MAX #define DFS_CHAN_MAX 1023 @@ -271,4 +274,69 @@ enum WLAN_DFS_EVENTS { WLAN_EV_NOL_FINISHED, }; +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +/** + * Structure of Pulse to be injected into the DFS Module + * ****************************************************** + * Header + * ====== + * ----------|--------------| + * num_pulses| total_len_seq| + * ----------|--------------| + * Buffer Contents per pulse: + * ========================== + * ------|----------|-----------|----------|-----------|---------------|-------- + * r_rssi|r_ext_rssi|r_rs_tstamp|r_fulltsf |fft_datalen|total_len_pulse|FFT + * | | | | | |Buffer.. + * ------|----------|-----------|----------|-----------|---------------|-------- + */ + +/** + * struct synthetic_pulse - Radar Pulse Structure to be filled on reading the + * user file. + * @r_rssi: RSSI of the pulse. + * @r_ext_rssi: Extension Channel RSSI. + * @r_rs_tstamp: Timestamp. + * @r_fulltsf: TSF64. + * @fft_datalen: Total len of FFT. + * @total_len_pulse: Total len of the pulse. + * @fft_buf: Pointer to fft data. + */ + +struct synthetic_pulse { + uint8_t r_rssi; + uint8_t r_ext_rssi; + uint32_t r_rs_tstamp; + uint64_t r_fulltsf; + uint16_t fft_datalen; + uint16_t total_len_pulse; + unsigned char *fft_buf; +} qdf_packed; + +/** + * struct synthetic_seq - Structure to hold an array of pointers to the + * pulse structure. + * @num_pulses: Total num of pulses in the sequence. + * @total_len_seq: Total len of the sequence. + * @pulse: Array of pointers to synthetic_pulse structure. + */ + +struct synthetic_seq { + uint8_t num_pulses; + uint32_t total_len_seq; + struct synthetic_pulse *pulse[0]; +}; + +/** + * struct seq_store - Structure to hold an array of pointers to the synthetic + * sequence structure. + * @num_sequence: Total number of "sequence of pulses" in the file. + * @seq_arr: Array of pointers to synthetic_seq structure. + */ + +struct seq_store { + uint8_t num_sequence; + struct synthetic_seq *seq_arr[0]; +}; +#endif /* WLAN_DFS_PARTIAL_OFFLOAD && WLAN_DFS_SYNTHETIC_RADAR */ #endif /* _DFS_IOCTL_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h index 9c409ccbfa..35f6f7f9b4 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h @@ -345,6 +345,46 @@ QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev, } #endif +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +/** + * ucfg_dfs_allow_hw_pulses() - Set or unset dfs-allow_hw_pulses + * which isolates synthetic radar pulse detection from actual radar detection. + * @pdev: Pointer to DFS pdev object. + * @allow_hw_pulses: Allow synthetic pulse detection true/false. + * + * Wrapper function for dfs_set_allow_hw_pulses(). + * This function called from outside of dfs component. + * + * Return: void + */ +void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev, + bool allow_hw_pulses); + +/** + * ucfg_dfs_is_hw_pulses_allowed() - Check if actual radar detection is allowed + * or synthetic pulse detection is enabled. + * @pdev: Pointer to DFS pdev object. + * + * Wrapper function for dfs_is_hw_pulses_allowed(). + * This function called from outside of dfs component. + * + * Return: bool + */ +bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev); +#else +static inline +void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev, + bool allow_hw_pulses) +{ +} + +static inline +bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev) +{ + return true; +} +#endif + /** * ucfg_dfs_get_override_status_timeout() - Get the value of host dfs status * wait timeout. diff --git a/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c b/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c index 1709fe17e2..2f284b4333 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -310,3 +310,42 @@ QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev, qdf_export_symbol(ucfg_dfs_get_override_status_timeout); #endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev, + bool allow_hw_pulses) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_allow_hw_pulses(dfs, allow_hw_pulses); +} + +qdf_export_symbol(ucfg_dfs_allow_hw_pulses); + +bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return false; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return false; + } + + return dfs_is_hw_pulses_allowed(dfs); +} + +qdf_export_symbol(ucfg_dfs_is_hw_pulses_allowed); +#endif