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) 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_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 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 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) 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 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) 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) 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 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 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