1 /* 2 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "../dfs.h" 20 #include "../dfs_random_chan_sel.h" 21 #include <qdf_mc_timer.h> 22 #include <wlan_utility.h> 23 24 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 25 /* 26 * TODO: At present SAP Channel leakage matrix for ch 144 27 * is not available from system's team. So to play it safe 28 * and avoid crash if channel 144 is request, in following 29 * matix channel 144 is added such that it will cause code 30 * to avoid selecting channel 144. 31 * 32 * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS 33 * PROVIDED BY SYSTEM'S TEAM. 34 */ 35 36 /* channel tx leakage table - ht80 */ 37 struct dfs_matrix_tx_leak_info ht80_chan[] = { 38 {52, 39 {{36, 148}, {40, 199}, 40 {44, 193}, {48, 197}, 41 {52, DFS_TX_LEAKAGE_MIN}, {56, 153}, 42 {60, 137}, {64, 134}, 43 {100, 358}, {104, 350}, 44 {108, 404}, {112, 344}, 45 {116, 424}, {120, 429}, 46 {124, 437}, {128, 435}, 47 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 48 {140, DFS_TX_LEAKAGE_MAX}, 49 {144, DFS_TX_LEAKAGE_MIN} 50 } }, 51 52 53 {56, 54 {{36, 171}, {40, 178}, 55 {44, 171}, {48, 178}, 56 {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, 57 {60, DFS_TX_LEAKAGE_MIN}, {64, 280}, 58 {100, 351}, {104, 376}, 59 {108, 362}, {112, 362}, 60 {116, 403}, {120, 397}, 61 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 62 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 63 {140, DFS_TX_LEAKAGE_MAX}, 64 {144, DFS_TX_LEAKAGE_MIN} 65 } }, 66 67 {60, 68 {{36, 156}, {40, 146}, 69 {44, DFS_TX_LEAKAGE_MIN}, {48, DFS_TX_LEAKAGE_MIN}, 70 {52, 180}, {56, DFS_TX_LEAKAGE_MIN}, 71 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 72 {100, 376}, {104, 360}, 73 {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, 74 {116, 395}, {120, 399}, 75 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 76 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 77 {140, DFS_TX_LEAKAGE_MAX}, 78 {144, DFS_TX_LEAKAGE_MIN} 79 } }, 80 81 {64, 82 {{36, 217}, {40, 221}, 83 {44, DFS_TX_LEAKAGE_MIN}, {48, DFS_TX_LEAKAGE_MIN}, 84 {52, 176}, {56, 176}, 85 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 86 {100, 384}, {104, 390}, 87 {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, 88 {116, 375}, {120, 374}, 89 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 90 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 91 {140, DFS_TX_LEAKAGE_MAX}, 92 {144, DFS_TX_LEAKAGE_MIN} 93 } }, 94 95 {100, 96 {{36, 357}, {40, 326}, 97 {44, 321}, {48, 326}, 98 {52, 378}, {56, 396}, 99 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 100 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 101 {108, 196}, {112, 116}, 102 {116, 166}, {120, DFS_TX_LEAKAGE_MIN}, 103 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 104 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 105 {140, DFS_TX_LEAKAGE_MIN}, 106 {144, DFS_TX_LEAKAGE_MIN} 107 } }, 108 109 {104, 110 {{36, 325}, {40, 325}, 111 {44, 305}, {48, 352}, 112 {52, 411}, {56, 411}, 113 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 114 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 115 {108, DFS_TX_LEAKAGE_MIN}, {112, 460}, 116 {116, 198}, {120, DFS_TX_LEAKAGE_MIN}, 117 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 118 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 119 {140, DFS_TX_LEAKAGE_MIN}, 120 {144, DFS_TX_LEAKAGE_MIN} 121 } }, 122 123 {108, 124 {{36, 304}, {40, 332}, 125 {44, 310}, {48, 335}, 126 {52, 431}, {56, 391}, 127 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 128 {100, 280}, {104, DFS_TX_LEAKAGE_MIN}, 129 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 130 {116, 185}, {120, DFS_TX_LEAKAGE_MIN}, 131 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 132 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 133 {140, DFS_TX_LEAKAGE_MIN}, 134 {144, DFS_TX_LEAKAGE_MIN} 135 } }, 136 137 {112, 138 {{36, 327}, {40, 335}, 139 {44, 331}, {48, 345}, 140 {52, 367}, {56, 401}, 141 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 142 {100, 131}, {104, 132}, 143 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 144 {116, 189}, {120, DFS_TX_LEAKAGE_MIN}, 145 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 146 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 147 {140, DFS_TX_LEAKAGE_MIN}, 148 {144, DFS_TX_LEAKAGE_MIN} 149 } }, 150 151 {116, 152 {{36, 384}, {40, 372}, 153 {44, 389}, {48, 396}, 154 {52, 348}, {56, 336}, 155 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 156 {100, 172}, {104, 169}, 157 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 158 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 159 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 160 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 161 {140, DFS_TX_LEAKAGE_MIN}, 162 {144, DFS_TX_LEAKAGE_MIN} 163 } }, 164 165 {120, 166 {{36, 395}, {40, 419}, 167 {44, 439}, {48, 407}, 168 {52, 321}, {56, 334}, 169 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 170 {100, 134}, {104, 186}, 171 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 172 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 173 {124, DFS_TX_LEAKAGE_MIN}, {128, 159}, 174 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 175 {140, DFS_TX_LEAKAGE_MIN}, 176 {144, DFS_TX_LEAKAGE_MIN} 177 } }, 178 179 {124, 180 {{36, 469}, {40, 433}, 181 {44, 434}, {48, 435}, 182 {52, 332}, {56, 345}, 183 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 184 {100, 146}, {104, 177}, 185 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 186 {116, 350}, {120, DFS_TX_LEAKAGE_MIN}, 187 {124, DFS_TX_LEAKAGE_MIN}, {128, 138}, 188 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 189 {140, DFS_TX_LEAKAGE_MIN}, 190 {144, DFS_TX_LEAKAGE_MIN} 191 } }, 192 193 {128, 194 {{36, 408}, {40, 434}, 195 {44, 449}, {48, 444}, 196 {52, 341}, {56, 374}, 197 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 198 {100, 205}, {104, 208}, 199 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 200 {116, 142}, {120, DFS_TX_LEAKAGE_MIN}, 201 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 202 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 203 {140, DFS_TX_LEAKAGE_MIN}, 204 {144, DFS_TX_LEAKAGE_MIN} 205 } }, 206 207 {132, 208 {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, 209 {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, 210 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 211 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 212 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 213 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 214 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 215 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 216 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 217 {140, DFS_TX_LEAKAGE_MIN}, 218 {144, DFS_TX_LEAKAGE_MIN} 219 } }, 220 221 {136, 222 {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, 223 {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, 224 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 225 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 226 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 227 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 228 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 229 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 230 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 231 {140, DFS_TX_LEAKAGE_MIN}, 232 {144, DFS_TX_LEAKAGE_MIN} 233 } }, 234 235 {140, 236 {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, 237 {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, 238 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 239 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 240 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 241 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 242 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 243 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 244 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 245 {144, DFS_TX_LEAKAGE_MIN} 246 } }, 247 248 {144, 249 {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, 250 {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, 251 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 252 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 253 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 254 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 255 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 256 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 257 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 258 {144, DFS_TX_LEAKAGE_MIN} 259 } }, 260 }; 261 262 /* channel tx leakage table - ht40 */ 263 struct dfs_matrix_tx_leak_info ht40_chan[] = { 264 {52, 265 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, 266 {44, 230}, {48, 230}, 267 {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, 268 {60, DFS_TX_LEAKAGE_AUTO_MIN}, {64, DFS_TX_LEAKAGE_AUTO_MIN}, 269 {100, 625}, {104, 323}, 270 {108, 646}, {112, 646}, 271 {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, 272 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 273 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 274 {140, DFS_TX_LEAKAGE_MAX}, 275 {144, DFS_TX_LEAKAGE_MIN} 276 } }, 277 278 {56, 279 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, 280 {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, 281 {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, 282 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 283 {100, 611}, {104, 611}, 284 {108, 617}, {112, 617}, 285 {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, 286 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 287 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 288 {140, DFS_TX_LEAKAGE_MAX}, 289 {144, DFS_TX_LEAKAGE_MIN} 290 } }, 291 292 {60, 293 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, 294 {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, 295 {52, 190}, {56, 190}, 296 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 297 {100, 608}, {104, 608}, 298 {108, 623}, {112, 623}, 299 {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, 300 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 301 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 302 {140, DFS_TX_LEAKAGE_MAX}, 303 {144, DFS_TX_LEAKAGE_MIN} 304 } }, 305 306 {64, 307 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, 308 {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, 309 {52, 295}, {56, 295}, 310 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 311 {100, 594}, {104, 594}, 312 {108, 625}, {112, 625}, 313 {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, 314 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 315 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 316 {140, DFS_TX_LEAKAGE_MAX}, 317 {144, DFS_TX_LEAKAGE_MIN} 318 } }, 319 320 {100, 321 {{36, 618}, {40, 618}, 322 {44, 604}, {48, 604}, 323 {52, 596}, {56, 596}, 324 {60, 584}, {64, 584}, 325 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 326 {108, 299}, {112, 299}, 327 {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, 328 {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, 329 {132, 538}, {136, 538}, 330 {140, 598}, 331 {144, DFS_TX_LEAKAGE_MIN} 332 } }, 333 334 {104, 335 {{36, 636}, {40, 636}, 336 {44, 601}, {48, 601}, 337 {52, 616}, {56, 616}, 338 {60, 584}, {64, 584}, 339 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 340 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 341 {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, 342 {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, 343 {132, 553}, {136, 553}, 344 {140, 568}, 345 {144, DFS_TX_LEAKAGE_MIN} 346 } }, 347 348 {108, 349 {{36, 600}, {40, 600}, 350 {44, 627}, {48, 627}, 351 {52, 611}, {56, 611}, 352 {60, 611}, {64, 611}, 353 {100, 214}, {104, 214}, 354 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 355 {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, 356 {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, 357 {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, 358 {140, 534}, 359 {144, DFS_TX_LEAKAGE_MIN} 360 } }, 361 362 {112, 363 {{36, 645}, {40, 645}, 364 {44, 641}, {48, 641}, 365 {52, 618}, {56, 618}, 366 {60, 612}, {64, 612}, 367 {100, 293}, {104, 293}, 368 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 369 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 370 {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, 371 {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, 372 {140, 521}, 373 {144, DFS_TX_LEAKAGE_MIN} 374 } }, 375 376 {116, 377 {{36, 661}, {40, 661}, 378 {44, 624}, {48, 624}, 379 {52, 634}, {56, 634}, 380 {60, 611}, {64, 611}, 381 {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, 382 {108, 217}, {112, 217}, 383 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 384 {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, 385 {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, 386 {140, DFS_TX_LEAKAGE_AUTO_MIN}, 387 {144, DFS_TX_LEAKAGE_MIN} 388 } }, 389 390 {120, 391 {{36, 667}, {40, 667}, 392 {44, 645}, {48, 645}, 393 {52, 633}, {56, 633}, 394 {60, 619}, {64, 619}, 395 {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, 396 {108, 291}, {112, 291}, 397 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 398 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 399 {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, 400 {140, DFS_TX_LEAKAGE_AUTO_MIN}, 401 {144, DFS_TX_LEAKAGE_MIN} 402 } }, 403 404 {124, 405 {{36, 676}, {40, 676}, 406 {44, 668}, {48, 668}, 407 {52, 595}, {56, 595}, 408 {60, 622}, {64, 622}, 409 {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, 410 {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, 411 {116, 225}, {120, 225}, 412 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 413 {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, 414 {140, DFS_TX_LEAKAGE_AUTO_MIN}, 415 {144, DFS_TX_LEAKAGE_MIN} 416 } }, 417 418 {128, 419 {{36, 678}, {40, 678}, 420 {44, 664}, {48, 664}, 421 {52, 651}, {56, 651}, 422 {60, 643}, {64, 643}, 423 {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, 424 {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, 425 {116, 293}, {120, 293}, 426 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 427 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 428 {140, DFS_TX_LEAKAGE_AUTO_MIN}, 429 {144, DFS_TX_LEAKAGE_MIN} 430 } }, 431 432 {132, 433 {{36, 689}, {40, 689}, 434 {44, 669}, {48, 669}, 435 {52, 662}, {56, 662}, 436 {60, 609}, {64, 609}, 437 {100, 538}, {104, 538}, 438 {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, 439 {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, 440 {124, 247}, {128, 247}, 441 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 442 {140, DFS_TX_LEAKAGE_MIN}, 443 {144, DFS_TX_LEAKAGE_MIN} 444 } }, 445 446 {136, 447 {{36, 703}, {40, 703}, 448 {44, 688}, {48, DFS_TX_LEAKAGE_MIN}, 449 {52, 671}, {56, 671}, 450 {60, 658}, {64, 658}, 451 {100, 504}, {104, 504}, 452 {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, 453 {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, 454 {124, 289}, {128, 289}, 455 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 456 {140, DFS_TX_LEAKAGE_MIN}, 457 {144, DFS_TX_LEAKAGE_MIN} 458 } }, 459 460 {140, 461 {{36, 695}, {40, 695}, 462 {44, 684}, {48, 684}, 463 {52, 664}, {56, 664}, 464 {60, 658}, {64, 658}, 465 {100, 601}, {104, 601}, 466 {108, 545}, {112, 545}, 467 {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, 468 {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, 469 {132, 262}, {136, 262}, 470 {140, DFS_TX_LEAKAGE_MIN}, 471 {144, DFS_TX_LEAKAGE_MIN} 472 } }, 473 474 {144, 475 {{36, 695}, {40, 695}, 476 {44, 684}, {48, 684}, 477 {52, 664}, {56, 664}, 478 {60, 658}, {64, 658}, 479 {100, 601}, {104, 601}, 480 {108, 545}, {112, 545}, 481 {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, 482 {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, 483 {132, 262}, {136, 262}, 484 {140, DFS_TX_LEAKAGE_MIN}, 485 {144, DFS_TX_LEAKAGE_MIN} 486 } }, 487 }; 488 489 /* channel tx leakage table - ht20 */ 490 struct dfs_matrix_tx_leak_info ht20_chan[] = { 491 {52, 492 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 286}, 493 {44, 225}, {48, 121}, 494 {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, 495 {60, 300}, {64, DFS_TX_LEAKAGE_AUTO_MIN}, 496 {100, 637}, {104, DFS_TX_LEAKAGE_MAX}, 497 {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, 498 {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, 499 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 500 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 501 {140, DFS_TX_LEAKAGE_MAX}, 502 {144, DFS_TX_LEAKAGE_MIN} 503 } }, 504 505 {56, 506 {{36, 468}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, 507 {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 206}, 508 {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, 509 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 510 {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, 511 {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, 512 {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, 513 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 514 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 515 {140, DFS_TX_LEAKAGE_MAX}, 516 {144, DFS_TX_LEAKAGE_MIN} 517 } }, 518 519 {60, 520 {{36, 507}, {40, 440}, 521 {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 313}, 522 {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, 523 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 524 {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, 525 {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, 526 {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, 527 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 528 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 529 {140, DFS_TX_LEAKAGE_MAX}, 530 {144, DFS_TX_LEAKAGE_MIN} 531 } }, 532 533 {64, 534 {{36, 516}, {40, 520}, 535 {44, 506}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, 536 {52, 301}, {56, 258}, 537 {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, 538 {100, 620}, {104, 617}, 539 {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, 540 {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, 541 {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, 542 {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, 543 {140, DFS_TX_LEAKAGE_MAX}, 544 {144, DFS_TX_LEAKAGE_MIN} 545 } }, 546 547 {100, 548 {{36, 616}, {40, 601}, 549 {44, 604}, {48, 589}, 550 {52, 612}, {56, 592}, 551 {60, 590}, {64, 582}, 552 {100, DFS_TX_LEAKAGE_MIN}, {104, 131}, 553 {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, 554 {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 522}, 555 {124, 571}, {128, 589}, 556 {132, 593}, {136, 598}, 557 {140, 594}, 558 {144, DFS_TX_LEAKAGE_MIN}, 559 } }, 560 561 {104, 562 {{36, 622}, {40, 624}, 563 {44, 618}, {48, 610}, 564 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 565 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 566 {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, 567 {108, DFS_TX_LEAKAGE_MIN}, {112, 463}, 568 {116, 483}, {120, 503}, 569 {124, 523}, {128, 565}, 570 {132, 570}, {136, 588}, 571 {140, 585}, 572 {144, DFS_TX_LEAKAGE_MIN}, 573 } }, 574 575 {108, 576 {{36, 620}, {40, 638}, 577 {44, 611}, {48, 614}, 578 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 579 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 580 {100, 477}, {104, DFS_TX_LEAKAGE_MIN}, 581 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 582 {116, 477}, {120, 497}, 583 {124, 517}, {128, 537}, 584 {132, 557}, {136, 577}, 585 {140, 603}, 586 {144, DFS_TX_LEAKAGE_MIN}, 587 } }, 588 589 {112, 590 {{36, 636}, {40, 623}, 591 {44, 638}, {48, 628}, 592 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 593 {60, DFS_TX_LEAKAGE_MAX}, {64, 606}, 594 {100, 501}, {104, 481}, 595 {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, 596 {116, DFS_TX_LEAKAGE_MIN}, {120, 481}, 597 {124, 501}, {128, 421}, 598 {132, 541}, {136, 561}, 599 {140, 583}, 600 {144, DFS_TX_LEAKAGE_MIN}, 601 } }, 602 603 {116, 604 {{36, 646}, {40, 648}, 605 {44, 633}, {48, 634}, 606 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 607 {60, 615}, {64, 594}, 608 {100, 575}, {104, 554}, 609 {108, 534}, {112, DFS_TX_LEAKAGE_MIN}, 610 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 611 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 612 {132, 534}, {136, 554}, 613 {140, 574}, 614 {144, DFS_TX_LEAKAGE_MIN}, 615 } }, 616 617 {120, 618 {{36, 643}, {40, 649}, 619 {44, 654}, {48, 629}, 620 {52, DFS_TX_LEAKAGE_MAX}, {56, 621}, 621 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 622 {100, 565}, {104, 545}, 623 {108, 525}, {112, 505}, 624 {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, 625 {124, DFS_TX_LEAKAGE_MIN}, {128, 505}, 626 {132, 525}, {136, 545}, 627 {140, 565}, 628 {144, DFS_TX_LEAKAGE_MIN}, 629 } }, 630 631 {124, 632 {{36, 638}, {40, 657}, 633 {44, 663}, {48, 649}, 634 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 635 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 636 {100, 581}, {104, 561}, 637 {108, 541}, {112, 521}, 638 {116, 499}, {120, DFS_TX_LEAKAGE_MIN}, 639 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 640 {132, 499}, {136, 519}, 641 {140, 539}, 642 {144, DFS_TX_LEAKAGE_MIN} 643 } }, 644 645 {128, 646 {{36, 651}, {40, 651}, 647 {44, 674}, {48, 640}, 648 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 649 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 650 {100, 603}, {104, 560}, 651 {108, 540}, {112, 520}, 652 {116, 499}, {120, 479}, 653 {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, 654 {132, DFS_TX_LEAKAGE_MIN}, {136, 479}, 655 {140, 499}, 656 {144, DFS_TX_LEAKAGE_MIN} 657 } }, 658 659 {132, 660 {{36, 643}, {40, 668}, 661 {44, 651}, {48, 657}, 662 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 663 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 664 {100, DFS_TX_LEAKAGE_MAX}, {104, 602}, 665 {108, 578}, {112, 570}, 666 {116, 550}, {120, 530}, 667 {124, 510}, {128, DFS_TX_LEAKAGE_MIN}, 668 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 669 {140, 490}, 670 {144, DFS_TX_LEAKAGE_MIN} 671 } }, 672 673 {136, 674 {{36, 654}, {40, 667}, 675 {44, 666}, {48, 642}, 676 {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, 677 {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, 678 {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, 679 {108, DFS_TX_LEAKAGE_MAX}, {112, 596}, 680 {116, 555}, {120, 535}, 681 {124, 515}, {128, 495}, 682 {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, 683 {140, DFS_TX_LEAKAGE_MIN}, 684 {144, DFS_TX_LEAKAGE_MIN} 685 } }, 686 687 {140, 688 {{36, 679}, {40, 673}, 689 {44, 667}, {48, 656}, 690 {52, 634}, {56, 663}, 691 {60, 662}, {64, 660}, 692 {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, 693 {108, DFS_TX_LEAKAGE_MAX}, {112, 590}, 694 {116, 573}, {120, 553}, 695 {124, 533}, {128, 513}, 696 {132, 490}, {136, DFS_TX_LEAKAGE_MIN}, 697 {140, DFS_TX_LEAKAGE_MIN}, 698 {144, DFS_TX_LEAKAGE_MIN} 699 } }, 700 701 {144, 702 {{36, 679}, {40, 673}, 703 {44, 667}, {48, 656}, 704 {52, 634}, {56, 663}, 705 {60, 662}, {64, 660}, 706 {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, 707 {108, DFS_TX_LEAKAGE_MAX}, {112, 590}, 708 {116, 573}, {120, 553}, 709 {124, 533}, {128, 513}, 710 {132, 490}, {136, DFS_TX_LEAKAGE_MIN}, 711 {140, DFS_TX_LEAKAGE_MIN}, 712 {144, DFS_TX_LEAKAGE_MIN} 713 } }, 714 }; 715 716 /* 717 * dfs_find_target_channel_in_channel_matrix() - finds the leakage matrix 718 * @ch_width: target channel width 719 * @NOL_channel: the NOL channel whose leakage matrix is required 720 * @pTarget_chnl_mtrx: pointer to target channel matrix returned. 721 * 722 * This function gives the leakage matrix for given NOL channel and ch_width 723 * 724 * Return: TRUE or FALSE 725 */ 726 static bool 727 dfs_find_target_channel_in_channel_matrix(enum phy_ch_width ch_width, 728 uint8_t NOL_channel, 729 struct dfs_tx_leak_info **pTarget_chnl_mtrx) 730 { 731 struct dfs_tx_leak_info *target_chan_matrix = NULL; 732 struct dfs_matrix_tx_leak_info *pchan_matrix = NULL; 733 uint32_t nchan_matrix; 734 int i = 0; 735 736 switch (ch_width) { 737 case CH_WIDTH_20MHZ: 738 /* HT20 */ 739 pchan_matrix = ht20_chan; 740 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 741 break; 742 case CH_WIDTH_40MHZ: 743 /* HT40 */ 744 pchan_matrix = ht40_chan; 745 nchan_matrix = QDF_ARRAY_SIZE(ht40_chan); 746 break; 747 case CH_WIDTH_80MHZ: 748 /* HT80 */ 749 pchan_matrix = ht80_chan; 750 nchan_matrix = QDF_ARRAY_SIZE(ht80_chan); 751 break; 752 default: 753 /* handle exception and fall back to HT20 table */ 754 pchan_matrix = ht20_chan; 755 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 756 break; 757 } 758 759 for (i = 0; i < nchan_matrix; i++) { 760 /* find the SAP channel to map the leakage matrix */ 761 if (NOL_channel == pchan_matrix[i].channel) { 762 target_chan_matrix = pchan_matrix[i].chan_matrix; 763 break; 764 } 765 } 766 767 if (NULL == target_chan_matrix) { 768 return false; 769 } else { 770 *pTarget_chnl_mtrx = target_chan_matrix; 771 return true; 772 } 773 } 774 775 QDF_STATUS 776 dfs_mark_leaking_ch(struct wlan_dfs *dfs, 777 enum phy_ch_width ch_width, 778 uint8_t temp_ch_lst_sz, 779 uint8_t *temp_ch_lst) 780 { 781 struct dfs_tx_leak_info *target_chan_matrix = NULL; 782 uint32_t num_channel = (CHAN_ENUM_144 - CHAN_ENUM_36) + 1; 783 uint32_t j = 0; 784 uint32_t k = 0; 785 uint8_t dfs_nol_channel; 786 struct dfs_nolelem *nol; 787 788 nol = dfs->dfs_nol; 789 while (nol) { 790 dfs_nol_channel = wlan_freq_to_chan(nol->nol_freq); 791 if (false == dfs_find_target_channel_in_channel_matrix( 792 ch_width, dfs_nol_channel, 793 &target_chan_matrix)) { 794 /* 795 * should never happen, we should always find a table 796 * here, if we don't, need a fix here! 797 */ 798 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 799 "Couldn't find target channel matrix!"); 800 QDF_ASSERT(0); 801 return QDF_STATUS_E_FAILURE; 802 } 803 /* 804 * following is based on assumption that both temp_ch_lst 805 * and target channel matrix are in increasing order of 806 * ch_id 807 */ 808 for (j = 0, k = 0; j < temp_ch_lst_sz && k < num_channel;) { 809 if (temp_ch_lst[j] == 0) { 810 j++; 811 continue; 812 } 813 if (target_chan_matrix[k].leak_chan != temp_ch_lst[j]) { 814 k++; 815 continue; 816 } 817 /* 818 * check leakage from candidate channel 819 * to NOL channel 820 */ 821 if (target_chan_matrix[k].leak_lvl <= 822 dfs->tx_leakage_threshold) { 823 /* 824 * candidate channel will have 825 * bad leakage in NOL channel, 826 * remove from temp list 827 */ 828 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 829 "dfs: channel: %d will have bad leakage due to channel: %d\n", 830 dfs_nol_channel, temp_ch_lst[j]); 831 temp_ch_lst[j] = 0; 832 } 833 j++; 834 k++; 835 } 836 nol = nol->nol_next; 837 } /* end of loop that selects each NOL */ 838 839 return QDF_STATUS_SUCCESS; 840 } 841 #else 842 QDF_STATUS 843 dfs_mark_leaking_ch(struct wlan_dfs *dfs, 844 enum phy_ch_width ch_width, 845 uint8_t temp_ch_lst_sz, 846 uint8_t *temp_ch_lst) 847 { 848 return QDF_STATUS_SUCCESS; 849 } 850 #endif 851 852 /** 853 * dfs_populate_80mhz_available_channels()- Populate channels for 80MHz using 854 * bitmap 855 * @dfs: Pointer to DFS structure. 856 * @bitmap: bitmap 857 * @avail_chnl: prepared channel list 858 * 859 * Prepare 80MHz channels from the bitmap. 860 * 861 * Return: channel count 862 */ 863 static uint8_t dfs_populate_80mhz_available_channels( 864 struct wlan_dfs *dfs, 865 struct chan_bonding_bitmap *bitmap, 866 uint8_t *avail_chnl) 867 { 868 uint8_t i = 0; 869 uint8_t chnl_count = 0; 870 uint8_t start_chan = 0; 871 872 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 873 start_chan = bitmap->chan_bonding_set[i].start_chan; 874 if (bitmap->chan_bonding_set[i].chan_map == 875 DFS_80MHZ_MASK) { 876 avail_chnl[chnl_count++] = start_chan + 877 (DFS_NEXT_5GHZ_CHANNEL * 0); 878 avail_chnl[chnl_count++] = start_chan + 879 (DFS_NEXT_5GHZ_CHANNEL * 1); 880 avail_chnl[chnl_count++] = start_chan + 881 (DFS_NEXT_5GHZ_CHANNEL * 2); 882 avail_chnl[chnl_count++] = start_chan + 883 (DFS_NEXT_5GHZ_CHANNEL * 3); 884 } 885 } 886 887 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 888 "channel count %d", chnl_count); 889 890 return chnl_count; 891 } 892 893 /** 894 * dfs_populate_40mhz_available_channels()- Populate channels for 40MHz using 895 * bitmap 896 * @dfs: Pointer to DFS structure. 897 * @bitmap: bitmap 898 * @avail_chnl: prepared channel list 899 * 900 * Prepare 40MHz channels from the bitmap. 901 * 902 * Return: channel count 903 */ 904 static uint8_t dfs_populate_40mhz_available_channels( 905 struct wlan_dfs *dfs, 906 struct chan_bonding_bitmap *bitmap, 907 uint8_t *avail_chnl) 908 { 909 uint8_t i = 0; 910 uint8_t chnl_count = 0; 911 uint8_t start_chan = 0; 912 913 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 914 start_chan = bitmap->chan_bonding_set[i].start_chan; 915 if ((bitmap->chan_bonding_set[i].chan_map & 916 DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) { 917 avail_chnl[chnl_count++] = start_chan + 918 (DFS_NEXT_5GHZ_CHANNEL * 0); 919 avail_chnl[chnl_count++] = start_chan + 920 (DFS_NEXT_5GHZ_CHANNEL * 1); 921 } 922 if ((bitmap->chan_bonding_set[i].chan_map & 923 DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) { 924 avail_chnl[chnl_count++] = start_chan + 925 (DFS_NEXT_5GHZ_CHANNEL * 2); 926 avail_chnl[chnl_count++] = start_chan + 927 (DFS_NEXT_5GHZ_CHANNEL * 3); 928 } 929 } 930 931 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 932 "channel count %d", chnl_count); 933 934 return chnl_count; 935 } 936 937 /** 938 * dfs_populate_available_channels()- Populate channels based on width and 939 * bitmap 940 * @dfs: Pointer to DFS structure. 941 * @bitmap: bitmap 942 * @ch_width: channel width 943 * @avail_chnl: prepared channel list 944 * 945 * Prepare channel list based on width and channel bitmap. 946 * 947 * Return: channel count 948 */ 949 static uint8_t dfs_populate_available_channels( 950 struct wlan_dfs *dfs, 951 struct chan_bonding_bitmap *bitmap, 952 uint8_t ch_width, 953 uint8_t *avail_chnl) 954 { 955 switch (ch_width) { 956 case DFS_CH_WIDTH_160MHZ: 957 case DFS_CH_WIDTH_80P80MHZ: 958 case DFS_CH_WIDTH_80MHZ: 959 return dfs_populate_80mhz_available_channels( 960 dfs, bitmap, avail_chnl); 961 case DFS_CH_WIDTH_40MHZ: 962 return dfs_populate_40mhz_available_channels( 963 dfs, bitmap, avail_chnl); 964 default: 965 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 966 "Invalid ch_width %d", ch_width); 967 break; 968 } 969 970 return 0; 971 } 972 973 /** 974 * dfs_get_rand_from_lst()- Get random channel from a given channel list 975 * @dfs: Pointer to DFS structure. 976 * @ch_lst: channel list 977 * @num_ch: number of channels 978 * 979 * Get random channel from given channel list. 980 * 981 * Return: channel number 982 */ 983 static uint8_t dfs_get_rand_from_lst( 984 struct wlan_dfs *dfs, 985 uint8_t *ch_lst, 986 uint8_t num_ch) 987 { 988 uint8_t i; 989 uint32_t rand_byte = 0; 990 991 if (!num_ch || !ch_lst) { 992 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 993 "invalid param ch_lst %pK, num_ch = %d", 994 ch_lst, num_ch); 995 return 0; 996 } 997 998 get_random_bytes((uint8_t *)&rand_byte, 1); 999 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch; 1000 1001 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1002 "random channel %d", ch_lst[i]); 1003 1004 return ch_lst[i]; 1005 } 1006 1007 /** 1008 * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based 1009 * on given channel number 1010 * @dfs: Pointer to DFS structure. 1011 * @bitmap: bitmap 1012 * @channel: channel number 1013 * 1014 * Set channel bit in bitmap based on given channel number. 1015 * 1016 * Return: None 1017 */ 1018 static void dfs_random_channel_sel_set_bitmap( 1019 struct wlan_dfs *dfs, 1020 struct chan_bonding_bitmap *bitmap, 1021 uint8_t channel) 1022 { 1023 int i = 0; 1024 int start_chan = 0; 1025 1026 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1027 start_chan = bitmap->chan_bonding_set[i].start_chan; 1028 if (channel >= start_chan && channel <= start_chan + 12) { 1029 bitmap->chan_bonding_set[i].chan_map |= 1030 (1 << ((channel - start_chan) / 1031 DFS_80_NUM_SUB_CHANNEL)); 1032 return; 1033 } 1034 } 1035 1036 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1037 "Channel=%d is not in the bitmap", channel); 1038 } 1039 1040 /** 1041 * dfs_find_ch_with_fallback()- find random channel 1042 * @dfs: Pointer to DFS structure. 1043 * @ch_wd: channel width 1044 * @center_freq_seg1: center frequency of secondary segment. 1045 * @ch_lst: list of available channels. 1046 * @num_ch: number of channels in the list. 1047 * 1048 * Find random channel based on given channel width and channel list, 1049 * fallback to lower width if requested channel width not available. 1050 * 1051 * Return: channel number 1052 */ 1053 static uint8_t dfs_find_ch_with_fallback( 1054 struct wlan_dfs *dfs, 1055 uint8_t *ch_wd, 1056 uint8_t *center_freq_seg1, 1057 uint8_t *ch_lst, 1058 uint32_t num_ch) 1059 { 1060 bool flag = false; 1061 uint32_t rand_byte = 0; 1062 struct chan_bonding_bitmap ch_map = { { {0} } }; 1063 uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0; 1064 uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; 1065 uint8_t final_lst[DFS_MAX_NUM_CHAN] = {0}; 1066 1067 /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ 1068 ch_map.chan_bonding_set[0].start_chan = 36; 1069 ch_map.chan_bonding_set[1].start_chan = 52; 1070 ch_map.chan_bonding_set[2].start_chan = 100; 1071 ch_map.chan_bonding_set[3].start_chan = 116; 1072 ch_map.chan_bonding_set[4].start_chan = 132; 1073 ch_map.chan_bonding_set[5].start_chan = 149; 1074 1075 for (i = 0; i < num_ch; i++) { 1076 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1077 "channel = %d added to bitmap", ch_lst[i]); 1078 dfs_random_channel_sel_set_bitmap(dfs, &ch_map, ch_lst[i]); 1079 } 1080 1081 /* populate available channel list from bitmap */ 1082 final_cnt = dfs_populate_available_channels(dfs, &ch_map, 1083 *ch_wd, final_lst); 1084 1085 /* If no valid ch bonding found, fallback */ 1086 if (final_cnt == 0) { 1087 if ((*ch_wd == DFS_CH_WIDTH_160MHZ) || 1088 (*ch_wd == DFS_CH_WIDTH_80P80MHZ) || 1089 (*ch_wd == DFS_CH_WIDTH_80MHZ)) { 1090 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1091 "from [%d] to 40Mhz", *ch_wd); 1092 *ch_wd = DFS_CH_WIDTH_40MHZ; 1093 } else if (*ch_wd == DFS_CH_WIDTH_40MHZ) { 1094 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1095 "from 40Mhz to 20MHz"); 1096 *ch_wd = DFS_CH_WIDTH_20MHZ; 1097 } 1098 return 0; 1099 } 1100 1101 /* ch count should be > 8 to switch new channel in 160Mhz band */ 1102 if (((*ch_wd == DFS_CH_WIDTH_160MHZ) || 1103 (*ch_wd == DFS_CH_WIDTH_80P80MHZ)) && 1104 (final_cnt < DFS_MAX_20M_SUB_CH)) { 1105 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1106 "from [%d] to 80Mhz", *ch_wd); 1107 *ch_wd = DFS_CH_WIDTH_80MHZ; 1108 return 0; 1109 } 1110 1111 if (*ch_wd == DFS_CH_WIDTH_160MHZ) { 1112 /* 1113 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128 1114 * and all the channels in these blocks are continuous 1115 * and separated by 4Mhz. 1116 */ 1117 for (i = 1; ((i < final_cnt)); i++) { 1118 if ((final_lst[i] - final_lst[i-1]) == 1119 DFS_NEXT_5GHZ_CHANNEL) 1120 count++; 1121 else 1122 count = 0; 1123 if (count == DFS_MAX_20M_SUB_CH - 1) { 1124 flag = true; 1125 new_160_start_ch = final_lst[i - count]; 1126 break; 1127 } 1128 } 1129 } else if (*ch_wd == DFS_CH_WIDTH_80P80MHZ) { 1130 flag = true; 1131 } 1132 1133 if ((flag == false) && (*ch_wd > DFS_CH_WIDTH_80MHZ)) { 1134 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1135 "from [%d] to 80Mhz", *ch_wd); 1136 *ch_wd = DFS_CH_WIDTH_80MHZ; 1137 return 0; 1138 } 1139 1140 if (*ch_wd == DFS_CH_WIDTH_160MHZ) { 1141 get_random_bytes((uint8_t *)&rand_byte, 1); 1142 rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) 1143 % DFS_MAX_20M_SUB_CH; 1144 target_channel = new_160_start_ch + (rand_byte * 1145 DFS_80_NUM_SUB_CHANNEL); 1146 } else if (*ch_wd == DFS_CH_WIDTH_80P80MHZ) { 1147 get_random_bytes((uint8_t *)&rand_byte, 1); 1148 index = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1149 final_cnt; 1150 target_channel = final_lst[index]; 1151 index -= (index % DFS_80_NUM_SUB_CHANNEL); 1152 primary_seg_start_ch = final_lst[index]; 1153 1154 /* reset channels associate with primary 80Mhz */ 1155 for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++) 1156 final_lst[i + index] = 0; 1157 /* select and calculate center freq for secondary segment */ 1158 for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) { 1159 if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] && 1160 (abs(primary_seg_start_ch - 1161 final_lst[i * DFS_80_NUM_SUB_CHANNEL]) > 1162 (DFS_MAX_20M_SUB_CH * 2))) { 1163 sec_seg_ch = 1164 final_lst[i * DFS_80_NUM_SUB_CHANNEL] + 1165 DFS_80MHZ_START_CENTER_CH_DIFF; 1166 break; 1167 } 1168 } 1169 1170 if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH)) 1171 *ch_wd = DFS_CH_WIDTH_160MHZ; 1172 else if (!sec_seg_ch) 1173 *ch_wd = DFS_CH_WIDTH_80MHZ; 1174 1175 *center_freq_seg1 = sec_seg_ch; 1176 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1177 "Center frequency seg1 = %d", sec_seg_ch); 1178 } else { 1179 target_channel = dfs_get_rand_from_lst(dfs, 1180 final_lst, final_cnt); 1181 } 1182 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1183 "target channel = %d", target_channel); 1184 1185 return target_channel; 1186 } 1187 1188 /** 1189 * dfs_remove_cur_ch_from_list()- remove current operating channels 1190 * @ch_list: list of avilable channel list 1191 * @ch_cnt: number of channels. 1192 * @ch_wd: channel width. 1193 * @cur_chan: current channel. 1194 * 1195 * Remove current channels from list of available channels. 1196 * 1197 * Return: channel number 1198 */ 1199 static void dfs_remove_cur_ch_from_list( 1200 struct dfs_channel *ch_list, 1201 uint32_t *ch_cnt, 1202 uint8_t *ch_wd, 1203 struct dfs_channel *cur_chan) 1204 { 1205 /* TODO */ 1206 return; 1207 } 1208 1209 bool dfs_freq_is_in_nol(struct wlan_dfs *dfs, uint32_t freq) 1210 { 1211 struct dfs_nolelem *nol; 1212 1213 if (!dfs) { 1214 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "null dfs"); 1215 return false; 1216 } 1217 1218 nol = dfs->dfs_nol; 1219 while (nol) { 1220 if (freq == nol->nol_freq) { 1221 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1222 "%d is in nol", freq); 1223 return true; 1224 } 1225 nol = nol->nol_next; 1226 } 1227 1228 return false; 1229 } 1230 1231 /** 1232 * dfs_apply_rules()- prepare channel list based on flags 1233 * @dfs: dfs handler 1234 * @flags: channel flags 1235 * @random_chan_list: output channel list 1236 * @random_chan_cnt: output channel count 1237 * @ch_list: input channel list 1238 * @ch_cnt: input channel count 1239 * @dfs_region: dfs region 1240 * @acs_info: acs channel range information 1241 * 1242 * prepare channel list based on flags 1243 * 1244 * Return: None 1245 */ 1246 static void dfs_apply_rules(struct wlan_dfs *dfs, 1247 uint32_t flags, 1248 uint8_t *random_chan_list, 1249 uint32_t *random_chan_cnt, 1250 struct dfs_channel *ch_list, 1251 uint32_t ch_cnt, 1252 uint8_t dfs_region, 1253 struct dfs_acs_info *acs_info) 1254 { 1255 struct dfs_channel *chan; 1256 uint16_t flag_no_weather = 0; 1257 uint16_t flag_no_lower_5g = 0; 1258 uint16_t flag_no_upper_5g = 0; 1259 uint16_t flag_no_dfs_chan = 0; 1260 uint16_t flag_no_2g_chan = 0; 1261 uint16_t flag_no_5g_chan = 0; 1262 int i; 1263 1264 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags); 1265 flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? 1266 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 1267 1268 flag_no_lower_5g = (dfs_region == DFS_MKK_REGION_VAL) ? 1269 flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH : 0; 1270 1271 flag_no_upper_5g = (dfs_region == DFS_MKK_REGION_VAL) ? 1272 flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH : 0; 1273 1274 flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH; 1275 flag_no_2g_chan = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH; 1276 flag_no_5g_chan = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH; 1277 1278 for (i = 0; i < ch_cnt; i++) { 1279 chan = &ch_list[i]; 1280 1281 if ((chan->dfs_ch_ieee == 0) || 1282 (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) { 1283 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1284 "invalid channel %d", 1285 chan->dfs_ch_ieee); 1286 continue; 1287 } 1288 1289 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { 1290 /* TODO : Skip all HT20 channels in the given mode */ 1291 if (chan->dfs_ch_ieee == 1292 dfs->dfs_curchan->dfs_ch_ieee) { 1293 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1294 "skip %d current operating channel\n", 1295 chan->dfs_ch_ieee); 1296 continue; 1297 } 1298 } 1299 1300 if (acs_info && (acs_info->acs_mode == 1) && 1301 ((chan->dfs_ch_ieee < acs_info->start_ch) || 1302 (chan->dfs_ch_ieee > acs_info->end_ch))) { 1303 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1304 "skip ch %d not in acs range (%d-%d)", 1305 chan->dfs_ch_ieee, acs_info->start_ch, 1306 acs_info->end_ch); 1307 continue; 1308 1309 } 1310 1311 if (flag_no_2g_chan && 1312 chan->dfs_ch_ieee <= DFS_MAX_24GHZ_CHANNEL) { 1313 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1314 "skip 2.4 GHz channel=%d", 1315 chan->dfs_ch_ieee); 1316 continue; 1317 } 1318 1319 if (flag_no_5g_chan && 1320 chan->dfs_ch_ieee > DFS_MAX_24GHZ_CHANNEL) { 1321 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1322 "skip 5 GHz channel=%d", 1323 chan->dfs_ch_ieee); 1324 continue; 1325 } 1326 1327 if (flag_no_weather) { 1328 if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) { 1329 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1330 "skip weather channel=%d", 1331 chan->dfs_ch_ieee); 1332 continue; 1333 } 1334 } 1335 1336 if (flag_no_lower_5g && 1337 DFS_IS_CHAN_JAPAN_INDOOR(chan->dfs_ch_ieee)) { 1338 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1339 "skip indoor channel=%d", 1340 chan->dfs_ch_ieee); 1341 continue; 1342 } 1343 1344 if (flag_no_upper_5g && 1345 DFS_IS_CHAN_JAPAN_OUTDOOR(chan->dfs_ch_ieee)) { 1346 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1347 "skip outdoor channel=%d", 1348 chan->dfs_ch_ieee); 1349 continue; 1350 } 1351 1352 if (flag_no_dfs_chan && 1353 (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) { 1354 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1355 "skip dfs channel=%d", 1356 chan->dfs_ch_ieee); 1357 continue; 1358 } 1359 1360 if (dfs_freq_is_in_nol(dfs, chan->dfs_ch_freq)) { 1361 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1362 "skip nol channel=%d", 1363 chan->dfs_ch_ieee); 1364 continue; 1365 } 1366 1367 random_chan_list[*random_chan_cnt] = chan->dfs_ch_ieee; 1368 *random_chan_cnt += 1; 1369 } 1370 } 1371 1372 uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, 1373 struct dfs_channel *ch_list, 1374 uint32_t ch_cnt, 1375 uint32_t flags, 1376 uint8_t *ch_wd, 1377 struct dfs_channel *cur_chan, 1378 uint8_t dfs_region, 1379 struct dfs_acs_info *acs_info) 1380 { 1381 int i = 0; 1382 uint8_t final_cnt = 0; 1383 uint8_t target_ch = 0; 1384 uint8_t *random_chan_list = NULL; 1385 uint32_t random_chan_cnt = 0; 1386 uint16_t flag_no_weather = 0; 1387 uint8_t *leakage_adjusted_lst; 1388 uint8_t final_lst[NUM_CHANNELS] = {0}; 1389 1390 if (!ch_list || !ch_cnt) { 1391 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1392 "Invalid params %pK, ch_cnt=%d", 1393 ch_list, ch_cnt); 1394 return 0; 1395 } 1396 1397 if (*ch_wd < DFS_CH_WIDTH_20MHZ || *ch_wd > DFS_CH_WIDTH_80P80MHZ) { 1398 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1399 "Invalid ch_wd %d", *ch_wd); 1400 return 0; 1401 } 1402 1403 random_chan_list = qdf_mem_malloc(ch_cnt * sizeof(*random_chan_list)); 1404 if (!random_chan_list) { 1405 dfs_alert(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1406 "Memory allocation failed"); 1407 return 0; 1408 } 1409 1410 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) 1411 dfs_remove_cur_ch_from_list(ch_list, &ch_cnt, ch_wd, cur_chan); 1412 1413 dfs_apply_rules(dfs, flags, random_chan_list, &random_chan_cnt, 1414 ch_list, ch_cnt, dfs_region, acs_info); 1415 1416 flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? 1417 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 1418 1419 /* list adjusted after leakage has been marked */ 1420 leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt); 1421 if (!leakage_adjusted_lst) { 1422 dfs_alert(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1423 "Memory allocation failed"); 1424 qdf_mem_free(random_chan_list); 1425 return 0; 1426 } 1427 1428 do { 1429 qdf_mem_copy(leakage_adjusted_lst, random_chan_list, 1430 random_chan_cnt); 1431 if (QDF_IS_STATUS_ERROR(dfs_mark_leaking_ch(dfs, *ch_wd, 1432 random_chan_cnt, 1433 leakage_adjusted_lst))) { 1434 qdf_mem_free(random_chan_list); 1435 qdf_mem_free(leakage_adjusted_lst); 1436 return 0; 1437 } 1438 1439 if (*ch_wd == DFS_CH_WIDTH_20MHZ) { 1440 /* 1441 * PASS: 3 - from leakage_adjusted_lst, prepare valid 1442 * ch list and use random number from that 1443 */ 1444 for (i = 0; i < random_chan_cnt; i++) { 1445 if (leakage_adjusted_lst[i] == 0) 1446 continue; 1447 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1448 "dfs: Channel=%d added to available list", 1449 leakage_adjusted_lst[i]); 1450 final_lst[final_cnt] = leakage_adjusted_lst[i]; 1451 final_cnt++; 1452 } 1453 target_ch = dfs_get_rand_from_lst( 1454 dfs, final_lst, final_cnt); 1455 break; 1456 } 1457 1458 target_ch = dfs_find_ch_with_fallback(dfs, ch_wd, 1459 &cur_chan->dfs_ch_vhtop_ch_freq_seg2, 1460 leakage_adjusted_lst, 1461 random_chan_cnt); 1462 1463 /* 1464 * When flag_no_weather is set, avoid usage of Adjacent 1465 * weather radar channel in HT40 mode as extension channel 1466 * will be on 5600. 1467 */ 1468 if (flag_no_weather && 1469 (target_ch == 1470 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM) && 1471 (*ch_wd == DFS_CH_WIDTH_40MHZ)) { 1472 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1473 "skip weather adjacent ch=%d\n", 1474 target_ch); 1475 continue; 1476 } 1477 1478 if (target_ch) 1479 break; 1480 } while (true); 1481 1482 qdf_mem_free(random_chan_list); 1483 qdf_mem_free(leakage_adjusted_lst); 1484 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_ch = %d", target_ch); 1485 1486 return target_ch; 1487 } 1488