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: This file has the DFS dispatcher API implementation which is exposed 23 * to outside of DFS component. 24 */ 25 26 #include "wlan_dfs_ucfg_api.h" 27 #include "wlan_dfs_init_deinit_api.h" 28 #include "../../core/src/dfs.h" 29 #include "../../core/src/dfs_zero_cac.h" 30 #include "../../core/src/dfs_partial_offload_radar.h" 31 #include "../../core/src/dfs_process_radar_found_ind.h" 32 #include <qdf_module.h> 33 34 QDF_STATUS ucfg_dfs_is_ap_cac_timer_running(struct wlan_objmgr_pdev *pdev, 35 int *is_ap_cac_timer_running) 36 { 37 struct wlan_dfs *dfs; 38 39 dfs = wlan_pdev_get_dfs_obj(pdev); 40 if (!dfs) 41 return QDF_STATUS_E_FAILURE; 42 43 *is_ap_cac_timer_running = dfs_is_ap_cac_timer_running(dfs); 44 45 return QDF_STATUS_SUCCESS; 46 } 47 qdf_export_symbol(ucfg_dfs_is_ap_cac_timer_running); 48 49 QDF_STATUS ucfg_dfs_getnol(struct wlan_objmgr_pdev *pdev, 50 void *dfs_nolinfo) 51 { 52 struct wlan_dfs *dfs; 53 54 dfs = wlan_pdev_get_dfs_obj(pdev); 55 if (!dfs) 56 return QDF_STATUS_E_FAILURE; 57 58 dfs_getnol(dfs, dfs_nolinfo); 59 60 return QDF_STATUS_SUCCESS; 61 } 62 qdf_export_symbol(ucfg_dfs_getnol); 63 64 QDF_STATUS ucfg_dfs_override_cac_timeout(struct wlan_objmgr_pdev *pdev, 65 int cac_timeout, 66 int *status) 67 { 68 struct wlan_dfs *dfs; 69 70 dfs = wlan_pdev_get_dfs_obj(pdev); 71 if (!dfs) 72 return QDF_STATUS_E_FAILURE; 73 74 *status = dfs_override_cac_timeout(dfs, cac_timeout); 75 76 return QDF_STATUS_SUCCESS; 77 } 78 qdf_export_symbol(ucfg_dfs_override_cac_timeout); 79 80 QDF_STATUS ucfg_dfs_get_override_cac_timeout(struct wlan_objmgr_pdev *pdev, 81 int *cac_timeout, 82 int *status) 83 { 84 struct wlan_dfs *dfs; 85 86 dfs = wlan_pdev_get_dfs_obj(pdev); 87 if (!dfs) 88 return QDF_STATUS_E_FAILURE; 89 90 *status = dfs_get_override_cac_timeout(dfs, cac_timeout); 91 92 return QDF_STATUS_SUCCESS; 93 } 94 qdf_export_symbol(ucfg_dfs_get_override_cac_timeout); 95 96 QDF_STATUS ucfg_dfs_get_override_precac_timeout(struct wlan_objmgr_pdev *pdev, 97 int *precac_timeout) 98 { 99 struct wlan_dfs *dfs; 100 101 dfs = wlan_pdev_get_dfs_obj(pdev); 102 if (!dfs) 103 return QDF_STATUS_E_FAILURE; 104 105 dfs_get_override_precac_timeout(dfs, precac_timeout); 106 107 return QDF_STATUS_SUCCESS; 108 } 109 qdf_export_symbol(ucfg_dfs_get_override_precac_timeout); 110 111 QDF_STATUS ucfg_dfs_override_precac_timeout(struct wlan_objmgr_pdev *pdev, 112 int precac_timeout) 113 { 114 struct wlan_dfs *dfs; 115 116 dfs = wlan_pdev_get_dfs_obj(pdev); 117 if (!dfs) 118 return QDF_STATUS_E_FAILURE; 119 120 dfs_override_precac_timeout(dfs, precac_timeout); 121 122 return QDF_STATUS_SUCCESS; 123 } 124 qdf_export_symbol(ucfg_dfs_override_precac_timeout); 125 126 QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev, 127 uint32_t value) 128 { 129 struct wlan_dfs *dfs; 130 131 dfs = wlan_pdev_get_dfs_obj(pdev); 132 if (!dfs) { 133 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 134 return QDF_STATUS_E_FAILURE; 135 } 136 137 dfs_set_precac_enable(dfs, value); 138 139 return QDF_STATUS_SUCCESS; 140 } 141 qdf_export_symbol(ucfg_dfs_set_precac_enable); 142 143 QDF_STATUS ucfg_dfs_get_agile_precac_enable(struct wlan_objmgr_pdev *pdev, 144 bool *buff) 145 { 146 struct wlan_dfs *dfs; 147 148 if (!pdev || !buff) 149 return QDF_STATUS_E_FAILURE; 150 151 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) { 152 *buff = false; 153 return QDF_STATUS_SUCCESS; 154 } 155 156 dfs = wlan_pdev_get_dfs_obj(pdev); 157 if (!dfs) { 158 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 159 *buff = false; 160 return QDF_STATUS_SUCCESS; 161 } 162 163 *buff = dfs_is_agile_precac_enabled(dfs); 164 165 return QDF_STATUS_SUCCESS; 166 } 167 168 qdf_export_symbol(ucfg_dfs_get_agile_precac_enable); 169 170 QDF_STATUS 171 ucfg_dfs_set_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev, 172 bool nol_subchannel_marking) 173 { 174 struct wlan_dfs *dfs; 175 176 dfs = wlan_pdev_get_dfs_obj(pdev); 177 if (!dfs) 178 return QDF_STATUS_E_FAILURE; 179 180 dfs_set_nol_subchannel_marking(dfs, nol_subchannel_marking); 181 182 return QDF_STATUS_SUCCESS; 183 } 184 qdf_export_symbol(ucfg_dfs_set_nol_subchannel_marking); 185 186 QDF_STATUS ucfg_dfs_get_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev, 187 bool *nol_subchannel_marking) 188 { 189 struct wlan_dfs *dfs; 190 191 dfs = wlan_pdev_get_dfs_obj(pdev); 192 if (!dfs) 193 return QDF_STATUS_E_FAILURE; 194 195 dfs_get_nol_subchannel_marking(dfs, nol_subchannel_marking); 196 197 return QDF_STATUS_SUCCESS; 198 } 199 qdf_export_symbol(ucfg_dfs_get_nol_subchannel_marking); 200 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT 201 QDF_STATUS ucfg_dfs_set_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev, 202 uint32_t value) 203 { 204 struct wlan_dfs *dfs; 205 206 dfs = wlan_pdev_get_dfs_obj(pdev); 207 if (!dfs) { 208 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 209 return QDF_STATUS_E_FAILURE; 210 } 211 212 dfs_set_precac_intermediate_chan(dfs, value); 213 214 return QDF_STATUS_SUCCESS; 215 } 216 217 QDF_STATUS ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev, 218 int *buff) 219 { 220 struct wlan_dfs *dfs; 221 222 dfs = wlan_pdev_get_dfs_obj(pdev); 223 if (!dfs) { 224 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 225 return QDF_STATUS_E_FAILURE; 226 } 227 228 *buff = dfs_get_precac_intermediate_chan(dfs); 229 230 return QDF_STATUS_SUCCESS; 231 } 232 233 #ifdef CONFIG_CHAN_FREQ_API 234 enum precac_chan_state 235 ucfg_dfs_get_precac_chan_state_for_freq(struct wlan_objmgr_pdev *pdev, 236 uint16_t precac_chan_freq) 237 { 238 struct wlan_dfs *dfs; 239 enum precac_chan_state retval = PRECAC_ERR; 240 241 dfs = wlan_pdev_get_dfs_obj(pdev); 242 if (!dfs) { 243 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 244 return PRECAC_ERR; 245 } 246 247 retval = dfs_get_precac_chan_state_for_freq(dfs, precac_chan_freq); 248 if (retval == PRECAC_ERR) { 249 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, 250 "Could not find precac channel state"); 251 } 252 253 return retval; 254 } 255 #endif 256 #endif 257 258 #ifdef MOBILE_DFS_SUPPORT 259 QDF_STATUS ucfg_dfs_update_config(struct wlan_objmgr_psoc *psoc, 260 struct dfs_user_config *req) 261 { 262 struct dfs_soc_priv_obj *soc_obj; 263 264 if (!psoc || !req) { 265 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 266 "psoc: 0x%pK, req: 0x%pK", psoc, req); 267 return QDF_STATUS_E_FAILURE; 268 } 269 270 soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 271 WLAN_UMAC_COMP_DFS); 272 if (!soc_obj) { 273 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 274 "Failed to get dfs psoc component"); 275 return QDF_STATUS_E_FAILURE; 276 } 277 278 soc_obj->dfs_is_phyerr_filter_offload = 279 req->dfs_is_phyerr_filter_offload; 280 281 return QDF_STATUS_SUCCESS; 282 } 283 qdf_export_symbol(ucfg_dfs_update_config); 284 #endif 285 286 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 287 QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev, 288 int status_timeout) 289 { 290 struct wlan_dfs *dfs; 291 292 dfs = wlan_pdev_get_dfs_obj(pdev); 293 if (!dfs) { 294 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 295 return QDF_STATUS_E_FAILURE; 296 } 297 298 dfs_set_override_status_timeout(dfs, status_timeout); 299 300 return QDF_STATUS_SUCCESS; 301 } 302 303 qdf_export_symbol(ucfg_dfs_set_override_status_timeout); 304 305 QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev, 306 int *status_timeout) 307 { 308 struct wlan_dfs *dfs; 309 310 dfs = wlan_pdev_get_dfs_obj(pdev); 311 if (!dfs) { 312 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 313 return QDF_STATUS_E_FAILURE; 314 } 315 316 dfs_get_override_status_timeout(dfs, status_timeout); 317 318 return QDF_STATUS_SUCCESS; 319 } 320 321 qdf_export_symbol(ucfg_dfs_get_override_status_timeout); 322 #endif 323 324 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) 325 void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev, 326 bool allow_hw_pulses) 327 { 328 struct wlan_dfs *dfs; 329 330 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) 331 return; 332 333 dfs = wlan_pdev_get_dfs_obj(pdev); 334 if (!dfs) { 335 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 336 return; 337 } 338 339 dfs_allow_hw_pulses(dfs, allow_hw_pulses); 340 } 341 342 qdf_export_symbol(ucfg_dfs_allow_hw_pulses); 343 344 bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev) 345 { 346 struct wlan_dfs *dfs; 347 348 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) 349 return false; 350 351 dfs = wlan_pdev_get_dfs_obj(pdev); 352 if (!dfs) { 353 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 354 return false; 355 } 356 357 return dfs_is_hw_pulses_allowed(dfs); 358 } 359 360 qdf_export_symbol(ucfg_dfs_is_hw_pulses_allowed); 361 #endif 362 363 #ifdef QCA_SUPPORT_AGILE_DFS 364 QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc *psoc) 365 { 366 struct dfs_soc_priv_obj *soc_obj; 367 368 if (!psoc) { 369 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); 370 return QDF_STATUS_E_FAILURE; 371 } 372 373 soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 374 WLAN_UMAC_COMP_DFS); 375 if (!soc_obj) { 376 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 377 "Failed to get dfs psoc component"); 378 return QDF_STATUS_E_FAILURE; 379 } 380 381 dfs_reset_agile_config(soc_obj); 382 383 return QDF_STATUS_SUCCESS; 384 } 385 386 qdf_export_symbol(ucfg_dfs_reset_agile_config); 387 #endif 388 389 QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev) 390 { 391 struct wlan_dfs *dfs; 392 393 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) 394 return QDF_STATUS_SUCCESS; 395 396 dfs = wlan_pdev_get_dfs_obj(pdev); 397 if (!dfs) { 398 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 399 return QDF_STATUS_E_FAILURE; 400 } 401 402 dfs_reinit_timers(dfs); 403 404 return QDF_STATUS_SUCCESS; 405 } 406 407 qdf_export_symbol(ucfg_dfs_reinit_timers); 408 409 #ifdef QCA_SUPPORT_ADFS_RCAC 410 QDF_STATUS ucfg_dfs_set_rcac_enable(struct wlan_objmgr_pdev *pdev, 411 bool rcac_en) 412 { 413 struct wlan_dfs *dfs; 414 415 dfs = wlan_pdev_get_dfs_obj(pdev); 416 if (!dfs) { 417 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 418 return QDF_STATUS_E_FAILURE; 419 } 420 421 dfs_set_rcac_enable(dfs, rcac_en); 422 423 return QDF_STATUS_SUCCESS; 424 } 425 426 qdf_export_symbol(ucfg_dfs_set_rcac_enable); 427 428 QDF_STATUS ucfg_dfs_get_rcac_enable(struct wlan_objmgr_pdev *pdev, 429 bool *rcac_en) 430 { 431 struct wlan_dfs *dfs; 432 433 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) { 434 *rcac_en = false; 435 return QDF_STATUS_SUCCESS; 436 } 437 438 dfs = wlan_pdev_get_dfs_obj(pdev); 439 if (!dfs) { 440 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 441 return QDF_STATUS_E_FAILURE; 442 } 443 444 dfs_get_rcac_enable(dfs, rcac_en); 445 446 return QDF_STATUS_SUCCESS; 447 } 448 449 qdf_export_symbol(ucfg_dfs_get_rcac_enable); 450 451 QDF_STATUS ucfg_dfs_set_rcac_freq(struct wlan_objmgr_pdev *pdev, 452 qdf_freq_t rcac_freq) 453 { 454 struct wlan_dfs *dfs; 455 456 dfs = wlan_pdev_get_dfs_obj(pdev); 457 if (!dfs) { 458 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 459 return QDF_STATUS_E_FAILURE; 460 } 461 462 dfs_set_rcac_freq(dfs, rcac_freq); 463 464 return QDF_STATUS_SUCCESS; 465 } 466 467 qdf_export_symbol(ucfg_dfs_set_rcac_freq); 468 469 QDF_STATUS ucfg_dfs_get_rcac_freq(struct wlan_objmgr_pdev *pdev, 470 qdf_freq_t *rcac_freq) 471 { 472 struct wlan_dfs *dfs; 473 474 dfs = wlan_pdev_get_dfs_obj(pdev); 475 if (!dfs) { 476 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 477 return QDF_STATUS_E_FAILURE; 478 } 479 480 dfs_get_rcac_freq(dfs, rcac_freq); 481 482 return QDF_STATUS_SUCCESS; 483 } 484 485 qdf_export_symbol(ucfg_dfs_get_rcac_freq); 486 487 bool ucfg_dfs_is_agile_rcac_enabled(struct wlan_objmgr_pdev *pdev) 488 { 489 struct wlan_dfs *dfs; 490 491 dfs = wlan_pdev_get_dfs_obj(pdev); 492 if (!dfs) { 493 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); 494 return false; 495 } 496 497 return dfs_is_agile_rcac_enabled(dfs); 498 } 499 500 qdf_export_symbol(ucfg_dfs_is_agile_rcac_enabled); 501 #endif 502 503