1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 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) 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) 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 278 void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev, 279 void *nollist, 280 int nentries) 281 { 282 if (global_dfs_to_mlme.mlme_clist_update) 283 global_dfs_to_mlme.mlme_clist_update(pdev, 284 nollist, 285 nentries); 286 } 287 288 #ifdef CONFIG_CHAN_FREQ_API 289 int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev, 290 uint16_t dfs_chan_freq, 291 uint16_t dfs_cfreq2, 292 uint64_t dfs_ch_flags) 293 { 294 int cac_timeout = 0; 295 296 if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq) 297 global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev, 298 dfs_chan_freq, 299 dfs_cfreq2, 300 dfs_ch_flags, 301 &cac_timeout); 302 303 return cac_timeout; 304 } 305 #endif 306 307 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 308 int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( 309 struct wlan_objmgr_pdev *pdev) 310 { 311 if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels) 312 return 1; 313 314 return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels( 315 pdev); 316 } 317 318 void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, 319 int no_chans_avail) 320 { 321 if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan) 322 return; 323 324 global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev, 325 no_chans_avail); 326 } 327 #endif 328 329 #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN) 330 bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, 331 uint32_t chan_freq) 332 { 333 if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist) 334 return true; 335 336 return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev, 337 chan_freq); 338 } 339 340 #endif 341 342 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 343 void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) 344 { 345 bool dfs_enable = 0; 346 347 /*Disable all DFS channels in master channel list and ic channel list */ 348 ucfg_reg_enable_dfs_channels(pdev, dfs_enable); 349 350 /* send the updated channel list to FW */ 351 global_dfs_to_mlme.mlme_update_scan_channel_list(pdev); 352 } 353 #endif 354 355 bool dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev *pdev) 356 { 357 if (!global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed) 358 return false; 359 360 return global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed(pdev); 361 } 362 363 bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev) 364 { 365 if (!global_dfs_to_mlme.mlme_is_opmode_sta) 366 return false; 367 368 return global_dfs_to_mlme.mlme_is_opmode_sta(pdev); 369 } 370