1 /* 2 * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. 3 * 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: Functions to call mlme functions from DFS component. 22 */ 23 24 #include "wlan_dfs_mlme_api.h" 25 #include "wlan_objmgr_vdev_obj.h" 26 #include "wlan_objmgr_pdev_obj.h" 27 #include "../../core/src/dfs.h" 28 #include "scheduler_api.h" 29 #include <wlan_reg_ucfg_api.h> 30 #ifdef QCA_MCL_DFS_SUPPORT 31 #include "wni_api.h" 32 #endif 33 34 #if defined(QCA_DFS_RCSA_SUPPORT) 35 void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev, 36 bool *wait_for_csa) 37 { 38 if (global_dfs_to_mlme.dfs_start_rcsa) 39 global_dfs_to_mlme.dfs_start_rcsa(pdev, wait_for_csa); 40 } 41 #endif 42 43 #ifndef QCA_MCL_DFS_SUPPORT 44 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, 45 uint8_t ieee, 46 uint16_t freq, 47 uint16_t vhtop_ch_freq_seg2, 48 uint64_t flags) 49 { 50 if (global_dfs_to_mlme.mlme_mark_dfs) 51 global_dfs_to_mlme.mlme_mark_dfs(pdev, 52 ieee, 53 freq, 54 vhtop_ch_freq_seg2, 55 flags); 56 } 57 #else /* Else of ndef MCL_DFS_SUPPORT */ 58 static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev, 59 void *object, 60 void *arg) 61 { 62 struct scheduler_msg sme_msg = {0}; 63 uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object); 64 65 sme_msg.type = eWNI_SME_DFS_RADAR_FOUND; 66 sme_msg.bodyptr = NULL; 67 sme_msg.bodyval = vdev_id; 68 scheduler_post_message(QDF_MODULE_ID_DFS, 69 QDF_MODULE_ID_SME, 70 QDF_MODULE_ID_SME, &sme_msg); 71 dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted", 72 vdev_id); 73 } 74 75 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, 76 uint8_t ieee, 77 uint16_t freq, 78 uint16_t vhtop_ch_freq_seg2, 79 uint64_t flags) 80 { 81 struct wlan_objmgr_vdev *vdev; 82 83 if (!pdev) { 84 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 85 return; 86 } 87 88 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 89 90 if (vdev) { 91 dfs_send_radar_ind(pdev, vdev, NULL); 92 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 93 } 94 } 95 #endif 96 97 #ifndef QCA_MCL_DFS_SUPPORT 98 #ifdef CONFIG_CHAN_NUM_API 99 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, 100 uint8_t ieee_chan, uint16_t freq, 101 uint8_t cfreq2, uint64_t flags) 102 { 103 if (global_dfs_to_mlme.mlme_start_csa) 104 global_dfs_to_mlme.mlme_start_csa(pdev, ieee_chan, freq, cfreq2, 105 flags); 106 } 107 #endif 108 #ifdef CONFIG_CHAN_FREQ_API 109 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, 110 uint8_t ieee_chan, uint16_t freq, 111 uint16_t cfreq2, uint64_t flags) 112 { 113 if (global_dfs_to_mlme.mlme_start_csa_for_freq) 114 global_dfs_to_mlme.mlme_start_csa_for_freq(pdev, ieee_chan, 115 freq, cfreq2, flags); 116 } 117 #endif 118 #else 119 #ifdef CONFIG_CHAN_NUM_API 120 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, 121 uint8_t ieee_chan, uint16_t freq, 122 uint8_t cfreq2, uint64_t flags) 123 { 124 struct wlan_objmgr_vdev *vdev; 125 126 if (!pdev) { 127 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 128 return; 129 } 130 131 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 132 133 if (vdev) { 134 dfs_send_radar_ind(pdev, vdev, NULL); 135 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 136 } 137 } 138 #endif 139 #ifdef CONFIG_CHAN_FREQ_API 140 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, 141 uint8_t ieee_chan, uint16_t freq, 142 uint16_t cfreq2, uint64_t flags) 143 { 144 struct wlan_objmgr_vdev *vdev; 145 146 if (!pdev) { 147 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 148 return; 149 } 150 151 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 152 153 if (vdev) { 154 dfs_send_radar_ind(pdev, vdev, NULL); 155 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 156 } 157 } 158 #endif 159 #endif 160 161 #ifndef QCA_MCL_DFS_SUPPORT 162 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 163 { 164 if (global_dfs_to_mlme.mlme_proc_cac) 165 global_dfs_to_mlme.mlme_proc_cac(pdev); 166 } 167 #else 168 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 169 { 170 struct scheduler_msg sme_msg = {0}; 171 172 sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE; 173 sme_msg.bodyptr = NULL; 174 sme_msg.bodyval = vdev_id; 175 scheduler_post_message(QDF_MODULE_ID_DFS, 176 QDF_MODULE_ID_SME, 177 QDF_MODULE_ID_SME, &sme_msg); 178 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_CAC_COMPLETE vdev%d posted", 179 vdev_id); 180 } 181 #endif 182 183 void dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev *pdev) 184 { 185 if (global_dfs_to_mlme.mlme_deliver_event_up_after_cac) 186 global_dfs_to_mlme.mlme_deliver_event_up_after_cac( 187 pdev); 188 } 189 190 void dfs_mlme_get_dfs_ch_nchans(struct wlan_objmgr_pdev *pdev, 191 int *nchans) 192 { 193 if (global_dfs_to_mlme.mlme_get_dfs_ch_nchans) 194 global_dfs_to_mlme.mlme_get_dfs_ch_nchans(pdev, 195 nchans); 196 } 197 198 #ifdef CONFIG_CHAN_NUM_API 199 QDF_STATUS dfs_mlme_get_extchan(struct wlan_objmgr_pdev *pdev, 200 uint16_t *dfs_ch_freq, 201 uint64_t *dfs_ch_flags, 202 uint16_t *dfs_ch_flagext, 203 uint8_t *dfs_ch_ieee, 204 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 205 uint8_t *dfs_ch_vhtop_ch_freq_seg2) 206 { 207 if (global_dfs_to_mlme.mlme_get_extchan) 208 return global_dfs_to_mlme.mlme_get_extchan(pdev, 209 dfs_ch_freq, 210 dfs_ch_flags, 211 dfs_ch_flagext, 212 dfs_ch_ieee, 213 dfs_ch_vhtop_ch_freq_seg1, 214 dfs_ch_vhtop_ch_freq_seg2); 215 216 return QDF_STATUS_E_FAILURE; 217 } 218 #endif 219 220 #ifdef CONFIG_CHAN_FREQ_API 221 QDF_STATUS dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev *pdev, 222 uint16_t *dfs_chan_freq, 223 uint64_t *dfs_chan_flags, 224 uint16_t *dfs_chan_flagext, 225 uint8_t *dfs_chan_ieee, 226 uint8_t *dfs_chan_vhtop_ch_freq_seg1, 227 uint8_t *dfs_chan_vhtop_ch_freq_seg2, 228 uint16_t *dfs_chan_mhz_freq_seg1, 229 uint16_t *dfs_chan_mhz_freq_seg2) 230 { 231 if (global_dfs_to_mlme.mlme_get_extchan_for_freq) 232 return global_dfs_to_mlme.mlme_get_extchan_for_freq(pdev, 233 dfs_chan_freq, 234 dfs_chan_flags, 235 dfs_chan_flagext, 236 dfs_chan_ieee, 237 dfs_chan_vhtop_ch_freq_seg1, 238 dfs_chan_vhtop_ch_freq_seg2, 239 dfs_chan_mhz_freq_seg1, 240 dfs_chan_mhz_freq_seg2); 241 242 return QDF_STATUS_E_FAILURE; 243 } 244 #endif 245 246 void dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev *pdev, 247 int val) 248 { 249 if (global_dfs_to_mlme.mlme_set_no_chans_available) 250 global_dfs_to_mlme.mlme_set_no_chans_available( 251 pdev, 252 val); 253 } 254 255 int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag) 256 { 257 int freq = 0; 258 259 if (global_dfs_to_mlme.mlme_ieee2mhz) 260 global_dfs_to_mlme.mlme_ieee2mhz(pdev, 261 ieee, 262 flag, 263 &freq); 264 265 return freq; 266 } 267 268 #ifdef CONFIG_CHAN_NUM_API 269 QDF_STATUS 270 dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev, 271 uint8_t ieee, 272 uint8_t des_cfreq2, 273 int mode, 274 uint16_t *dfs_ch_freq, 275 uint64_t *dfs_ch_flags, 276 uint16_t *dfs_ch_flagext, 277 uint8_t *dfs_ch_ieee, 278 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 279 uint8_t *dfs_ch_vhtop_ch_freq_seg2) 280 { 281 if (global_dfs_to_mlme.mlme_find_dot11_channel) 282 return global_dfs_to_mlme.mlme_find_dot11_channel(pdev, 283 ieee, 284 des_cfreq2, 285 mode, 286 dfs_ch_freq, 287 dfs_ch_flags, 288 dfs_ch_flagext, 289 dfs_ch_ieee, 290 dfs_ch_vhtop_ch_freq_seg1, 291 dfs_ch_vhtop_ch_freq_seg2); 292 return QDF_STATUS_E_FAILURE; 293 } 294 #endif 295 296 #ifdef CONFIG_CHAN_FREQ_API 297 QDF_STATUS 298 dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev *pdev, 299 uint16_t freq, 300 uint16_t des_cfreq2, 301 int mode, 302 uint16_t *dfs_chan_freq, 303 uint64_t *dfs_chan_flag, 304 uint16_t *dfs_flagext, 305 uint8_t *dfs_chan_ieee, 306 uint8_t *dfs_cfreq1, 307 uint8_t *dfs_cfreq2, 308 uint16_t *cfreq1_mhz, 309 uint16_t *cfreq2_mhz) 310 { 311 if (global_dfs_to_mlme.mlme_find_dot11_chan_for_freq) 312 return global_dfs_to_mlme.mlme_find_dot11_chan_for_freq(pdev, 313 freq, 314 des_cfreq2, 315 mode, 316 dfs_chan_freq, 317 dfs_chan_flag, 318 dfs_flagext, 319 dfs_chan_ieee, 320 dfs_cfreq1, 321 dfs_cfreq2, 322 cfreq1_mhz, 323 cfreq2_mhz); 324 return QDF_STATUS_E_FAILURE; 325 } 326 #endif 327 328 #ifdef CONFIG_CHAN_NUM_API 329 void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev, 330 uint16_t *dfs_ch_freq, 331 uint64_t *dfs_ch_flags, 332 uint16_t *dfs_ch_flagext, 333 uint8_t *dfs_ch_ieee, 334 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 335 uint8_t *dfs_ch_vhtop_ch_freq_seg2, 336 int index) 337 { 338 if (global_dfs_to_mlme.mlme_get_dfs_ch_channels) 339 global_dfs_to_mlme.mlme_get_dfs_ch_channels(pdev, 340 dfs_ch_freq, 341 dfs_ch_flags, 342 dfs_ch_flagext, 343 dfs_ch_ieee, 344 dfs_ch_vhtop_ch_freq_seg1, 345 dfs_ch_vhtop_ch_freq_seg2, 346 index); 347 } 348 #endif 349 350 #ifdef CONFIG_CHAN_FREQ_API 351 void dfs_mlme_get_dfs_channels_for_freq(struct wlan_objmgr_pdev *pdev, 352 uint16_t *dfs_chan_freq, 353 uint64_t *dfs_chan_flags, 354 uint16_t *dfs_chan_flagext, 355 uint8_t *dfs_chan_ieee, 356 uint8_t *dfs_chan_vhtop_freq_seg1, 357 uint8_t *dfs_chan_vhtop_freq_seg2, 358 uint16_t *dfs_ch_mhz_freq_seg1, 359 uint16_t *dfs_ch_mhz_freq_seg2, 360 int index) 361 { 362 if (global_dfs_to_mlme.mlme_get_dfs_channels_for_freq) 363 global_dfs_to_mlme.mlme_get_dfs_channels_for_freq(pdev, 364 dfs_chan_freq, 365 dfs_chan_flags, 366 dfs_chan_flagext, 367 dfs_chan_ieee, 368 dfs_chan_vhtop_freq_seg1, 369 dfs_chan_vhtop_freq_seg2, 370 dfs_ch_mhz_freq_seg1, 371 dfs_ch_mhz_freq_seg2, 372 index); 373 } 374 #endif 375 376 uint32_t dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev *pdev) 377 { 378 uint16_t flag_ext = 0; 379 380 if (global_dfs_to_mlme.mlme_dfs_ch_flags_ext) 381 global_dfs_to_mlme.mlme_dfs_ch_flags_ext(pdev, 382 &flag_ext); 383 384 return flag_ext; 385 } 386 387 void dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev *pdev) 388 { 389 if (global_dfs_to_mlme.mlme_channel_change_by_precac) 390 global_dfs_to_mlme.mlme_channel_change_by_precac( 391 pdev); 392 } 393 394 void dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev *pdev) 395 { 396 if (global_dfs_to_mlme.mlme_nol_timeout_notification) 397 global_dfs_to_mlme.mlme_nol_timeout_notification( 398 pdev); 399 } 400 401 void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev, 402 void *nollist, 403 int nentries) 404 { 405 if (global_dfs_to_mlme.mlme_clist_update) 406 global_dfs_to_mlme.mlme_clist_update(pdev, 407 nollist, 408 nentries); 409 } 410 411 #ifdef CONFIG_CHAN_NUM_API 412 int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev, 413 uint16_t dfs_ch_freq, 414 uint8_t dfs_ch_vhtop_ch_freq_seg2, 415 uint64_t dfs_ch_flags) 416 { 417 int cac_timeout = 0; 418 419 if (global_dfs_to_mlme.mlme_get_cac_timeout) 420 global_dfs_to_mlme.mlme_get_cac_timeout(pdev, 421 dfs_ch_freq, 422 dfs_ch_vhtop_ch_freq_seg2, 423 dfs_ch_flags, 424 &cac_timeout); 425 426 return cac_timeout; 427 } 428 #endif 429 430 #ifdef CONFIG_CHAN_FREQ_API 431 int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev, 432 uint16_t dfs_chan_freq, 433 uint16_t dfs_cfreq2, 434 uint64_t dfs_ch_flags) 435 { 436 int cac_timeout = 0; 437 438 if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq) 439 global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev, 440 dfs_chan_freq, 441 dfs_cfreq2, 442 dfs_ch_flags, 443 &cac_timeout); 444 445 return cac_timeout; 446 } 447 #endif 448 449 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 450 int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( 451 struct wlan_objmgr_pdev *pdev) 452 { 453 if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels) 454 return 1; 455 456 return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels( 457 pdev); 458 } 459 460 void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, 461 int no_chans_avail) 462 { 463 if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan) 464 return; 465 466 global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev, 467 no_chans_avail); 468 } 469 #endif 470 471 #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN) 472 bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, 473 uint32_t chan_freq) 474 { 475 if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist) 476 return true; 477 478 return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev, 479 chan_freq); 480 } 481 482 #endif 483 484 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 485 void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) 486 { 487 bool dfs_enable = 0; 488 489 /*Disable all DFS channels in master channel list and ic channel list */ 490 ucfg_reg_enable_dfs_channels(pdev, dfs_enable); 491 492 /* send the updated channel list to FW */ 493 global_dfs_to_mlme.mlme_update_scan_channel_list(pdev); 494 } 495 #endif 496 497 bool dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev *pdev) 498 { 499 if (!global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed) 500 return false; 501 502 return global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed(pdev); 503 } 504 505 bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev) 506 { 507 if (!global_dfs_to_mlme.mlme_is_opmode_sta) 508 return false; 509 510 return global_dfs_to_mlme.mlme_is_opmode_sta(pdev); 511 } 512 513 void dfs_mlme_acquire_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev) 514 { 515 if (!global_dfs_to_mlme.mlme_acquire_radar_mode_switch_lock) 516 return; 517 518 global_dfs_to_mlme.mlme_acquire_radar_mode_switch_lock(pdev); 519 } 520 521 void dfs_mlme_release_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev) 522 { 523 if (!global_dfs_to_mlme.mlme_release_radar_mode_switch_lock) 524 return; 525 526 global_dfs_to_mlme.mlme_release_radar_mode_switch_lock(pdev); 527 } 528