1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name *
5*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name * above copyright notice and this permission notice appear in all
8*5113495bSYour Name * copies.
9*5113495bSYour Name *
10*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name */
19*5113495bSYour Name
20*5113495bSYour Name /**
21*5113495bSYour Name * DOC: This file init/deint functions for DFS module.
22*5113495bSYour Name */
23*5113495bSYour Name
24*5113495bSYour Name #include "wlan_dfs_ucfg_api.h"
25*5113495bSYour Name #include "wlan_dfs_tgt_api.h"
26*5113495bSYour Name #include <wlan_objmgr_vdev_obj.h>
27*5113495bSYour Name #include "wlan_dfs_utils_api.h"
28*5113495bSYour Name #ifndef MOBILE_DFS_SUPPORT
29*5113495bSYour Name #include "ieee80211_mlme_dfs_interface.h"
30*5113495bSYour Name #endif
31*5113495bSYour Name #include "wlan_objmgr_global_obj.h"
32*5113495bSYour Name #include "wlan_dfs_init_deinit_api.h"
33*5113495bSYour Name #include "wlan_dfs_lmac_api.h"
34*5113495bSYour Name #include "../../core/src/dfs.h"
35*5113495bSYour Name #include "a_types.h"
36*5113495bSYour Name #include "wlan_serialization_api.h"
37*5113495bSYour Name #include <qdf_trace.h>
38*5113495bSYour Name #include "wlan_scan_ucfg_api.h"
39*5113495bSYour Name #include "wlan_dfs_mlme_api.h"
40*5113495bSYour Name #include "../../core/src/dfs_zero_cac.h"
41*5113495bSYour Name
42*5113495bSYour Name struct dfs_to_mlme global_dfs_to_mlme;
43*5113495bSYour Name
wlan_pdev_get_dfs_obj(struct wlan_objmgr_pdev * pdev)44*5113495bSYour Name struct wlan_dfs *wlan_pdev_get_dfs_obj(struct wlan_objmgr_pdev *pdev)
45*5113495bSYour Name {
46*5113495bSYour Name struct wlan_dfs *dfs;
47*5113495bSYour Name dfs = wlan_objmgr_pdev_get_comp_private_obj(pdev,
48*5113495bSYour Name WLAN_UMAC_COMP_DFS);
49*5113495bSYour Name
50*5113495bSYour Name return dfs;
51*5113495bSYour Name }
52*5113495bSYour Name
53*5113495bSYour Name /*
54*5113495bSYour Name * register_dfs_precac_auto_chan_callbacks_freq() - Register auto chan switch
55*5113495bSYour Name * frequency based APIs callback.
56*5113495bSYour Name * @mlme_callback: Pointer to dfs_to_mlme.
57*5113495bSYour Name */
58*5113495bSYour Name #ifndef MOBILE_DFS_SUPPORT
59*5113495bSYour Name #if defined(WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT) && defined(CONFIG_CHAN_FREQ_API)
60*5113495bSYour Name static inline void
register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme * mlme_callback)61*5113495bSYour Name register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback)
62*5113495bSYour Name {
63*5113495bSYour Name if (!mlme_callback)
64*5113495bSYour Name return;
65*5113495bSYour Name
66*5113495bSYour Name mlme_callback->mlme_precac_chan_change_csa_for_freq =
67*5113495bSYour Name mlme_dfs_precac_chan_change_csa_for_freq;
68*5113495bSYour Name }
69*5113495bSYour Name #else
70*5113495bSYour Name static inline void
register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme * mlme_callback)71*5113495bSYour Name register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback)
72*5113495bSYour Name {
73*5113495bSYour Name }
74*5113495bSYour Name #endif
75*5113495bSYour Name #endif
76*5113495bSYour Name
77*5113495bSYour Name /**
78*5113495bSYour Name * register_dfs_postnol_csa_callback - Register CSA callback
79*5113495bSYour Name * @mlme_callback: Pointer to dfs_to_mlme.
80*5113495bSYour Name */
81*5113495bSYour Name #ifndef MOBILE_DFS_SUPPORT
82*5113495bSYour Name #if defined(QCA_SUPPORT_DFS_CHAN_POSTNOL) || defined(QCA_DFS_BW_EXPAND)
83*5113495bSYour Name static inline void
register_dfs_postnol_csa_callback(struct dfs_to_mlme * mlme_callback)84*5113495bSYour Name register_dfs_postnol_csa_callback(struct dfs_to_mlme *mlme_callback)
85*5113495bSYour Name {
86*5113495bSYour Name if (!mlme_callback)
87*5113495bSYour Name return;
88*5113495bSYour Name
89*5113495bSYour Name mlme_callback->mlme_postnol_chan_switch =
90*5113495bSYour Name mlme_dfs_postnol_chan_switch;
91*5113495bSYour Name }
92*5113495bSYour Name #else
93*5113495bSYour Name static inline void
register_dfs_postnol_csa_callback(struct dfs_to_mlme * mlme_callback)94*5113495bSYour Name register_dfs_postnol_csa_callback(struct dfs_to_mlme *mlme_callback)
95*5113495bSYour Name {
96*5113495bSYour Name }
97*5113495bSYour Name #endif
98*5113495bSYour Name
99*5113495bSYour Name /**
100*5113495bSYour Name * register_dfs_unpunc_chan_switch_callback() - Register unpuncture channel VDEV
101*5113495bSYour Name * restart callback.
102*5113495bSYour Name * @mlme_callback: Pointer to dfs_to_mlme.
103*5113495bSYour Name */
104*5113495bSYour Name #if defined(QCA_DFS_BW_PUNCTURE) && !defined(CONFIG_REG_CLIENT)
105*5113495bSYour Name static inline void
register_dfs_unpunc_chan_switch_callback(struct dfs_to_mlme * mlme_callback)106*5113495bSYour Name register_dfs_unpunc_chan_switch_callback(struct dfs_to_mlme *mlme_callback)
107*5113495bSYour Name {
108*5113495bSYour Name if (!mlme_callback)
109*5113495bSYour Name return;
110*5113495bSYour Name
111*5113495bSYour Name mlme_callback->mlme_unpunc_chan_switch =
112*5113495bSYour Name mlme_dfs_unpunc_chan_switch;
113*5113495bSYour Name }
114*5113495bSYour Name #else
115*5113495bSYour Name static inline void
register_dfs_unpunc_chan_switch_callback(struct dfs_to_mlme * mlme_callback)116*5113495bSYour Name register_dfs_unpunc_chan_switch_callback(struct dfs_to_mlme *mlme_callback)
117*5113495bSYour Name {
118*5113495bSYour Name }
119*5113495bSYour Name #endif
120*5113495bSYour Name #endif /* MOBILE_DFS_SUPPORT */
121*5113495bSYour Name
122*5113495bSYour Name /*
123*5113495bSYour Name * register_dfs_callbacks_for_freq() - Register dfs callbacks.
124*5113495bSYour Name * @mlme_callback: Pointer to dfs_to_mlme.
125*5113495bSYour Name */
126*5113495bSYour Name #ifndef MOBILE_DFS_SUPPORT
127*5113495bSYour Name #ifdef CONFIG_CHAN_FREQ_API
128*5113495bSYour Name static inline void
register_dfs_callbacks_for_freq(struct dfs_to_mlme * mlme_callback)129*5113495bSYour Name register_dfs_callbacks_for_freq(struct dfs_to_mlme *mlme_callback)
130*5113495bSYour Name {
131*5113495bSYour Name if (!mlme_callback)
132*5113495bSYour Name return;
133*5113495bSYour Name
134*5113495bSYour Name mlme_callback->mlme_find_dot11_chan_for_freq =
135*5113495bSYour Name mlme_dfs_find_dot11_chan_for_freq;
136*5113495bSYour Name mlme_callback->mlme_get_cac_timeout_for_freq =
137*5113495bSYour Name mlme_dfs_get_cac_timeout_for_freq;
138*5113495bSYour Name mlme_callback->mlme_get_extchan_for_freq =
139*5113495bSYour Name mlme_dfs_get_extchan_for_freq;
140*5113495bSYour Name mlme_callback->mlme_start_csa_for_freq = mlme_dfs_start_csa_for_freq;
141*5113495bSYour Name }
142*5113495bSYour Name #endif
143*5113495bSYour Name #endif
144*5113495bSYour Name
145*5113495bSYour Name #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
register_dfs_callbacks_spoof_success_failure(struct dfs_to_mlme * tmp_dfs_to_mlme)146*5113495bSYour Name static void register_dfs_callbacks_spoof_success_failure(
147*5113495bSYour Name struct dfs_to_mlme *tmp_dfs_to_mlme)
148*5113495bSYour Name {
149*5113495bSYour Name tmp_dfs_to_mlme->mlme_rebuild_chan_list_with_non_dfs_channels =
150*5113495bSYour Name mlme_dfs_rebuild_chan_list_with_non_dfs_channels;
151*5113495bSYour Name tmp_dfs_to_mlme->mlme_proc_spoof_success =
152*5113495bSYour Name mlme_dfs_proc_spoof_success;
153*5113495bSYour Name }
154*5113495bSYour Name #else
register_dfs_callbacks_spoof_success_failure(struct dfs_to_mlme * tmp_dfs_to_mlme)155*5113495bSYour Name static inline void register_dfs_callbacks_spoof_success_failure(
156*5113495bSYour Name struct dfs_to_mlme *tmp_dfs_to_mlme)
157*5113495bSYour Name {
158*5113495bSYour Name }
159*5113495bSYour Name #endif
160*5113495bSYour Name
161*5113495bSYour Name #ifndef MOBILE_DFS_SUPPORT
register_dfs_callbacks(void)162*5113495bSYour Name void register_dfs_callbacks(void)
163*5113495bSYour Name {
164*5113495bSYour Name struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
165*5113495bSYour Name
166*5113495bSYour Name tmp_dfs_to_mlme->pdev_component_obj_attach =
167*5113495bSYour Name wlan_objmgr_pdev_component_obj_attach;
168*5113495bSYour Name tmp_dfs_to_mlme->pdev_component_obj_detach =
169*5113495bSYour Name wlan_objmgr_pdev_component_obj_detach;
170*5113495bSYour Name
171*5113495bSYour Name tmp_dfs_to_mlme->dfs_start_rcsa = mlme_dfs_start_rcsa;
172*5113495bSYour Name tmp_dfs_to_mlme->mlme_proc_cac = mlme_dfs_proc_cac;
173*5113495bSYour Name tmp_dfs_to_mlme->mlme_deliver_event_up_after_cac =
174*5113495bSYour Name mlme_dfs_deliver_event_up_after_cac;
175*5113495bSYour Name tmp_dfs_to_mlme->mlme_set_no_chans_available =
176*5113495bSYour Name mlme_dfs_set_no_chans_available;
177*5113495bSYour Name tmp_dfs_to_mlme->mlme_ieee2mhz = mlme_dfs_ieee2mhz;
178*5113495bSYour Name tmp_dfs_to_mlme->mlme_dfs_ch_flags_ext = mlme_dfs_dfs_ch_flags_ext;
179*5113495bSYour Name tmp_dfs_to_mlme->mlme_channel_change_by_precac =
180*5113495bSYour Name mlme_dfs_channel_change_by_precac;
181*5113495bSYour Name tmp_dfs_to_mlme->mlme_nol_timeout_notification =
182*5113495bSYour Name mlme_dfs_nol_timeout_notification;
183*5113495bSYour Name tmp_dfs_to_mlme->mlme_clist_update = mlme_dfs_clist_update;
184*5113495bSYour Name
185*5113495bSYour Name register_dfs_callbacks_spoof_success_failure(tmp_dfs_to_mlme);
186*5113495bSYour Name
187*5113495bSYour Name tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan =
188*5113495bSYour Name mlme_dfs_restart_vaps_with_non_dfs_chan;
189*5113495bSYour Name tmp_dfs_to_mlme->mlme_is_opmode_sta =
190*5113495bSYour Name mlme_dfs_is_opmode_sta;
191*5113495bSYour Name tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist =
192*5113495bSYour Name mlme_dfs_check_allowed_prim_chanlist;
193*5113495bSYour Name tmp_dfs_to_mlme->mlme_update_scan_channel_list =
194*5113495bSYour Name mlme_dfs_update_scan_channel_list;
195*5113495bSYour Name tmp_dfs_to_mlme->mlme_bringdown_vaps =
196*5113495bSYour Name mlme_dfs_bringdown_vaps;
197*5113495bSYour Name tmp_dfs_to_mlme->mlme_dfs_deliver_event =
198*5113495bSYour Name mlme_dfs_deliver_event;
199*5113495bSYour Name tmp_dfs_to_mlme->mlme_is_inter_band_chan_switch_allowed =
200*5113495bSYour Name mlme_is_inter_band_chan_switch_allowed;
201*5113495bSYour Name
202*5113495bSYour Name tmp_dfs_to_mlme->mlme_acquire_radar_mode_switch_lock =
203*5113495bSYour Name mlme_acquire_radar_mode_switch_lock;
204*5113495bSYour Name tmp_dfs_to_mlme->mlme_release_radar_mode_switch_lock =
205*5113495bSYour Name mlme_release_radar_mode_switch_lock;
206*5113495bSYour Name tmp_dfs_to_mlme->mlme_mark_dfs =
207*5113495bSYour Name mlme_dfs_mark_dfs;
208*5113495bSYour Name tmp_dfs_to_mlme->mlme_set_tx_flag = mlme_dfs_set_tx_flag;
209*5113495bSYour Name /*
210*5113495bSYour Name * Register precac auto channel switch feature related callbacks
211*5113495bSYour Name */
212*5113495bSYour Name register_dfs_precac_auto_chan_callbacks_freq(tmp_dfs_to_mlme);
213*5113495bSYour Name /* Register freq based callbacks */
214*5113495bSYour Name register_dfs_callbacks_for_freq(tmp_dfs_to_mlme);
215*5113495bSYour Name register_dfs_postnol_csa_callback(tmp_dfs_to_mlme);
216*5113495bSYour Name register_dfs_unpunc_chan_switch_callback(tmp_dfs_to_mlme);
217*5113495bSYour Name }
218*5113495bSYour Name #else
register_dfs_callbacks(void)219*5113495bSYour Name void register_dfs_callbacks(void)
220*5113495bSYour Name {
221*5113495bSYour Name struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
222*5113495bSYour Name
223*5113495bSYour Name tmp_dfs_to_mlme->pdev_component_obj_attach =
224*5113495bSYour Name wlan_objmgr_pdev_component_obj_attach;
225*5113495bSYour Name tmp_dfs_to_mlme->pdev_component_obj_detach =
226*5113495bSYour Name wlan_objmgr_pdev_component_obj_detach;
227*5113495bSYour Name }
228*5113495bSYour Name #endif
229*5113495bSYour Name
230*5113495bSYour Name /**
231*5113495bSYour Name * dfs_psoc_obj_create_notification() - dfs psoc create notification handler
232*5113495bSYour Name * @psoc: psoc object
233*5113495bSYour Name * @arg_list: Argument list
234*5113495bSYour Name *
235*5113495bSYour Name * Return: QDF_STATUS
236*5113495bSYour Name */
dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)237*5113495bSYour Name static QDF_STATUS dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
238*5113495bSYour Name void *arg_list)
239*5113495bSYour Name {
240*5113495bSYour Name QDF_STATUS status;
241*5113495bSYour Name struct dfs_soc_priv_obj *dfs_soc_obj;
242*5113495bSYour Name
243*5113495bSYour Name dfs_soc_obj = qdf_mem_malloc(sizeof(*dfs_soc_obj));
244*5113495bSYour Name if (!dfs_soc_obj)
245*5113495bSYour Name return QDF_STATUS_E_NOMEM;
246*5113495bSYour Name
247*5113495bSYour Name dfs_soc_obj->psoc = psoc;
248*5113495bSYour Name
249*5113495bSYour Name status = wlan_objmgr_psoc_component_obj_attach(psoc,
250*5113495bSYour Name WLAN_UMAC_COMP_DFS,
251*5113495bSYour Name (void *)dfs_soc_obj,
252*5113495bSYour Name QDF_STATUS_SUCCESS);
253*5113495bSYour Name
254*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
255*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
256*5113495bSYour Name "Failed to attach psoc dfs component");
257*5113495bSYour Name qdf_mem_free(dfs_soc_obj);
258*5113495bSYour Name return status;
259*5113495bSYour Name }
260*5113495bSYour Name /* Initialize precac timer here*/
261*5113495bSYour Name dfs_zero_cac_timer_init(dfs_soc_obj);
262*5113495bSYour Name
263*5113495bSYour Name /* Initialize Rolling CAC timer */
264*5113495bSYour Name dfs_rcac_timer_init(dfs_soc_obj);
265*5113495bSYour Name
266*5113495bSYour Name /* DFS Agile SM initialization */
267*5113495bSYour Name dfs_agile_sm_create(dfs_soc_obj);
268*5113495bSYour Name
269*5113495bSYour Name dfs_debug(NULL, WLAN_DEBUG_DFS1,
270*5113495bSYour Name "DFS obj attach to psoc successfully");
271*5113495bSYour Name
272*5113495bSYour Name return status;
273*5113495bSYour Name }
274*5113495bSYour Name
275*5113495bSYour Name /**
276*5113495bSYour Name * dfs_psoc_obj_destroy_notification() - dfs psoc destroy notification handler
277*5113495bSYour Name * @psoc: psoc object
278*5113495bSYour Name * @arg_list: Argument list
279*5113495bSYour Name *
280*5113495bSYour Name * Return: QDF_STATUS
281*5113495bSYour Name */
dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)282*5113495bSYour Name static QDF_STATUS dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
283*5113495bSYour Name void *arg_list)
284*5113495bSYour Name {
285*5113495bSYour Name QDF_STATUS status;
286*5113495bSYour Name struct dfs_soc_priv_obj *dfs_soc_obj;
287*5113495bSYour Name
288*5113495bSYour Name dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
289*5113495bSYour Name WLAN_UMAC_COMP_DFS);
290*5113495bSYour Name if (!dfs_soc_obj) {
291*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
292*5113495bSYour Name "Failed to get dfs obj in psoc");
293*5113495bSYour Name return QDF_STATUS_E_FAILURE;
294*5113495bSYour Name }
295*5113495bSYour Name
296*5113495bSYour Name /* Delete DFS Agile SM */
297*5113495bSYour Name dfs_agile_sm_destroy(dfs_soc_obj);
298*5113495bSYour Name
299*5113495bSYour Name dfs_rcac_timer_deinit(dfs_soc_obj);
300*5113495bSYour Name dfs_zero_cac_timer_detach(dfs_soc_obj);
301*5113495bSYour Name
302*5113495bSYour Name status = wlan_objmgr_psoc_component_obj_detach(psoc,
303*5113495bSYour Name WLAN_UMAC_COMP_DFS,
304*5113495bSYour Name dfs_soc_obj);
305*5113495bSYour Name
306*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
307*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
308*5113495bSYour Name "Failed to detach psoc dfs component");
309*5113495bSYour Name
310*5113495bSYour Name qdf_mem_free(dfs_soc_obj);
311*5113495bSYour Name
312*5113495bSYour Name return status;
313*5113495bSYour Name }
314*5113495bSYour Name
dfs_init(void)315*5113495bSYour Name QDF_STATUS dfs_init(void)
316*5113495bSYour Name {
317*5113495bSYour Name QDF_STATUS status;
318*5113495bSYour Name
319*5113495bSYour Name status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_DFS,
320*5113495bSYour Name dfs_psoc_obj_create_notification,
321*5113495bSYour Name NULL);
322*5113495bSYour Name
323*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
324*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
325*5113495bSYour Name "Failed to register psoc create handler for dfs");
326*5113495bSYour Name goto err_psoc_create;
327*5113495bSYour Name }
328*5113495bSYour Name
329*5113495bSYour Name status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
330*5113495bSYour Name dfs_psoc_obj_destroy_notification,
331*5113495bSYour Name NULL);
332*5113495bSYour Name
333*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
334*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
335*5113495bSYour Name "Failed to register psoc delete handler for dfs");
336*5113495bSYour Name goto err_psoc_delete;
337*5113495bSYour Name }
338*5113495bSYour Name
339*5113495bSYour Name register_dfs_callbacks();
340*5113495bSYour Name
341*5113495bSYour Name status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_DFS,
342*5113495bSYour Name wlan_dfs_pdev_obj_create_notification,
343*5113495bSYour Name NULL);
344*5113495bSYour Name
345*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
346*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
347*5113495bSYour Name "Failed to register pdev create handler for dfs");
348*5113495bSYour Name goto err_pdev_create;
349*5113495bSYour Name }
350*5113495bSYour Name
351*5113495bSYour Name status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
352*5113495bSYour Name wlan_dfs_pdev_obj_destroy_notification,
353*5113495bSYour Name NULL);
354*5113495bSYour Name
355*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
356*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
357*5113495bSYour Name "Failed to register pdev delete handler for dfs");
358*5113495bSYour Name goto err_pdev_delete;
359*5113495bSYour Name }
360*5113495bSYour Name
361*5113495bSYour Name status = qdf_print_set_category_verbose(qdf_get_pidx(),
362*5113495bSYour Name QDF_MODULE_ID_DFS,
363*5113495bSYour Name QDF_TRACE_LEVEL_DEBUG,
364*5113495bSYour Name true);
365*5113495bSYour Name
366*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
367*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
368*5113495bSYour Name "Failed to set verbose for category");
369*5113495bSYour Name goto err_category_verbose;
370*5113495bSYour Name }
371*5113495bSYour Name
372*5113495bSYour Name return QDF_STATUS_SUCCESS;
373*5113495bSYour Name
374*5113495bSYour Name err_category_verbose:
375*5113495bSYour Name wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
376*5113495bSYour Name wlan_dfs_pdev_obj_destroy_notification,
377*5113495bSYour Name NULL);
378*5113495bSYour Name err_pdev_delete:
379*5113495bSYour Name wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS,
380*5113495bSYour Name wlan_dfs_pdev_obj_create_notification,
381*5113495bSYour Name NULL);
382*5113495bSYour Name err_pdev_create:
383*5113495bSYour Name wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
384*5113495bSYour Name dfs_psoc_obj_destroy_notification,
385*5113495bSYour Name NULL);
386*5113495bSYour Name err_psoc_delete:
387*5113495bSYour Name wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS,
388*5113495bSYour Name dfs_psoc_obj_create_notification,
389*5113495bSYour Name NULL);
390*5113495bSYour Name err_psoc_create:
391*5113495bSYour Name return status;
392*5113495bSYour Name }
393*5113495bSYour Name
dfs_deinit(void)394*5113495bSYour Name QDF_STATUS dfs_deinit(void)
395*5113495bSYour Name {
396*5113495bSYour Name QDF_STATUS status;
397*5113495bSYour Name
398*5113495bSYour Name status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS,
399*5113495bSYour Name dfs_psoc_obj_create_notification,
400*5113495bSYour Name NULL);
401*5113495bSYour Name
402*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
403*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
404*5113495bSYour Name "Failed to deregister dfs psoc obj create");
405*5113495bSYour Name
406*5113495bSYour Name status = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
407*5113495bSYour Name dfs_psoc_obj_destroy_notification,
408*5113495bSYour Name NULL);
409*5113495bSYour Name
410*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
411*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
412*5113495bSYour Name "Failed to deregister dfs psoc obj destroy");
413*5113495bSYour Name
414*5113495bSYour Name status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS,
415*5113495bSYour Name wlan_dfs_pdev_obj_create_notification,
416*5113495bSYour Name NULL);
417*5113495bSYour Name
418*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
419*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
420*5113495bSYour Name "Failed to deregister dfs pdev obj create");
421*5113495bSYour Name
422*5113495bSYour Name status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
423*5113495bSYour Name wlan_dfs_pdev_obj_destroy_notification,
424*5113495bSYour Name NULL);
425*5113495bSYour Name
426*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
427*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
428*5113495bSYour Name "Failed to deregister dfs pdev obj destroy");
429*5113495bSYour Name
430*5113495bSYour Name return QDF_STATUS_SUCCESS;
431*5113495bSYour Name }
432*5113495bSYour Name
wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev * pdev,void * arg)433*5113495bSYour Name QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
434*5113495bSYour Name void *arg)
435*5113495bSYour Name {
436*5113495bSYour Name struct wlan_dfs *dfs = NULL;
437*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
438*5113495bSYour Name struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
439*5113495bSYour Name struct dfs_soc_priv_obj *dfs_soc_obj;
440*5113495bSYour Name uint8_t pdev_id;
441*5113495bSYour Name QDF_STATUS status;
442*5113495bSYour Name bool is_5ghz = false;
443*5113495bSYour Name bool is_6ghz_only_pdev;
444*5113495bSYour Name qdf_freq_t low_5g, high_5g;
445*5113495bSYour Name
446*5113495bSYour Name if (!pdev) {
447*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null pdev");
448*5113495bSYour Name return QDF_STATUS_E_FAILURE;
449*5113495bSYour Name }
450*5113495bSYour Name
451*5113495bSYour Name psoc = wlan_pdev_get_psoc(pdev);
452*5113495bSYour Name if (!psoc) {
453*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
454*5113495bSYour Name return QDF_STATUS_E_FAILURE;
455*5113495bSYour Name }
456*5113495bSYour Name
457*5113495bSYour Name wlan_reg_get_freq_range(pdev, NULL, NULL, &low_5g, &high_5g);
458*5113495bSYour Name is_6ghz_only_pdev = wlan_reg_is_range_only6g(low_5g, high_5g);
459*5113495bSYour Name
460*5113495bSYour Name if (is_6ghz_only_pdev) {
461*5113495bSYour Name pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
462*5113495bSYour Name dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
463*5113495bSYour Name "Do not allocate DFS object for 6G, pdev_id = %d",
464*5113495bSYour Name pdev_id);
465*5113495bSYour Name return QDF_STATUS_SUCCESS;
466*5113495bSYour Name }
467*5113495bSYour Name
468*5113495bSYour Name dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
469*5113495bSYour Name if (!(dfs_tx_ops && dfs_tx_ops->dfs_is_pdev_5ghz)) {
470*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_tx_ops is null");
471*5113495bSYour Name return QDF_STATUS_E_FAILURE;
472*5113495bSYour Name }
473*5113495bSYour Name
474*5113495bSYour Name status = dfs_tx_ops->dfs_is_pdev_5ghz(pdev, &is_5ghz);
475*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
476*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "Failed to get is_5ghz value");
477*5113495bSYour Name return QDF_STATUS_E_FAILURE;
478*5113495bSYour Name }
479*5113495bSYour Name
480*5113495bSYour Name if (!is_5ghz) {
481*5113495bSYour Name pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
482*5113495bSYour Name dfs_info(dfs, WLAN_DEBUG_DFS,
483*5113495bSYour Name "Do not allocate DFS object for 2G, pdev_id = %d",
484*5113495bSYour Name pdev_id);
485*5113495bSYour Name return QDF_STATUS_SUCCESS;
486*5113495bSYour Name }
487*5113495bSYour Name
488*5113495bSYour Name if (dfs_create_object(&dfs) == 1) {
489*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "failed to create object");
490*5113495bSYour Name return QDF_STATUS_E_FAILURE;
491*5113495bSYour Name }
492*5113495bSYour Name
493*5113495bSYour Name status = global_dfs_to_mlme.pdev_component_obj_attach(pdev,
494*5113495bSYour Name WLAN_UMAC_COMP_DFS, (void *)dfs, QDF_STATUS_SUCCESS);
495*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
496*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "obj attach failed");
497*5113495bSYour Name dfs_destroy_object(dfs);
498*5113495bSYour Name return QDF_STATUS_E_FAILURE;
499*5113495bSYour Name }
500*5113495bSYour Name
501*5113495bSYour Name dfs->dfs_pdev_obj = pdev;
502*5113495bSYour Name
503*5113495bSYour Name if (!dfs_tx_ops->dfs_is_tgt_offload) {
504*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
505*5113495bSYour Name "dfs_is_tgt_offload is null");
506*5113495bSYour Name dfs_destroy_object(dfs);
507*5113495bSYour Name return QDF_STATUS_E_FAILURE;
508*5113495bSYour Name }
509*5113495bSYour Name
510*5113495bSYour Name dfs->dfs_is_offload_enabled = dfs_tx_ops->dfs_is_tgt_offload(psoc);
511*5113495bSYour Name dfs_info(dfs, WLAN_DEBUG_DFS, "dfs_offload %d",
512*5113495bSYour Name dfs->dfs_is_offload_enabled);
513*5113495bSYour Name
514*5113495bSYour Name if (!dfs_tx_ops->dfs_is_tgt_bangradar_320_supp) {
515*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
516*5113495bSYour Name "dfs_is_tgt_bangradar_320_supp is null");
517*5113495bSYour Name dfs_destroy_object(dfs);
518*5113495bSYour Name return QDF_STATUS_E_FAILURE;
519*5113495bSYour Name }
520*5113495bSYour Name
521*5113495bSYour Name dfs->dfs_is_bangradar_320_supported =
522*5113495bSYour Name dfs_tx_ops->dfs_is_tgt_bangradar_320_supp(psoc);
523*5113495bSYour Name dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_bangradar_320_support %d",
524*5113495bSYour Name dfs->dfs_is_bangradar_320_supported);
525*5113495bSYour Name
526*5113495bSYour Name if (!dfs_tx_ops->dfs_is_tgt_radar_found_chan_freq_eq_center_freq) {
527*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
528*5113495bSYour Name "dfs_is_radar_found_chan_freq_eq_center_freq is null");
529*5113495bSYour Name dfs_destroy_object(dfs);
530*5113495bSYour Name return QDF_STATUS_E_FAILURE;
531*5113495bSYour Name }
532*5113495bSYour Name
533*5113495bSYour Name dfs->dfs_is_radar_found_chan_freq_eq_center_freq =
534*5113495bSYour Name dfs_tx_ops->dfs_is_tgt_radar_found_chan_freq_eq_center_freq(psoc);
535*5113495bSYour Name dfs_info(dfs, WLAN_DEBUG_DFS,
536*5113495bSYour Name "dfs_is_radar_found_chan_freq_eq_center_freq %d",
537*5113495bSYour Name dfs->dfs_is_radar_found_chan_freq_eq_center_freq);
538*5113495bSYour Name
539*5113495bSYour Name dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
540*5113495bSYour Name WLAN_UMAC_COMP_DFS);
541*5113495bSYour Name dfs->dfs_soc_obj = dfs_soc_obj;
542*5113495bSYour Name dfs_agile_soc_obj_init(dfs, psoc);
543*5113495bSYour Name dfs_create_punc_sm(dfs);
544*5113495bSYour Name
545*5113495bSYour Name if (dfs_attach(dfs) == 1) {
546*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_attch failed");
547*5113495bSYour Name dfs_destroy_object(dfs);
548*5113495bSYour Name return QDF_STATUS_E_FAILURE;
549*5113495bSYour Name }
550*5113495bSYour Name
551*5113495bSYour Name return QDF_STATUS_SUCCESS;
552*5113495bSYour Name }
553*5113495bSYour Name
wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev * pdev,void * arg)554*5113495bSYour Name QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
555*5113495bSYour Name void *arg)
556*5113495bSYour Name {
557*5113495bSYour Name struct wlan_dfs *dfs = NULL;
558*5113495bSYour Name
559*5113495bSYour Name if (!pdev) {
560*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "PDEV is NULL");
561*5113495bSYour Name return QDF_STATUS_E_FAILURE;
562*5113495bSYour Name }
563*5113495bSYour Name
564*5113495bSYour Name dfs = wlan_pdev_get_dfs_obj(pdev);
565*5113495bSYour Name
566*5113495bSYour Name /* DFS is NULL during unload. should we call this function before */
567*5113495bSYour Name if (dfs) {
568*5113495bSYour Name dfs_destroy_punc_sm(dfs);
569*5113495bSYour Name dfs_detach(dfs);
570*5113495bSYour Name global_dfs_to_mlme.pdev_component_obj_detach(pdev,
571*5113495bSYour Name WLAN_UMAC_COMP_DFS,
572*5113495bSYour Name (void *)dfs);
573*5113495bSYour Name
574*5113495bSYour Name dfs->dfs_pdev_obj = NULL;
575*5113495bSYour Name dfs_destroy_object(dfs);
576*5113495bSYour Name }
577*5113495bSYour Name
578*5113495bSYour Name return QDF_STATUS_SUCCESS;
579*5113495bSYour Name }
580*5113495bSYour Name
dfs_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev * vdev,union wlan_serialization_rules_info * comp_info,struct wlan_serialization_command * cmd)581*5113495bSYour Name static void dfs_scan_serialization_comp_info_cb(
582*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
583*5113495bSYour Name union wlan_serialization_rules_info *comp_info,
584*5113495bSYour Name struct wlan_serialization_command *cmd)
585*5113495bSYour Name {
586*5113495bSYour Name struct wlan_dfs *dfs = NULL;
587*5113495bSYour Name struct wlan_objmgr_pdev *pdev;
588*5113495bSYour Name
589*5113495bSYour Name if (!comp_info) {
590*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "comp_info is NULL");
591*5113495bSYour Name return;
592*5113495bSYour Name }
593*5113495bSYour Name
594*5113495bSYour Name if (!vdev) {
595*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "vdev is NULL");
596*5113495bSYour Name return;
597*5113495bSYour Name }
598*5113495bSYour Name
599*5113495bSYour Name pdev = wlan_vdev_get_pdev(vdev);
600*5113495bSYour Name if (!pdev) {
601*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "pdev is NULL");
602*5113495bSYour Name return;
603*5113495bSYour Name }
604*5113495bSYour Name
605*5113495bSYour Name comp_info->scan_info.is_cac_in_progress = false;
606*5113495bSYour Name
607*5113495bSYour Name if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
608*5113495bSYour Name return;
609*5113495bSYour Name
610*5113495bSYour Name dfs = wlan_pdev_get_dfs_obj(pdev);
611*5113495bSYour Name if (!dfs) {
612*5113495bSYour Name dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
613*5113495bSYour Name return;
614*5113495bSYour Name }
615*5113495bSYour Name
616*5113495bSYour Name if (dfs_is_ap_cac_timer_running(dfs))
617*5113495bSYour Name comp_info->scan_info.is_cac_in_progress = true;
618*5113495bSYour Name }
619*5113495bSYour Name
wifi_dfs_psoc_enable(struct wlan_objmgr_psoc * psoc)620*5113495bSYour Name QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc)
621*5113495bSYour Name {
622*5113495bSYour Name QDF_STATUS status;
623*5113495bSYour Name
624*5113495bSYour Name status = tgt_dfs_reg_ev_handler(psoc);
625*5113495bSYour Name if (status != QDF_STATUS_SUCCESS) {
626*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "tgt_dfs_reg_ev_handler failed");
627*5113495bSYour Name return QDF_STATUS_E_FAILURE;
628*5113495bSYour Name }
629*5113495bSYour Name
630*5113495bSYour Name status = wlan_serialization_register_comp_info_cb(psoc,
631*5113495bSYour Name WLAN_UMAC_COMP_DFS,
632*5113495bSYour Name WLAN_SER_CMD_SCAN,
633*5113495bSYour Name dfs_scan_serialization_comp_info_cb);
634*5113495bSYour Name if (status != QDF_STATUS_SUCCESS) {
635*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Serialize scan cmd register failed");
636*5113495bSYour Name return status;
637*5113495bSYour Name }
638*5113495bSYour Name
639*5113495bSYour Name return QDF_STATUS_SUCCESS;
640*5113495bSYour Name }
641*5113495bSYour Name
wifi_dfs_psoc_disable(struct wlan_objmgr_psoc * psoc)642*5113495bSYour Name QDF_STATUS wifi_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc)
643*5113495bSYour Name {
644*5113495bSYour Name QDF_STATUS status;
645*5113495bSYour Name
646*5113495bSYour Name status = wlan_serialization_deregister_comp_info_cb(psoc,
647*5113495bSYour Name WLAN_UMAC_COMP_DFS,
648*5113495bSYour Name WLAN_SER_CMD_SCAN);
649*5113495bSYour Name if (status != QDF_STATUS_SUCCESS) {
650*5113495bSYour Name dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Serialize scan cmd deregister failed");
651*5113495bSYour Name return status;
652*5113495bSYour Name }
653*5113495bSYour Name
654*5113495bSYour Name return QDF_STATUS_SUCCESS;
655*5113495bSYour Name }
656