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 #ifdef CONFIG_CHAN_NUM_API 45 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, 46 uint8_t ieee, 47 uint16_t freq, 48 uint8_t vhtop_ch_freq_seg2, 49 uint64_t flags) 50 { 51 if (global_dfs_to_mlme.mlme_mark_dfs) 52 global_dfs_to_mlme.mlme_mark_dfs(pdev, 53 ieee, 54 freq, 55 vhtop_ch_freq_seg2, 56 flags); 57 } 58 #endif 59 #ifdef CONFIG_CHAN_FREQ_API 60 void dfs_mlme_mark_dfs_for_freq(struct wlan_objmgr_pdev *pdev, 61 uint8_t ieee, 62 uint16_t freq, 63 uint16_t vhtop_ch_freq_seg2, 64 uint64_t flags) 65 { 66 if (global_dfs_to_mlme.mlme_mark_dfs_for_freq) 67 global_dfs_to_mlme.mlme_mark_dfs_for_freq(pdev, 68 ieee, 69 freq, 70 vhtop_ch_freq_seg2, 71 flags); 72 } 73 #endif 74 #else /* Else of ndef MCL_DFS_SUPPORT */ 75 static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev, 76 void *object, 77 void *arg) 78 { 79 struct scheduler_msg sme_msg = {0}; 80 uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object); 81 82 sme_msg.type = eWNI_SME_DFS_RADAR_FOUND; 83 sme_msg.bodyptr = NULL; 84 sme_msg.bodyval = vdev_id; 85 scheduler_post_message(QDF_MODULE_ID_DFS, 86 QDF_MODULE_ID_SME, 87 QDF_MODULE_ID_SME, &sme_msg); 88 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted", 89 vdev_id); 90 } 91 92 #ifdef CONFIG_CHAN_NUM_API 93 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, 94 uint8_t ieee, 95 uint16_t freq, 96 uint8_t vhtop_ch_freq_seg2, 97 uint64_t flags) 98 { 99 struct wlan_objmgr_vdev *vdev; 100 101 if (!pdev) { 102 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 103 return; 104 } 105 106 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 107 108 if (vdev) { 109 dfs_send_radar_ind(pdev, vdev, NULL); 110 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 111 } 112 } 113 #endif 114 115 #ifdef CONFIG_CHAN_FREQ_API 116 void dfs_mlme_mark_dfs_for_freq(struct wlan_objmgr_pdev *pdev, 117 uint8_t ieee, 118 uint16_t freq, 119 uint16_t vhtop_ch_freq_seg2, 120 uint64_t flags) 121 { 122 struct wlan_objmgr_vdev *vdev; 123 124 if (!pdev) { 125 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 126 return; 127 } 128 129 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 130 131 if (vdev) { 132 dfs_send_radar_ind(pdev, vdev, NULL); 133 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 134 } 135 } 136 #endif 137 #endif 138 139 #ifndef QCA_MCL_DFS_SUPPORT 140 #ifdef CONFIG_CHAN_NUM_API 141 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, 142 uint8_t ieee_chan, uint16_t freq, 143 uint8_t cfreq2, uint64_t flags) 144 { 145 if (global_dfs_to_mlme.mlme_start_csa) 146 global_dfs_to_mlme.mlme_start_csa(pdev, ieee_chan, freq, cfreq2, 147 flags); 148 } 149 #endif 150 #ifdef CONFIG_CHAN_FREQ_API 151 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, 152 uint8_t ieee_chan, uint16_t freq, 153 uint16_t cfreq2, uint64_t flags) 154 { 155 if (global_dfs_to_mlme.mlme_start_csa_for_freq) 156 global_dfs_to_mlme.mlme_start_csa_for_freq(pdev, ieee_chan, 157 freq, cfreq2, flags); 158 } 159 #endif 160 #else 161 #ifdef CONFIG_CHAN_NUM_API 162 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, 163 uint8_t ieee_chan, uint16_t freq, 164 uint8_t cfreq2, uint64_t flags) 165 { 166 struct wlan_objmgr_vdev *vdev; 167 168 if (!pdev) { 169 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 170 return; 171 } 172 173 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 174 175 if (vdev) { 176 dfs_send_radar_ind(pdev, vdev, NULL); 177 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 178 } 179 } 180 #endif 181 #ifdef CONFIG_CHAN_FREQ_API 182 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, 183 uint8_t ieee_chan, uint16_t freq, 184 uint16_t cfreq2, uint64_t flags) 185 { 186 struct wlan_objmgr_vdev *vdev; 187 188 if (!pdev) { 189 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 190 return; 191 } 192 193 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 194 195 if (vdev) { 196 dfs_send_radar_ind(pdev, vdev, NULL); 197 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 198 } 199 } 200 #endif 201 #endif 202 203 #ifndef QCA_MCL_DFS_SUPPORT 204 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 205 { 206 if (global_dfs_to_mlme.mlme_proc_cac) 207 global_dfs_to_mlme.mlme_proc_cac(pdev); 208 } 209 #else 210 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 211 { 212 struct scheduler_msg sme_msg = {0}; 213 214 sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE; 215 sme_msg.bodyptr = NULL; 216 sme_msg.bodyval = vdev_id; 217 scheduler_post_message(QDF_MODULE_ID_DFS, 218 QDF_MODULE_ID_SME, 219 QDF_MODULE_ID_SME, &sme_msg); 220 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_CAC_COMPLETE vdev%d posted", 221 vdev_id); 222 } 223 #endif 224 225 void dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev *pdev) 226 { 227 if (global_dfs_to_mlme.mlme_deliver_event_up_after_cac) 228 global_dfs_to_mlme.mlme_deliver_event_up_after_cac( 229 pdev); 230 } 231 232 void dfs_mlme_get_dfs_ch_nchans(struct wlan_objmgr_pdev *pdev, 233 int *nchans) 234 { 235 if (global_dfs_to_mlme.mlme_get_dfs_ch_nchans) 236 global_dfs_to_mlme.mlme_get_dfs_ch_nchans(pdev, 237 nchans); 238 } 239 240 #ifdef CONFIG_CHAN_NUM_API 241 QDF_STATUS dfs_mlme_get_extchan(struct wlan_objmgr_pdev *pdev, 242 uint16_t *dfs_ch_freq, 243 uint64_t *dfs_ch_flags, 244 uint16_t *dfs_ch_flagext, 245 uint8_t *dfs_ch_ieee, 246 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 247 uint8_t *dfs_ch_vhtop_ch_freq_seg2) 248 { 249 if (global_dfs_to_mlme.mlme_get_extchan) 250 return global_dfs_to_mlme.mlme_get_extchan(pdev, 251 dfs_ch_freq, 252 dfs_ch_flags, 253 dfs_ch_flagext, 254 dfs_ch_ieee, 255 dfs_ch_vhtop_ch_freq_seg1, 256 dfs_ch_vhtop_ch_freq_seg2); 257 258 return QDF_STATUS_E_FAILURE; 259 } 260 #endif 261 262 #ifdef CONFIG_CHAN_FREQ_API 263 QDF_STATUS dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev *pdev, 264 uint16_t *dfs_chan_freq, 265 uint64_t *dfs_chan_flags, 266 uint16_t *dfs_chan_flagext, 267 uint8_t *dfs_chan_ieee, 268 uint8_t *dfs_chan_vhtop_ch_freq_seg1, 269 uint8_t *dfs_chan_vhtop_ch_freq_seg2, 270 uint16_t *dfs_chan_mhz_freq_seg1, 271 uint16_t *dfs_chan_mhz_freq_seg2) 272 { 273 if (global_dfs_to_mlme.mlme_get_extchan_for_freq) 274 return global_dfs_to_mlme.mlme_get_extchan_for_freq(pdev, 275 dfs_chan_freq, 276 dfs_chan_flags, 277 dfs_chan_flagext, 278 dfs_chan_ieee, 279 dfs_chan_vhtop_ch_freq_seg1, 280 dfs_chan_vhtop_ch_freq_seg2, 281 dfs_chan_mhz_freq_seg1, 282 dfs_chan_mhz_freq_seg2); 283 284 return QDF_STATUS_E_FAILURE; 285 } 286 #endif 287 288 void dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev *pdev, 289 int val) 290 { 291 if (global_dfs_to_mlme.mlme_set_no_chans_available) 292 global_dfs_to_mlme.mlme_set_no_chans_available( 293 pdev, 294 val); 295 } 296 297 int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag) 298 { 299 int freq = 0; 300 301 if (global_dfs_to_mlme.mlme_ieee2mhz) 302 global_dfs_to_mlme.mlme_ieee2mhz(pdev, 303 ieee, 304 flag, 305 &freq); 306 307 return freq; 308 } 309 310 #ifdef CONFIG_CHAN_NUM_API 311 QDF_STATUS 312 dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev, 313 uint8_t ieee, 314 uint8_t des_cfreq2, 315 int mode, 316 uint16_t *dfs_ch_freq, 317 uint64_t *dfs_ch_flags, 318 uint16_t *dfs_ch_flagext, 319 uint8_t *dfs_ch_ieee, 320 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 321 uint8_t *dfs_ch_vhtop_ch_freq_seg2) 322 { 323 if (global_dfs_to_mlme.mlme_find_dot11_channel) 324 return global_dfs_to_mlme.mlme_find_dot11_channel(pdev, 325 ieee, 326 des_cfreq2, 327 mode, 328 dfs_ch_freq, 329 dfs_ch_flags, 330 dfs_ch_flagext, 331 dfs_ch_ieee, 332 dfs_ch_vhtop_ch_freq_seg1, 333 dfs_ch_vhtop_ch_freq_seg2); 334 return QDF_STATUS_E_FAILURE; 335 } 336 #endif 337 338 #ifdef CONFIG_CHAN_FREQ_API 339 QDF_STATUS 340 dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev *pdev, 341 uint16_t freq, 342 uint16_t des_cfreq2, 343 int mode, 344 uint16_t *dfs_chan_freq, 345 uint64_t *dfs_chan_flag, 346 uint16_t *dfs_flagext, 347 uint8_t *dfs_chan_ieee, 348 uint8_t *dfs_cfreq1, 349 uint8_t *dfs_cfreq2, 350 uint16_t *cfreq1_mhz, 351 uint16_t *cfreq2_mhz) 352 { 353 if (global_dfs_to_mlme.mlme_find_dot11_chan_for_freq) 354 return global_dfs_to_mlme.mlme_find_dot11_chan_for_freq(pdev, 355 freq, 356 des_cfreq2, 357 mode, 358 dfs_chan_freq, 359 dfs_chan_flag, 360 dfs_flagext, 361 dfs_chan_ieee, 362 dfs_cfreq1, 363 dfs_cfreq2, 364 cfreq1_mhz, 365 cfreq2_mhz); 366 return QDF_STATUS_E_FAILURE; 367 } 368 #endif 369 370 #ifdef CONFIG_CHAN_NUM_API 371 void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev, 372 uint16_t *dfs_ch_freq, 373 uint64_t *dfs_ch_flags, 374 uint16_t *dfs_ch_flagext, 375 uint8_t *dfs_ch_ieee, 376 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 377 uint8_t *dfs_ch_vhtop_ch_freq_seg2, 378 int index) 379 { 380 if (global_dfs_to_mlme.mlme_get_dfs_ch_channels) 381 global_dfs_to_mlme.mlme_get_dfs_ch_channels(pdev, 382 dfs_ch_freq, 383 dfs_ch_flags, 384 dfs_ch_flagext, 385 dfs_ch_ieee, 386 dfs_ch_vhtop_ch_freq_seg1, 387 dfs_ch_vhtop_ch_freq_seg2, 388 index); 389 } 390 #endif 391 392 #ifdef CONFIG_CHAN_FREQ_API 393 void dfs_mlme_get_dfs_channels_for_freq(struct wlan_objmgr_pdev *pdev, 394 uint16_t *dfs_chan_freq, 395 uint64_t *dfs_chan_flags, 396 uint16_t *dfs_chan_flagext, 397 uint8_t *dfs_chan_ieee, 398 uint8_t *dfs_chan_vhtop_freq_seg1, 399 uint8_t *dfs_chan_vhtop_freq_seg2, 400 uint16_t *dfs_ch_mhz_freq_seg1, 401 uint16_t *dfs_ch_mhz_freq_seg2, 402 int index) 403 { 404 if (global_dfs_to_mlme.mlme_get_dfs_channels_for_freq) 405 global_dfs_to_mlme.mlme_get_dfs_channels_for_freq(pdev, 406 dfs_chan_freq, 407 dfs_chan_flags, 408 dfs_chan_flagext, 409 dfs_chan_ieee, 410 dfs_chan_vhtop_freq_seg1, 411 dfs_chan_vhtop_freq_seg2, 412 dfs_ch_mhz_freq_seg1, 413 dfs_ch_mhz_freq_seg2, 414 index); 415 } 416 #endif 417 418 uint32_t dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev *pdev) 419 { 420 uint16_t flag_ext = 0; 421 422 if (global_dfs_to_mlme.mlme_dfs_ch_flags_ext) 423 global_dfs_to_mlme.mlme_dfs_ch_flags_ext(pdev, 424 &flag_ext); 425 426 return flag_ext; 427 } 428 429 void dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev *pdev) 430 { 431 if (global_dfs_to_mlme.mlme_channel_change_by_precac) 432 global_dfs_to_mlme.mlme_channel_change_by_precac( 433 pdev); 434 } 435 436 void dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev *pdev) 437 { 438 if (global_dfs_to_mlme.mlme_nol_timeout_notification) 439 global_dfs_to_mlme.mlme_nol_timeout_notification( 440 pdev); 441 } 442 443 void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev, 444 void *nollist, 445 int nentries) 446 { 447 if (global_dfs_to_mlme.mlme_clist_update) 448 global_dfs_to_mlme.mlme_clist_update(pdev, 449 nollist, 450 nentries); 451 } 452 453 #ifdef CONFIG_CHAN_NUM_API 454 int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev, 455 uint16_t dfs_ch_freq, 456 uint8_t dfs_ch_vhtop_ch_freq_seg2, 457 uint64_t dfs_ch_flags) 458 { 459 int cac_timeout = 0; 460 461 if (global_dfs_to_mlme.mlme_get_cac_timeout) 462 global_dfs_to_mlme.mlme_get_cac_timeout(pdev, 463 dfs_ch_freq, 464 dfs_ch_vhtop_ch_freq_seg2, 465 dfs_ch_flags, 466 &cac_timeout); 467 468 return cac_timeout; 469 } 470 #endif 471 472 #ifdef CONFIG_CHAN_FREQ_API 473 int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev, 474 uint16_t dfs_chan_freq, 475 uint16_t dfs_cfreq2, 476 uint64_t dfs_ch_flags) 477 { 478 int cac_timeout = 0; 479 480 if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq) 481 global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev, 482 dfs_chan_freq, 483 dfs_cfreq2, 484 dfs_ch_flags, 485 &cac_timeout); 486 487 return cac_timeout; 488 } 489 #endif 490 491 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 492 int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( 493 struct wlan_objmgr_pdev *pdev) 494 { 495 if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels) 496 return 1; 497 498 return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels( 499 pdev); 500 } 501 502 void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, 503 int no_chans_avail) 504 { 505 if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan) 506 return; 507 508 global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev, 509 no_chans_avail); 510 } 511 #endif 512 513 #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN) 514 bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, 515 uint32_t chan_freq) 516 { 517 if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist) 518 return true; 519 520 return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev, 521 chan_freq); 522 } 523 524 #endif 525 526 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 527 void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) 528 { 529 bool dfs_enable = 0; 530 531 /*Disable all DFS channels in master channel list and ic channel list */ 532 ucfg_reg_enable_dfs_channels(pdev, dfs_enable); 533 534 /* send the updated channel list to FW */ 535 global_dfs_to_mlme.mlme_update_scan_channel_list(pdev); 536 } 537 #endif 538 539 bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev) 540 { 541 if (!global_dfs_to_mlme.mlme_is_opmode_sta) 542 return false; 543 544 return global_dfs_to_mlme.mlme_is_opmode_sta(pdev); 545 } 546 547 void dfs_mlme_acquire_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev) 548 { 549 if (!global_dfs_to_mlme.mlme_acquire_radar_mode_switch_lock) 550 return; 551 552 global_dfs_to_mlme.mlme_acquire_radar_mode_switch_lock(pdev); 553 } 554 555 void dfs_mlme_release_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev) 556 { 557 if (!global_dfs_to_mlme.mlme_release_radar_mode_switch_lock) 558 return; 559 560 global_dfs_to_mlme.mlme_release_radar_mode_switch_lock(pdev); 561 } 562