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