diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 76c4b9205aa1..09e4469947fd 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -186,6 +186,15 @@ #define PRECAC_LIST_LOCK_DESTROY(_dfs) qdf_spinlock_destroy( \ &(_dfs)->dfs_precac_lock) +#define WLAN_DFS_DATA_STRUCT_LOCK(_dfs) \ + qdf_spin_lock_bh(&(_dfs)->dfs_data_struct_lock) +#define WLAN_DFS_DATA_STRUCT_UNLOCK(_dfs) \ + qdf_spin_unlock_bh(&(_dfs)->dfs_data_struct_lock) +#define WLAN_DFS_DATA_STRUCT_LOCK_CREATE(_dfs) \ + qdf_spinlock_create(&(_dfs)->dfs_data_struct_lock) +#define WLAN_DFS_DATA_STRUCT_LOCK_DESTROY(_dfs) \ + qdf_spinlock_destroy(&(_dfs)->dfs_data_struct_lock) + /* Mask for time stamp from descriptor */ #define DFS_TSMASK 0xFFFFFFFF /* Shift for time stamp from descriptor */ @@ -1002,6 +1011,10 @@ struct dfs_event_log { * @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. + * @dfs_data_struct_lock: DFS data structure lock. This is to protect + * all the filtering data structures. For + * example: dfs_bin5radars, dfs_filtertype, + * etc. */ struct wlan_dfs { uint32_t dfs_debug_mask; @@ -1134,6 +1147,7 @@ struct wlan_dfs { uint8_t dfs_bw_reduced; int32_t dfs_freq_offset; bool dfs_cac_aborted; + qdf_spinlock_t dfs_data_struct_lock; }; /** diff --git a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c b/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c index e1a508c174bd..9493626d9ea0 100644 --- a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c +++ b/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c @@ -417,7 +417,9 @@ void dfs_get_po_radars(struct wlan_dfs *dfs) rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B; } + WLAN_DFS_DATA_STRUCT_LOCK(dfs); dfs_init_radar_filters(dfs, &rinfo); + WLAN_DFS_DATA_STRUCT_UNLOCK(dfs); } #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) diff --git a/umac/dfs/core/src/misc/dfs_filter_init.c b/umac/dfs/core/src/misc/dfs_filter_init.c index 723fe1a8c46d..33b579d1496c 100644 --- a/umac/dfs/core/src/misc/dfs_filter_init.c +++ b/umac/dfs/core/src/misc/dfs_filter_init.c @@ -117,7 +117,13 @@ static os_timer_func(dfs_task) return; } + /* Need to take a lock here since dfs filtering data structures are + * freed and re-allocated in dfs_init_radar_filters() during channel + * change which may happen in the middle of dfs pulse processing. + */ + WLAN_DFS_DATA_STRUCT_LOCK(dfs); dfs_process_radarevent(dfs, dfs->dfs_curchan); + WLAN_DFS_DATA_STRUCT_UNLOCK(dfs); dfs->wlan_radar_tasksched = 0; } @@ -220,6 +226,7 @@ int dfs_main_attach(struct wlan_dfs *dfs) STAILQ_INIT(&dfs->dfs_arq); STAILQ_INIT(&(dfs->dfs_eventq)); WLAN_DFSEVENTQ_LOCK_CREATE(dfs); + WLAN_DFS_DATA_STRUCT_LOCK_CREATE(dfs); dfs->events = dfs_alloc_dfs_events(); if (!(dfs->events)) { @@ -411,6 +418,7 @@ void dfs_main_detach(struct wlan_dfs *dfs) dfs->events = NULL; } + WLAN_DFS_DATA_STRUCT_LOCK_DESTROY(dfs); WLAN_DFSQ_LOCK_DESTROY(dfs); WLAN_ARQ_LOCK_DESTROY(dfs); WLAN_DFSEVENTQ_LOCK_DESTROY(dfs);