diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index f3769932e6..76c4b9205a 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -364,6 +364,28 @@ #define HOST_DFS_STATUS_WAIT_TIMER_MS 200 #endif +/* + * USENOL_DISABLE_NOL_HOST_AND_FW : Do not add radar hit channel to NOL + * in host and FW. Enable CSA on the same channel. + */ +#define USENOL_DISABLE_NOL_HOST_AND_FW 0 +/* + * USENOL_ENABLE_NOL_HOST_AND_FW : Add the radar hit channel to NOL in + * host and FW (in case of FO). NOL timer cannot be configured by the user + * as FW does not allow manipulating NOL timeout. If noltimeout is configured, + * (say 1 min) FW will not be intimated about the configuration and hence NOL + * timer may elapse at different instances in host (after 1 min) and FW (after + * default 30 min) which could lead to DFS Violation if host tries to come up + * on the channel after host NOL timeout (of 1 min) as the FW would still + * have the channel in NOL list. + */ +#define USENOL_ENABLE_NOL_HOST_AND_FW 1 +/* + * USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW : Add the radar hit channel to NOL + * in host. NOL timer can be configured by user. NOL in FW (for FO) is disabled. + */ +#define USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW 2 + /** * struct dfs_pulseparams - DFS pulse param structure. * @p_time: Time for start of pulse in usecs. @@ -979,6 +1001,7 @@ struct dfs_event_log { * @dfs_bw_reduced: DFS bandwidth reduced channel bit. * @dfs_freq_offset: Frequency offset where radar was found. * @dfs_cac_aborted: DFS cac is aborted. + * @dfs_disable_radar_marking: To mark or unmark NOL chan as radar hit. */ struct wlan_dfs { uint32_t dfs_debug_mask; @@ -1071,7 +1094,9 @@ struct wlan_dfs { os_timer_t dfs_precac_timer; int dfs_precac_timeout_override; uint8_t dfs_num_precac_freqs; - +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) + uint8_t dfs_disable_radar_marking; +#endif TAILQ_HEAD(, dfs_precac_entry) dfs_precac_required_list; TAILQ_HEAD(, dfs_precac_entry) dfs_precac_done_list; TAILQ_HEAD(, dfs_precac_entry) dfs_precac_nol_list; @@ -2472,4 +2497,27 @@ void dfs_task_testtimer_detach(struct wlan_dfs *dfs); * @dfs: Pointer to wlan_dfs structure. */ void dfs_timer_detach(struct wlan_dfs *dfs); + +/** + * dfs_is_disable_radar_marking_set() - Check if radar marking is set on + * NOL chan. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +int dfs_is_disable_radar_marking_set(struct wlan_dfs *dfs, + bool *disable_radar_marking); +#else +static inline int dfs_is_disable_radar_marking_set(struct wlan_dfs *dfs, + bool *disable_radar_marking) +{ + return QDF_STATUS_SUCCESS; +} +#endif +/** + * dfs_get_disable_radar_marking() - Get the value of disable radar marking. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs); +#endif #endif /* _DFS_H_ */ diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index 34b1488333..be8ffb6ab7 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/umac/dfs/core/src/misc/dfs.c @@ -33,6 +33,9 @@ #include "../dfs_etsi_precac.h" #include "../dfs_partial_offload_radar.h" +/* Disable NOL in FW. */ +#define DISABLE_NOL_FW 0 + #ifndef WLAN_DFS_STATIC_MEM_ALLOC /* * dfs_alloc_wlan_dfs() - allocate wlan_dfs buffer @@ -274,6 +277,35 @@ void dfs_destroy_object(struct wlan_dfs *dfs) } #endif +/* dfs_set_disable_radar_marking()- Set the flag to mark/unmark a radar flag + * on NOL channel. + * @dfs: Pointer to wlan_dfs structure. + * @disable_radar_marking: Flag to enable/disable marking channel as radar. + */ +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +static void dfs_set_disable_radar_marking(struct wlan_dfs *dfs, + bool disable_radar_marking) +{ + dfs->dfs_disable_radar_marking = disable_radar_marking; +} +#else +static inline void dfs_set_disable_radar_marking(struct wlan_dfs *dfs, + bool disable_radar_marking) +{ +} +#endif + +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs) +{ + return dfs->dfs_disable_radar_marking; +} +#else +static inline bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs) +{ + return QDF_STATUS_SUCCESS; +} +#endif int dfs_control(struct wlan_dfs *dfs, u_int id, void *indata, @@ -290,6 +322,7 @@ int dfs_control(struct wlan_dfs *dfs, uint32_t *data = NULL; int i; struct dfs_emulate_bang_radar_test_cmd dfs_unit_test; + int usenol_pdev_param; qdf_mem_zero(&dfs_unit_test, sizeof(dfs_unit_test)); @@ -574,6 +607,36 @@ int dfs_control(struct wlan_dfs *dfs, break; } dfs->dfs_use_nol = *(uint32_t *)indata; + usenol_pdev_param = dfs->dfs_use_nol; + if (dfs->dfs_is_offload_enabled) { + if (dfs->dfs_use_nol == + USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW) + usenol_pdev_param = DISABLE_NOL_FW; + tgt_dfs_send_usenol_pdev_param(dfs->dfs_pdev_obj, + usenol_pdev_param); + } + break; + case DFS_SET_DISABLE_RADAR_MARKING: + if (dfs->dfs_is_offload_enabled && + (utils_get_dfsdomain(dfs->dfs_pdev_obj) == + DFS_FCC_DOMAIN)) { + if (insize < sizeof(uint32_t) || !indata) { + error = -EINVAL; + break; + } + dfs_set_disable_radar_marking(dfs, *(uint8_t *)indata); + } + break; + case DFS_GET_DISABLE_RADAR_MARKING: + if (!outdata || !outsize || *outsize < sizeof(uint8_t)) { + error = -EINVAL; + break; + } + if (dfs->dfs_is_offload_enabled) { + *outsize = sizeof(uint8_t); + *((uint8_t *)outdata) = + dfs_get_disable_radar_marking(dfs); + } break; case DFS_GET_NOL: if (!outdata || !outsize || @@ -605,12 +668,12 @@ int dfs_control(struct wlan_dfs *dfs, dfs_print_nolhistory(dfs); break; case DFS_BANGRADAR: + dfs->dfs_bangradar = 1; if (dfs->dfs_is_offload_enabled) { error = dfs_fill_emulate_bang_radar_test(dfs, SEG_ID_PRIMARY, &dfs_unit_test); } else { - dfs->dfs_bangradar = 1; error = dfs_start_host_based_bangradar(dfs); } break; diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h b/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h index 87961ee88e..2ed5af1ad6 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h @@ -52,13 +52,15 @@ #define DFS_SHOW_PRECAC_LISTS 24 #define DFS_RESET_PRECAC_LISTS 25 #define DFS_BANGRADAR_ENH 26 +#define DFS_SET_DISABLE_RADAR_MARKING 27 +#define DFS_GET_DISABLE_RADAR_MARKING 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 diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h index 535c34a73c..73b5f9baad 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h @@ -267,4 +267,18 @@ bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, return true; } #endif + +/** + * dfs_mlme_handle_dfs_scan_violation() - Handle scan start failure + * due to DFS violation (presence of NOL channel in scan channel list). + * @pdev: Pointer to pdev object. + */ +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev); +#else +static inline +void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) +{ +} +#endif #endif /* _WLAN_DFS_MLME_API_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h index f56312ffb0..aac43dd84f 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h @@ -402,4 +402,22 @@ QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev) * Return: true if the pdev supports 5GHz, else false. */ bool tgt_dfs_is_pdev_5ghz(struct wlan_objmgr_pdev *pdev); +/** + * tgt_dfs_send_usenol_pdev_param() - Send usenol pdev param to FW. + * @pdev: Pointer to pdev object. + * @usenol: Value of usenol + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev, + bool usenol); +#else +static inline +QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev, + bool usenol) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* _WLAN_DFS_TGT_API_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h index 027c747fb3..69e8a19ebf 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h @@ -59,6 +59,8 @@ * @mlme_check_allowed_prim_chanlist: Check whether the given channel is * present in the primary allowed channel * list or not. + * @mlme_update_scan_channel_list: Update the scan channel list sent to FW. + * @mlme_bringdown_vaps: Bringdown vaps if no chans is present. */ struct dfs_to_mlme { QDF_STATUS (*pdev_component_obj_attach)(struct wlan_objmgr_pdev *pdev, @@ -141,6 +143,10 @@ struct dfs_to_mlme { (struct wlan_objmgr_pdev *pdev, int no_chans_avail); bool (*mlme_check_allowed_prim_chanlist) (struct wlan_objmgr_pdev *pdev, uint32_t chan_num); + QDF_STATUS (*mlme_update_scan_channel_list) + (struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*mlme_bringdown_vaps) + (struct wlan_objmgr_pdev *pdev); }; extern struct dfs_to_mlme global_dfs_to_mlme; diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h index 3f68a862af..f1e615b516 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h @@ -571,4 +571,22 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, */ bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev, bool *continue_current_cac); + +/** + * utils_dfs_get_disable_radar_marking - Retrieve the value of disable radar + * marking. + * @pdev: Pointer to DFS pdev object. + * @dis_radar_marking: pointer to retrieve the value of disable_radar_marking. + */ +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev, + bool *disable_radar_marking); +#else +static inline +QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev, + bool *disable_radar_marking) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* _WLAN_DFS_UTILS_API_H_ */ diff --git a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c index ceb3518f76..ded8ad9411 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c @@ -34,6 +34,8 @@ #include "a_types.h" #include "wlan_serialization_api.h" #include +#include "wlan_scan_ucfg_api.h" +#include "wlan_dfs_mlme_api.h" struct dfs_to_mlme global_dfs_to_mlme; @@ -102,6 +104,10 @@ void register_dfs_callbacks(void) mlme_dfs_restart_vaps_with_non_dfs_chan; tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist = mlme_dfs_check_allowed_prim_chanlist; + tmp_dfs_to_mlme->mlme_update_scan_channel_list = + mlme_dfs_update_scan_channel_list; + tmp_dfs_to_mlme->mlme_bringdown_vaps = + mlme_dfs_bringdown_vaps; /* * Register precac auto channel switch feature related callbacks diff --git a/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c b/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c index b727afb6d8..801d12f6dd 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c @@ -26,6 +26,7 @@ #include "wlan_objmgr_pdev_obj.h" #include "../../core/src/dfs.h" #include "scheduler_api.h" +#include #ifdef QCA_MCL_DFS_SUPPORT #include "wni_api.h" #endif @@ -322,4 +323,18 @@ bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev, chan_num); } + +#endif + +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) +{ + bool dfs_enable = 0; + + /*Disable all DFS channels in master channel list and ic channel list */ + ucfg_reg_enable_dfs_channels(pdev, dfs_enable); + + /* send the updated channel list to FW */ + global_dfs_to_mlme.mlme_update_scan_channel_list(pdev); +} #endif diff --git a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c index 41490e1b6f..a4cc0ea264 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c @@ -584,3 +584,29 @@ QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev) qdf_export_symbol(tgt_dfs_reset_spoof_test); #endif + +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev, + bool usenol) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); + return QDF_STATUS_E_FAILURE; + } + + dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); + if (dfs_tx_ops && dfs_tx_ops->dfs_send_usenol_pdev_param) + return dfs_tx_ops->dfs_send_usenol_pdev_param(pdev, usenol); + + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, + "dfs_tx_ops=%pK", dfs_tx_ops); + + return QDF_STATUS_E_FAILURE; +} + +qdf_export_symbol(tgt_dfs_send_usenol_pdev_param); +#endif diff --git a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index 8c41200a11..495dfca772 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -979,3 +979,26 @@ int dfs_get_num_chans(void) { return NUM_CHANNELS; } + +#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) +QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev, + bool *disable_radar_marking) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return QDF_STATUS_SUCCESS; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); + return QDF_STATUS_E_FAILURE; + } + + *disable_radar_marking = dfs_get_disable_radar_marking(dfs); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(utils_dfs_get_disable_radar_marking); +#endif