1  /*
2   * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4   *
5   *
6   * Permission to use, copy, modify, and/or distribute this software for
7   * any purpose with or without fee is hereby granted, provided that the
8   * above copyright notice and this permission notice appear in all
9   * copies.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18   * PERFORMANCE OF THIS SOFTWARE.
19   */
20  
21  /**
22   * DOC: Functions to call mlme functions from DFS component.
23   */
24  
25  #include "wlan_dfs_mlme_api.h"
26  #include "wlan_objmgr_vdev_obj.h"
27  #include "wlan_objmgr_pdev_obj.h"
28  #include "../../core/src/dfs.h"
29  #include "scheduler_api.h"
30  #include <wlan_reg_ucfg_api.h>
31  #ifdef MOBILE_DFS_SUPPORT
32  #include "wni_api.h"
33  #endif
34  
35  #if defined(QCA_DFS_RCSA_SUPPORT)
dfs_mlme_start_rcsa(struct wlan_objmgr_pdev * pdev,bool * wait_for_csa)36  void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev,
37  		bool *wait_for_csa)
38  {
39  	if (global_dfs_to_mlme.dfs_start_rcsa)
40  		global_dfs_to_mlme.dfs_start_rcsa(pdev, wait_for_csa);
41  }
42  #endif
43  
44  #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
dfs_mlme_proc_spoof_success(struct wlan_objmgr_pdev * pdev)45  void dfs_mlme_proc_spoof_success(struct wlan_objmgr_pdev *pdev)
46  {
47  	if (global_dfs_to_mlme.mlme_proc_spoof_success)
48  		global_dfs_to_mlme.mlme_proc_spoof_success(pdev);
49  }
50  #endif
51  
52  #ifndef MOBILE_DFS_SUPPORT
dfs_mlme_mark_dfs(struct wlan_objmgr_pdev * pdev,uint8_t ieee,uint16_t freq,uint16_t vhtop_ch_freq_seg2,uint64_t flags,uint16_t dfs_radar_bitmap)53  void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
54  		uint8_t ieee,
55  		uint16_t freq,
56  		uint16_t vhtop_ch_freq_seg2,
57  		uint64_t flags,
58  		uint16_t dfs_radar_bitmap)
59  {
60  	if (global_dfs_to_mlme.mlme_mark_dfs)
61  		global_dfs_to_mlme.mlme_mark_dfs(pdev,
62  				ieee,
63  				freq,
64  				vhtop_ch_freq_seg2,
65  				flags,
66  				dfs_radar_bitmap);
67  }
68  #else /* Else of ndef MCL_DFS_SUPPORT */
dfs_send_radar_ind(struct wlan_objmgr_pdev * pdev,void * object,void * arg)69  static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev,
70  		void *object,
71  		void *arg)
72  {
73  	struct scheduler_msg sme_msg = {0};
74  	uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object);
75  
76  	sme_msg.type = eWNI_SME_DFS_RADAR_FOUND;
77  	sme_msg.bodyptr = NULL;
78  	sme_msg.bodyval = vdev_id;
79  	scheduler_post_message(QDF_MODULE_ID_DFS,
80  			       QDF_MODULE_ID_SME,
81  			       QDF_MODULE_ID_SME, &sme_msg);
82  	dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted",
83  		  vdev_id);
84  }
85  
dfs_mlme_mark_dfs(struct wlan_objmgr_pdev * pdev,uint8_t ieee,uint16_t freq,uint16_t vhtop_ch_freq_seg2,uint64_t flags,uint16_t dfs_radar_bitmap)86  void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
87  		uint8_t ieee,
88  		uint16_t freq,
89  		uint16_t vhtop_ch_freq_seg2,
90  		uint64_t flags,
91  		uint16_t dfs_radar_bitmap)
92  {
93  	struct wlan_objmgr_vdev *vdev;
94  
95  	if (!pdev) {
96  		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
97  		return;
98  	}
99  
100  	vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID);
101  
102  	if (vdev) {
103  		dfs_send_radar_ind(pdev, vdev, NULL);
104  		wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
105  	}
106  }
107  #endif
108  
109  #ifndef MOBILE_DFS_SUPPORT
110  #ifdef CONFIG_CHAN_FREQ_API
dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev * pdev,uint8_t ieee_chan,uint16_t freq,uint16_t cfreq2,uint64_t flags)111  void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev,
112  				 uint8_t ieee_chan, uint16_t freq,
113  				 uint16_t cfreq2, uint64_t flags)
114  {
115  	if (global_dfs_to_mlme.mlme_start_csa_for_freq)
116  		global_dfs_to_mlme.mlme_start_csa_for_freq(pdev, ieee_chan,
117  							   freq, cfreq2, flags);
118  }
119  #endif
120  #else
121  #ifdef CONFIG_CHAN_FREQ_API
dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev * pdev,uint8_t ieee_chan,uint16_t freq,uint16_t cfreq2,uint64_t flags)122  void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev,
123  				 uint8_t ieee_chan, uint16_t freq,
124  				 uint16_t cfreq2, uint64_t flags)
125  {
126  	struct wlan_objmgr_vdev *vdev;
127  
128  	if (!pdev) {
129  		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
130  		return;
131  	}
132  
133  	vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID);
134  
135  	if (vdev) {
136  		dfs_send_radar_ind(pdev, vdev, NULL);
137  		wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
138  	}
139  }
140  #endif
141  #endif
142  
143  #ifndef MOBILE_DFS_SUPPORT
dfs_mlme_proc_cac(struct wlan_objmgr_pdev * pdev,uint32_t vdev_id)144  void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
145  {
146  	if (global_dfs_to_mlme.mlme_proc_cac)
147  		global_dfs_to_mlme.mlme_proc_cac(pdev);
148  }
149  #else
dfs_mlme_proc_cac(struct wlan_objmgr_pdev * pdev,uint32_t vdev_id)150  void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
151  {
152  	struct scheduler_msg sme_msg = {0};
153  
154  	sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE;
155  	sme_msg.bodyptr = NULL;
156  	sme_msg.bodyval = vdev_id;
157  	scheduler_post_message(QDF_MODULE_ID_DFS,
158  			       QDF_MODULE_ID_SME,
159  			       QDF_MODULE_ID_SME, &sme_msg);
160  	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_CAC_COMPLETE vdev%d posted",
161  		    vdev_id);
162  }
163  #endif
164  
dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev * pdev)165  void dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev *pdev)
166  {
167  	if (global_dfs_to_mlme.mlme_deliver_event_up_after_cac)
168  		global_dfs_to_mlme.mlme_deliver_event_up_after_cac(
169  				pdev);
170  }
171  
172  #ifdef CONFIG_CHAN_FREQ_API
dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t * dfs_chan_freq,uint64_t * dfs_chan_flags,uint16_t * dfs_chan_flagext,uint8_t * dfs_chan_ieee,uint8_t * dfs_chan_vhtop_ch_freq_seg1,uint8_t * dfs_chan_vhtop_ch_freq_seg2,uint16_t * dfs_chan_mhz_freq_seg1,uint16_t * dfs_chan_mhz_freq_seg2)173  QDF_STATUS dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev *pdev,
174  					 uint16_t *dfs_chan_freq,
175  					 uint64_t *dfs_chan_flags,
176  					 uint16_t *dfs_chan_flagext,
177  					 uint8_t *dfs_chan_ieee,
178  					 uint8_t *dfs_chan_vhtop_ch_freq_seg1,
179  					 uint8_t *dfs_chan_vhtop_ch_freq_seg2,
180  					 uint16_t *dfs_chan_mhz_freq_seg1,
181  					 uint16_t *dfs_chan_mhz_freq_seg2)
182  {
183  	if (global_dfs_to_mlme.mlme_get_extchan_for_freq)
184  		return global_dfs_to_mlme.mlme_get_extchan_for_freq(pdev,
185  				dfs_chan_freq,
186  				dfs_chan_flags,
187  				dfs_chan_flagext,
188  				dfs_chan_ieee,
189  				dfs_chan_vhtop_ch_freq_seg1,
190  				dfs_chan_vhtop_ch_freq_seg2,
191  				dfs_chan_mhz_freq_seg1,
192  				dfs_chan_mhz_freq_seg2);
193  
194  	return QDF_STATUS_E_FAILURE;
195  }
196  #endif
197  
dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev * pdev,int val)198  void dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev *pdev,
199  		int val)
200  {
201  	if (global_dfs_to_mlme.mlme_set_no_chans_available)
202  		global_dfs_to_mlme.mlme_set_no_chans_available(
203  				pdev,
204  				val);
205  }
206  
dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev * pdev,int ieee,uint64_t flag)207  int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag)
208  {
209  	int freq = 0;
210  
211  	if (global_dfs_to_mlme.mlme_ieee2mhz)
212  		global_dfs_to_mlme.mlme_ieee2mhz(pdev,
213  				ieee,
214  				flag,
215  				&freq);
216  
217  	return freq;
218  }
219  
220  #ifdef CONFIG_CHAN_FREQ_API
221  QDF_STATUS
dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t freq,uint16_t des_cfreq2,int mode,uint16_t * dfs_chan_freq,uint64_t * dfs_chan_flag,uint16_t * dfs_flagext,uint8_t * dfs_chan_ieee,uint8_t * dfs_cfreq1,uint8_t * dfs_cfreq2,uint16_t * cfreq1_mhz,uint16_t * cfreq2_mhz)222  dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev *pdev,
223  				  uint16_t freq,
224  				  uint16_t des_cfreq2,
225  				  int mode,
226  				  uint16_t *dfs_chan_freq,
227  				  uint64_t *dfs_chan_flag,
228  				  uint16_t *dfs_flagext,
229  				  uint8_t *dfs_chan_ieee,
230  				  uint8_t *dfs_cfreq1,
231  				  uint8_t *dfs_cfreq2,
232  				  uint16_t *cfreq1_mhz,
233  				  uint16_t *cfreq2_mhz)
234  {
235  	if (global_dfs_to_mlme.mlme_find_dot11_chan_for_freq)
236  	return global_dfs_to_mlme.mlme_find_dot11_chan_for_freq(pdev,
237  								freq,
238  								des_cfreq2,
239  								mode,
240  								dfs_chan_freq,
241  								dfs_chan_flag,
242  								dfs_flagext,
243  								dfs_chan_ieee,
244  								dfs_cfreq1,
245  								dfs_cfreq2,
246  								cfreq1_mhz,
247  								cfreq2_mhz);
248  	return QDF_STATUS_E_FAILURE;
249  }
250  #endif
251  
252  
dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev * pdev)253  uint32_t dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev *pdev)
254  {
255  	uint16_t flag_ext = 0;
256  
257  	if (global_dfs_to_mlme.mlme_dfs_ch_flags_ext)
258  		global_dfs_to_mlme.mlme_dfs_ch_flags_ext(pdev,
259  				&flag_ext);
260  
261  	return flag_ext;
262  }
263  
dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev * pdev)264  void dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev *pdev)
265  {
266  	if (global_dfs_to_mlme.mlme_channel_change_by_precac)
267  		global_dfs_to_mlme.mlme_channel_change_by_precac(
268  				pdev);
269  }
270  
dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev * pdev)271  void dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev *pdev)
272  {
273  	if (global_dfs_to_mlme.mlme_nol_timeout_notification)
274  		global_dfs_to_mlme.mlme_nol_timeout_notification(
275  				pdev);
276  }
277  
dfs_mlme_set_tx_flag(struct wlan_objmgr_pdev * pdev,bool is_tx_allowed)278  void dfs_mlme_set_tx_flag(struct wlan_objmgr_pdev *pdev, bool is_tx_allowed)
279  {
280  	if (global_dfs_to_mlme.mlme_set_tx_flag)
281  		global_dfs_to_mlme.mlme_set_tx_flag(pdev, is_tx_allowed);
282  }
283  
dfs_mlme_clist_update(struct wlan_objmgr_pdev * pdev,void * nollist,int nentries)284  void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev,
285  		void *nollist,
286  		int nentries)
287  {
288  	if (global_dfs_to_mlme.mlme_clist_update)
289  		global_dfs_to_mlme.mlme_clist_update(pdev,
290  				nollist,
291  				nentries);
292  }
293  
294  #ifdef CONFIG_CHAN_FREQ_API
dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t dfs_chan_freq,uint16_t dfs_cfreq2,uint64_t dfs_ch_flags)295  int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev,
296  				      uint16_t dfs_chan_freq,
297  				      uint16_t dfs_cfreq2,
298  				      uint64_t dfs_ch_flags)
299  {
300  	int cac_timeout = 0;
301  
302  	if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq)
303  		global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev,
304  								 dfs_chan_freq,
305  								 dfs_cfreq2,
306  								 dfs_ch_flags,
307  								 &cac_timeout);
308  
309  	return cac_timeout;
310  }
311  #endif
312  
313  #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
dfs_mlme_rebuild_chan_list_with_non_dfs_channels(struct wlan_objmgr_pdev * pdev)314  int dfs_mlme_rebuild_chan_list_with_non_dfs_channels(
315  		struct wlan_objmgr_pdev *pdev)
316  {
317  	if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels)
318  		return 1;
319  
320  	return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels(
321  			pdev);
322  }
323  
dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev * pdev,int no_chans_avail)324  void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev,
325  					     int no_chans_avail)
326  {
327  	if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan)
328  		return;
329  
330  	global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev,
331  							       no_chans_avail);
332  }
333  #endif
334  
335  #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN)
dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev * pdev,uint32_t chan_freq)336  bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev,
337  					  uint32_t chan_freq)
338  {
339  	if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist)
340  		return true;
341  
342  	return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev,
343  								   chan_freq);
344  }
345  
346  #endif
347  
348  #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev * pdev)349  void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
350  {
351  	bool dfs_enable = 0;
352  
353  	/*Disable all DFS channels in master channel list and ic channel list */
354  	ucfg_reg_enable_dfs_channels(pdev, dfs_enable);
355  
356  	/* send the updated channel list to FW */
357  	global_dfs_to_mlme.mlme_update_scan_channel_list(pdev);
358  }
359  #endif
360  
dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev * pdev)361  bool dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev *pdev)
362  {
363  	if (!global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed)
364  		return false;
365  
366  	return global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed(pdev);
367  }
368  
dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev * pdev)369  bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev)
370  {
371  	if (!global_dfs_to_mlme.mlme_is_opmode_sta)
372  		return false;
373  
374  	return global_dfs_to_mlme.mlme_is_opmode_sta(pdev);
375  }
376