1 /* 2 * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2011, Atheros Communications Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "../dfs.h" 19 #include "../dfs_zero_cac.h" 20 #include "../dfs_filter_init.h" 21 #include "wlan_dfs_mlme_api.h" 22 #include "wlan_dfs_lmac_api.h" 23 #include "../dfs_partial_offload_radar.h" 24 #include "../dfs_internal.h" 25 26 void dfs_get_radars(struct wlan_dfs *dfs) 27 { 28 struct wlan_objmgr_psoc *psoc; 29 30 if (!dfs) { 31 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 32 return; 33 } 34 35 psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj); 36 if (!psoc) { 37 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "psoc is NULL"); 38 return; 39 } 40 41 if (wlan_objmgr_psoc_get_dev_type(psoc) == WLAN_DEV_OL) { 42 /* For Partial offload */ 43 dfs_get_po_radars(dfs); 44 } else { 45 /* For Direct Attach (DA) */ 46 dfs_get_da_radars(dfs); 47 } 48 } 49 50 int dfs_radar_disable(struct wlan_dfs *dfs) 51 { 52 dfs->dfs_proc_phyerr &= ~DFS_AR_EN; 53 dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; 54 55 return 0; 56 } 57 58 void dfs_phyerr_param_copy(struct wlan_dfs_phyerr_param *dst, 59 struct wlan_dfs_phyerr_param *src) 60 { 61 qdf_mem_copy(dst, src, sizeof(*dst)); 62 } 63 64 #ifdef CONFIG_CHAN_FREQ_API 65 struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, 66 int ext_chan_flag) 67 { 68 struct dfs_state *rs = NULL; 69 struct dfs_channel *ch, cmp_ch1; 70 int i; 71 QDF_STATUS err; 72 73 if (!dfs) { 74 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 75 return NULL; 76 } 77 ch = &cmp_ch1; 78 if (ext_chan_flag) { 79 err = dfs_mlme_get_extchan_for_freq( 80 dfs->dfs_pdev_obj, 81 &ch->dfs_ch_freq, 82 &ch->dfs_ch_flags, 83 &ch->dfs_ch_flagext, 84 &ch->dfs_ch_ieee, 85 &ch->dfs_ch_vhtop_ch_freq_seg1, 86 &ch->dfs_ch_vhtop_ch_freq_seg2, 87 &ch->dfs_ch_mhz_freq_seg1, 88 &ch->dfs_ch_mhz_freq_seg2); 89 90 if (err == QDF_STATUS_SUCCESS) { 91 dfs_debug(dfs, WLAN_DEBUG_DFS2, 92 "Extension channel freq = %u flags=0x%x", 93 ch->dfs_ch_freq, 94 ch->dfs_ch_flagext); 95 } else { 96 return NULL; 97 } 98 } else { 99 ch = dfs->dfs_curchan; 100 dfs_debug(dfs, WLAN_DEBUG_DFS2, 101 "Primary channel freq = %u flags=0x%x", 102 ch->dfs_ch_freq, ch->dfs_ch_flagext); 103 } 104 105 for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { 106 if ((dfs->dfs_radar[i].rs_chan.dfs_ch_freq == 107 ch->dfs_ch_freq) && 108 (dfs->dfs_radar[i].rs_chan.dfs_ch_flags == 109 ch->dfs_ch_flags)) { 110 if (index) 111 *index = (uint8_t)i; 112 return &dfs->dfs_radar[i]; 113 } 114 } 115 /* No existing channel found, look for first free channel state entry.*/ 116 for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { 117 if (dfs->dfs_radar[i].rs_chan.dfs_ch_freq == 0) { 118 rs = &dfs->dfs_radar[i]; 119 /* Found one, set channel info and default thresholds.*/ 120 rs->rs_chan = *ch; 121 122 /* Copy the parameters from the default set. */ 123 dfs_phyerr_param_copy(&rs->rs_param, 124 &dfs->dfs_defaultparams); 125 126 if (index) 127 *index = (uint8_t)i; 128 129 return rs; 130 } 131 } 132 dfs_debug(dfs, WLAN_DEBUG_DFS2, "No more radar states left."); 133 134 return NULL; 135 } 136 #else 137 #ifdef CONFIG_CHAN_NUM_API 138 struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, 139 int ext_chan_flag) 140 { 141 struct dfs_state *rs = NULL; 142 struct dfs_channel *cmp_ch, cmp_ch1; 143 int i; 144 QDF_STATUS err; 145 146 if (!dfs) { 147 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 148 return NULL; 149 } 150 cmp_ch = &cmp_ch1; 151 if (ext_chan_flag) { 152 err = dfs_mlme_get_extchan(dfs->dfs_pdev_obj, 153 &(cmp_ch->dfs_ch_freq), 154 &(cmp_ch->dfs_ch_flags), 155 &(cmp_ch->dfs_ch_flagext), 156 &(cmp_ch->dfs_ch_ieee), 157 &(cmp_ch->dfs_ch_vhtop_ch_freq_seg1), 158 &(cmp_ch->dfs_ch_vhtop_ch_freq_seg2)); 159 160 if (err == QDF_STATUS_SUCCESS) { 161 dfs_debug(dfs, WLAN_DEBUG_DFS2, 162 "Extension channel freq = %u flags=0x%x", 163 cmp_ch->dfs_ch_freq, 164 cmp_ch->dfs_ch_flagext); 165 } else 166 return NULL; 167 } else { 168 cmp_ch = dfs->dfs_curchan; 169 dfs_debug(dfs, WLAN_DEBUG_DFS2, 170 "Primary channel freq = %u flags=0x%x", 171 cmp_ch->dfs_ch_freq, cmp_ch->dfs_ch_flagext); 172 } 173 174 for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { 175 if ((dfs->dfs_radar[i].rs_chan.dfs_ch_freq == 176 cmp_ch->dfs_ch_freq) && 177 (dfs->dfs_radar[i].rs_chan.dfs_ch_flags == 178 cmp_ch->dfs_ch_flags) 179 ) { 180 if (index) 181 *index = (uint8_t)i; 182 return &(dfs->dfs_radar[i]); 183 } 184 } 185 /* No existing channel found, look for first free channel state entry.*/ 186 for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { 187 if (dfs->dfs_radar[i].rs_chan.dfs_ch_freq == 0) { 188 rs = &(dfs->dfs_radar[i]); 189 /* Found one, set channel info and default thresholds.*/ 190 rs->rs_chan = *cmp_ch; 191 192 /* Copy the parameters from the default set. */ 193 dfs_phyerr_param_copy(&rs->rs_param, 194 &dfs->dfs_defaultparams); 195 196 if (index) 197 *index = (uint8_t)i; 198 199 return rs; 200 } 201 } 202 dfs_debug(dfs, WLAN_DEBUG_DFS2, "No more radar states left."); 203 204 return NULL; 205 } 206 #endif 207 #endif 208 209 #ifdef CONFIG_CHAN_FREQ_API 210 void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode) 211 { 212 int is_ext_ch; 213 int is_fastclk = 0; 214 struct dfs_channel *exch, extchan; 215 QDF_STATUS err = QDF_STATUS_E_FAILURE; 216 217 if (!dfs) { 218 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 219 return; 220 } 221 222 is_ext_ch = WLAN_IS_CHAN_11N_HT40(dfs->dfs_curchan); 223 lmac_dfs_disable(dfs->dfs_pdev_obj, no_cac); 224 /* 225 * In all modes, if the primary is DFS then we have to 226 * enable radar detection. In HT80_80, we can have 227 * primary non-DFS 80MHz with extension 80MHz DFS. 228 */ 229 if ((WLAN_IS_CHAN_DFS(dfs->dfs_curchan) || 230 ((WLAN_IS_CHAN_11AC_VHT160(dfs->dfs_curchan) || 231 WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) && 232 WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan))) || 233 (dfs_is_precac_timer_running(dfs))) { 234 struct dfs_state *rs_pri = NULL, *rs_ext = NULL; 235 uint8_t index_pri, index_ext; 236 237 dfs->dfs_proc_phyerr |= DFS_AR_EN; 238 dfs->dfs_proc_phyerr |= DFS_RADAR_EN; 239 dfs->dfs_proc_phyerr |= DFS_SECOND_SEGMENT_RADAR_EN; 240 241 exch = &extchan; 242 if (is_ext_ch) { 243 err = dfs_mlme_get_extchan_for_freq 244 ( 245 dfs->dfs_pdev_obj, 246 &exch->dfs_ch_freq, 247 &exch->dfs_ch_flags, 248 &exch->dfs_ch_flagext, 249 &exch->dfs_ch_ieee, 250 &exch->dfs_ch_vhtop_ch_freq_seg1, 251 &exch->dfs_ch_vhtop_ch_freq_seg2, 252 &exch->dfs_ch_mhz_freq_seg1, 253 &exch->dfs_ch_mhz_freq_seg2); 254 } 255 dfs_reset_alldelaylines(dfs); 256 257 rs_pri = dfs_getchanstate(dfs, &index_pri, 0); 258 if (err == QDF_STATUS_SUCCESS) 259 rs_ext = dfs_getchanstate(dfs, &index_ext, 1); 260 261 if (rs_pri && ((err == QDF_STATUS_E_FAILURE) || (rs_ext))) { 262 struct wlan_dfs_phyerr_param pe; 263 264 qdf_mem_set(&pe, sizeof(pe), '\0'); 265 266 if (index_pri != dfs->dfs_curchan_radindex) 267 dfs_reset_alldelaylines(dfs); 268 269 dfs->dfs_curchan_radindex = (int16_t)index_pri; 270 271 if (rs_ext) 272 dfs->dfs_extchan_radindex = (int16_t)index_ext; 273 274 dfs_phyerr_param_copy(&pe, &rs_pri->rs_param); 275 dfs_debug(dfs, WLAN_DEBUG_DFS3, 276 "firpwr=%d, rssi=%d, height=%d, prssi=%d, inband=%d, relpwr=%d, relstep=%d, maxlen=%d", 277 pe.pe_firpwr, 278 pe.pe_rrssi, pe.pe_height, 279 pe.pe_prssi, pe.pe_inband, 280 pe.pe_relpwr, pe.pe_relstep, 281 pe.pe_maxlen); 282 283 lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk, 284 &pe, dfs->dfsdomain); 285 dfs_debug(dfs, WLAN_DEBUG_DFS, 286 "Enabled radar detection on channel %d", 287 dfs->dfs_curchan->dfs_ch_freq); 288 289 dfs->dur_multiplier = is_fastclk ? 290 DFS_FAST_CLOCK_MULTIPLIER : 291 DFS_NO_FAST_CLOCK_MULTIPLIER; 292 293 dfs_debug(dfs, WLAN_DEBUG_DFS3, 294 "duration multiplier is %d", 295 dfs->dur_multiplier); 296 } else 297 dfs_debug(dfs, WLAN_DEBUG_DFS, 298 "No more radar states left"); 299 } 300 } 301 #else 302 #ifdef CONFIG_CHAN_NUM_API 303 void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode) 304 { 305 int is_ext_ch; 306 int is_fastclk = 0; 307 struct dfs_channel *ext_ch, extchan; 308 QDF_STATUS err = QDF_STATUS_E_FAILURE; 309 310 if (!dfs) { 311 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 312 return; 313 } 314 315 is_ext_ch = WLAN_IS_CHAN_11N_HT40(dfs->dfs_curchan); 316 lmac_dfs_disable(dfs->dfs_pdev_obj, no_cac); 317 /* 318 * In all modes, if the primary is DFS then we have to 319 * enable radar detection. In HT80_80, we can have 320 * primary non-DFS 80MHz with extension 80MHz DFS. 321 */ 322 if ((WLAN_IS_CHAN_DFS(dfs->dfs_curchan) || 323 ((WLAN_IS_CHAN_11AC_VHT160(dfs->dfs_curchan) || 324 WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) 325 && 326 WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan))) || 327 (dfs_is_precac_timer_running(dfs))) { 328 struct dfs_state *rs_pri = NULL, *rs_ext = NULL; 329 uint8_t index_pri, index_ext; 330 331 dfs->dfs_proc_phyerr |= DFS_AR_EN; 332 dfs->dfs_proc_phyerr |= DFS_RADAR_EN; 333 dfs->dfs_proc_phyerr |= DFS_SECOND_SEGMENT_RADAR_EN; 334 335 ext_ch = &extchan; 336 if (is_ext_ch) 337 err = dfs_mlme_get_extchan(dfs->dfs_pdev_obj, 338 &(ext_ch->dfs_ch_freq), 339 &(ext_ch->dfs_ch_flags), 340 &(ext_ch->dfs_ch_flagext), 341 &(ext_ch->dfs_ch_ieee), 342 &(ext_ch->dfs_ch_vhtop_ch_freq_seg1), 343 &(ext_ch->dfs_ch_vhtop_ch_freq_seg2)); 344 345 346 dfs_reset_alldelaylines(dfs); 347 348 rs_pri = dfs_getchanstate(dfs, &index_pri, 0); 349 if (err == QDF_STATUS_SUCCESS) 350 rs_ext = dfs_getchanstate(dfs, &index_ext, 1); 351 352 if (rs_pri && ((err == QDF_STATUS_E_FAILURE) || 353 (rs_ext))) { 354 struct wlan_dfs_phyerr_param pe; 355 356 qdf_mem_set(&pe, sizeof(pe), '\0'); 357 358 if (index_pri != dfs->dfs_curchan_radindex) 359 dfs_reset_alldelaylines(dfs); 360 361 dfs->dfs_curchan_radindex = (int16_t)index_pri; 362 363 if (rs_ext) 364 dfs->dfs_extchan_radindex = (int16_t)index_ext; 365 366 dfs_phyerr_param_copy(&pe, &rs_pri->rs_param); 367 dfs_debug(dfs, WLAN_DEBUG_DFS3, 368 "firpwr=%d, rssi=%d, height=%d, prssi=%d, inband=%d, relpwr=%d, relstep=%d, maxlen=%d", 369 pe.pe_firpwr, 370 pe.pe_rrssi, pe.pe_height, 371 pe.pe_prssi, pe.pe_inband, 372 pe.pe_relpwr, pe.pe_relstep, 373 pe.pe_maxlen); 374 375 lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk, 376 &pe, dfs->dfsdomain); 377 dfs_debug(dfs, WLAN_DEBUG_DFS, 378 "Enabled radar detection on channel %d", 379 dfs->dfs_curchan->dfs_ch_freq); 380 381 dfs->dur_multiplier = is_fastclk ? 382 DFS_FAST_CLOCK_MULTIPLIER : 383 DFS_NO_FAST_CLOCK_MULTIPLIER; 384 385 dfs_debug(dfs, WLAN_DEBUG_DFS3, 386 "duration multiplier is %d", 387 dfs->dur_multiplier); 388 } else 389 dfs_debug(dfs, WLAN_DEBUG_DFS, 390 "No more radar states left"); 391 } 392 } 393 #endif 394 #endif 395 396 int dfs_set_thresholds(struct wlan_dfs *dfs, const uint32_t threshtype, 397 const uint32_t value) 398 { 399 int16_t chanindex; 400 struct dfs_state *rs; 401 struct wlan_dfs_phyerr_param pe; 402 int is_fastclk = 0; 403 404 if (!dfs) { 405 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); 406 return 0; 407 } 408 409 chanindex = dfs->dfs_curchan_radindex; 410 if ((chanindex < 0) || (chanindex >= DFS_NUM_RADAR_STATES)) { 411 dfs_debug(dfs, WLAN_DEBUG_DFS1, 412 "%s: chanindex = %d, DFS_NUM_RADAR_STATES=%d\n", 413 __func__, 414 chanindex, 415 DFS_NUM_RADAR_STATES); 416 return 0; 417 } 418 419 dfs_debug(dfs, WLAN_DEBUG_DFS, 420 "threshtype=%d, value=%d", threshtype, value); 421 422 wlan_dfs_phyerr_init_noval(&pe); 423 424 rs = &(dfs->dfs_radar[chanindex]); 425 switch (threshtype) { 426 case DFS_PARAM_FIRPWR: 427 rs->rs_param.pe_firpwr = (int32_t) value; 428 pe.pe_firpwr = value; 429 break; 430 case DFS_PARAM_RRSSI: 431 rs->rs_param.pe_rrssi = value; 432 pe.pe_rrssi = value; 433 break; 434 case DFS_PARAM_HEIGHT: 435 rs->rs_param.pe_height = value; 436 pe.pe_height = value; 437 break; 438 case DFS_PARAM_PRSSI: 439 rs->rs_param.pe_prssi = value; 440 pe.pe_prssi = value; 441 break; 442 case DFS_PARAM_INBAND: 443 rs->rs_param.pe_inband = value; 444 pe.pe_inband = value; 445 break; 446 /* 5413 specific */ 447 case DFS_PARAM_RELPWR: 448 rs->rs_param.pe_relpwr = value; 449 pe.pe_relpwr = value; 450 break; 451 case DFS_PARAM_RELSTEP: 452 rs->rs_param.pe_relstep = value; 453 pe.pe_relstep = value; 454 break; 455 case DFS_PARAM_MAXLEN: 456 rs->rs_param.pe_maxlen = value; 457 pe.pe_maxlen = value; 458 break; 459 default: 460 dfs_debug(dfs, WLAN_DEBUG_DFS1, 461 "unknown threshtype (%d)", threshtype); 462 break; 463 } 464 465 466 /* 467 * The driver layer dfs_enable routine is tasked with translating 468 * values from the global format to the per-device (HAL, offload) 469 * format. 470 */ 471 lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk, 472 &pe, dfs->dfsdomain); 473 474 return 1; 475 } 476 477 int dfs_get_thresholds(struct wlan_dfs *dfs, 478 struct wlan_dfs_phyerr_param *param) 479 { 480 lmac_dfs_get_thresholds(dfs->dfs_pdev_obj, param); 481 482 return 1; 483 } 484 485 uint16_t dfs_chan2freq(struct dfs_channel *chan) 486 { 487 if (!chan) 488 return 0; 489 490 return chan == WLAN_CHAN_ANYC ? WLAN_CHAN_ANY : chan->dfs_ch_freq; 491 } 492