1 /* 2 * Copyright (c) 2012-2020 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 #include <wlan_reg_services_api.h> 24 #include "../dfs_process_radar_found_ind.h" 25 26 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 27 /* 28 * TODO: At present SAP Channel leakage matrix for ch 144 29 * is not available from system's team. So to play it safe 30 * and avoid crash if channel 144 is request, in following 31 * matix channel 144 is added such that it will cause code 32 * to avoid selecting channel 144. 33 * 34 * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS 35 * PROVIDED BY SYSTEM'S TEAM. 36 */ 37 38 /* channel tx leakage table - ht80 */ 39 struct dfs_matrix_tx_leak_info ht80_chan[] = { 40 {52, 5260, 41 {{36, 5180, 148}, {40, 5200, 199}, 42 {44, 5520, 193}, {48, 5240, 197}, 43 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, 153}, 44 {60, 5300, 137}, {64, 5320, 134}, 45 {100, 5500, 358}, {104, 5520, 350}, 46 {108, 5540, 404}, {112, 5560, 344}, 47 {116, 5580, 424}, {120, 5600, 429}, 48 {124, 5620, 437}, {128, 5640, 435}, 49 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 50 {140, 5700, DFS_TX_LEAKAGE_MAX}, 51 {144, 5720, DFS_TX_LEAKAGE_MIN} 52 } }, 53 54 55 {56, 5280, 56 {{36, 5180, 171}, {40, 5200, 178}, 57 {44, 5220, 171}, {48, 5240, 178}, 58 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 59 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, 280}, 60 {100, 5500, 351}, {104, 5520, 376}, 61 {108, 5540, 362}, {112, 5560, 362}, 62 {116, 5580, 403}, {120, 5600, 397}, 63 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 64 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 65 {140, 5700, DFS_TX_LEAKAGE_MAX}, 66 {144, 5720, DFS_TX_LEAKAGE_MIN} 67 } }, 68 69 {60,5300, 70 {{36, 5180, 156}, {40, 5200, 146}, 71 {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN}, 72 {52, 5260, 180}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 73 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 74 {100, 5500, 376}, {104, 5520, 360}, 75 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 76 {116, 5580, 395}, {120, 5600, 399}, 77 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 78 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 79 {140, 5700, DFS_TX_LEAKAGE_MAX}, 80 {144, 5720, DFS_TX_LEAKAGE_MIN} 81 } }, 82 83 {64, 5320, 84 {{36, 5180, 217}, {40, 5200, 221}, 85 {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN}, 86 {52, 5260, 176}, {56, 5280, 176}, 87 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 88 {100, 5500, 384}, {104, 5520, 390}, 89 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 90 {116, 5580, 375}, {120, 5600, 374}, 91 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 92 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 93 {140, 5700, DFS_TX_LEAKAGE_MAX}, 94 {144, 5720, DFS_TX_LEAKAGE_MIN} 95 } }, 96 97 {100, 5500, 98 {{36, 5180, 357}, {40, 5200, 326}, 99 {44, 5220, 321}, {48, 5240, 326}, 100 {52, 5260, 378}, {56, 5280, 396}, 101 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 102 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 103 {108, 5540, 196}, {112, 5560, 116}, 104 {116, 5580, 166}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 105 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 106 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 107 {140, 5700, DFS_TX_LEAKAGE_MIN}, 108 {144, 5720, DFS_TX_LEAKAGE_MIN} 109 } }, 110 111 {104, 5520, 112 {{36, 5180, 325}, {40, 5200, 325}, 113 {44, 5220, 305}, {48, 5240, 352}, 114 {52, 5260, 411}, {56, 5280, 411}, 115 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 116 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 117 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 460}, 118 {116, 5580, 198}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 119 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 120 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 121 {140, 5700, DFS_TX_LEAKAGE_MIN}, 122 {144, 5720, DFS_TX_LEAKAGE_MIN} 123 } }, 124 125 {108, 5540, 126 {{36,5180, 304}, {40, 5200, 332}, 127 {44, 5220, 310}, {48, 5240, 335}, 128 {52, 5260, 431}, {56, 5280, 391}, 129 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 130 {100, 5500, 280}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 131 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 132 {116, 5580, 185}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 133 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 134 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 135 {140, 5700, DFS_TX_LEAKAGE_MIN}, 136 {144, 5720, DFS_TX_LEAKAGE_MIN} 137 } }, 138 139 {112,5560, 140 {{36, 5180, 327}, {40, 5200, 335}, 141 {44, 5220, 331}, {48, 5240, 345}, 142 {52, 5260, 367}, {56, 5280, 401}, 143 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 144 {100, 5500, 131}, {104, 5520, 132}, 145 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 146 {116, 5580, 189}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 147 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 148 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 149 {140, 5700, DFS_TX_LEAKAGE_MIN}, 150 {144, 5720, DFS_TX_LEAKAGE_MIN} 151 } }, 152 153 {116, 5580, 154 {{36, 5180, 384}, {40, 5200, 372}, 155 {44, 5220, 389}, {48, 5240, 396}, 156 {52, 5260, 348}, {56, 5280, 336}, 157 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 158 {100, 5500, 172}, {104, 5520, 169}, 159 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 160 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 161 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 162 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 163 {140, 5700, DFS_TX_LEAKAGE_MIN}, 164 {144, 5720, DFS_TX_LEAKAGE_MIN} 165 } }, 166 167 {120, 5600, 168 {{36, 5180, 395}, {40, 5200, 419}, 169 {44, 5220, 439}, {48, 5240, 407}, 170 {52, 5260, 321}, {56, 5280, 334}, 171 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 172 {100, 5500, 134}, {104, 5520, 186}, 173 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 174 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 175 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 159}, 176 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 177 {140, 5700, DFS_TX_LEAKAGE_MIN}, 178 {144, 5720, DFS_TX_LEAKAGE_MIN} 179 } }, 180 181 {124, 5620, 182 {{36, 5180, 469}, {40, 5200, 433}, 183 {44, 5220, 434}, {48, 5240, 435}, 184 {52, 5260, 332}, {56, 5280, 345}, 185 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 186 {100, 5500, 146}, {104, 5520, 177}, 187 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 188 {116, 5580, 350}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 189 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 138}, 190 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 191 {140, 5700, DFS_TX_LEAKAGE_MIN}, 192 {144, 5720, DFS_TX_LEAKAGE_MIN} 193 } }, 194 195 {128, 5640, 196 {{36, 5180, 408}, {40, 5200, 434}, 197 {44, 5220, 449}, {48, 5240, 444}, 198 {52, 5260, 341}, {56, 5280, 374}, 199 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 200 {100, 5500, 205}, {104, 5520, 208}, 201 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 202 {116, 5580, 142}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 203 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 204 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 205 {140, 5700, DFS_TX_LEAKAGE_MIN}, 206 {144, 5720, DFS_TX_LEAKAGE_MIN} 207 } }, 208 209 {132, 5660, 210 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, 211 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, 212 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 213 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 214 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 215 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 216 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 217 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 218 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 219 {140, 5700, DFS_TX_LEAKAGE_MIN}, 220 {144, 5720, DFS_TX_LEAKAGE_MIN} 221 } }, 222 223 {136, 5680, 224 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, 225 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, 226 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 227 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 228 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 229 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 230 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 231 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 232 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 233 {140, 5700, DFS_TX_LEAKAGE_MIN}, 234 {144, 5720, DFS_TX_LEAKAGE_MIN} 235 } }, 236 237 {140, 5700, 238 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, 239 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, 240 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 241 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 242 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 243 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 244 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 245 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 246 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 247 {144, 5720, DFS_TX_LEAKAGE_MIN} 248 } }, 249 250 {144, 5720, 251 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, 252 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, 253 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 254 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 255 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 256 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 257 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 258 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 259 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 260 {144, 5720, DFS_TX_LEAKAGE_MIN} 261 } }, 262 }; 263 264 /* channel tx leakage table - ht40 */ 265 struct dfs_matrix_tx_leak_info ht40_chan[] = { 266 {52, 5260, 267 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 268 {44, 5220, 230}, {48, 5240, 230}, 269 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 270 {60, 5300, DFS_TX_LEAKAGE_AUTO_MIN}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN}, 271 {100, 5500, 625}, {104, 5520, 323}, 272 {108, 5540, 646}, {112, 5560, 646}, 273 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 274 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 275 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 276 {140, 5700, DFS_TX_LEAKAGE_MAX}, 277 {144, 5720, DFS_TX_LEAKAGE_MIN} 278 } }, 279 280 {56, 5280, 281 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 282 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, 283 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 284 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 285 {100, 5500, 611}, {104, 5520, 611}, 286 {108, 5540, 617}, {112, 5560, 617}, 287 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 288 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 289 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 290 {140, 5700, DFS_TX_LEAKAGE_MAX}, 291 {144, 5720, DFS_TX_LEAKAGE_MIN} 292 } }, 293 294 {60, 5300, 295 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 296 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, 297 {52, 5260, 190}, {56, 5280, 190}, 298 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 299 {100, 5500, 608}, {104, 5520, 608}, 300 {108, 5540, 623}, {112, 5560, 623}, 301 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 302 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 303 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 304 {140, 5700, DFS_TX_LEAKAGE_MAX}, 305 {144, 5720, DFS_TX_LEAKAGE_MIN} 306 } }, 307 308 {64, 5320, 309 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 310 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, 311 {52, 5260, 295}, {56, 5280, 295}, 312 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 313 {100, 5500, 594}, {104, 5520, 594}, 314 {108, 5540, 625}, {112, 5560, 625}, 315 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 316 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 317 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 318 {140, 5700, DFS_TX_LEAKAGE_MAX}, 319 {144, 5720, DFS_TX_LEAKAGE_MIN} 320 } }, 321 322 {100, 5500, 323 {{36, 5180, 618}, {40, 5200, 618}, 324 {44, 5220, 604}, {48, 5240, 604}, 325 {52, 5260, 596}, {56, 5280, 596}, 326 {60, 5300, 584}, {64, 5320, 584}, 327 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 328 {108, 5540, 299}, {112, 5560, 299}, 329 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 330 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 331 {132, 5660, 538}, {136,5680, 538}, 332 {140, 5700, 598}, 333 {144, 5720, DFS_TX_LEAKAGE_MIN} 334 } }, 335 336 {104, 5520, 337 {{36, 5180, 636}, {40, 5200, 636}, 338 {44, 5220, 601}, {48, 5240, 601}, 339 {52, 5260, 616}, {56, 5280, 616}, 340 {60, 5300, 584}, {64, 5320, 584}, 341 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 342 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 343 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 344 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 345 {132, 5660, 553}, {136, 5680, 553}, 346 {140, 5700, 568}, 347 {144, 5720, DFS_TX_LEAKAGE_MIN} 348 } }, 349 350 {108, 5540, 351 {{36, 5180, 600}, {40, 5200, 600}, 352 {44, 5220, 627}, {48, 5240, 627}, 353 {52, 5260, 611}, {56, 5280, 611}, 354 {60, 5300, 611}, {64, 5320, 611}, 355 {100, 5500, 214}, {104, 5520, 214}, 356 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 357 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 358 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 359 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 360 {140, 5700, 534}, 361 {144, 5720, DFS_TX_LEAKAGE_MIN} 362 } }, 363 364 {112, 5560, 365 {{36, 5180, 645}, {40, 5200, 645}, 366 {44, 5220, 641}, {48, 5240, 641}, 367 {52, 5260, 618}, {56, 5280, 618}, 368 {60, 5300, 612}, {64, 5320, 612}, 369 {100, 5500, 293}, {104, 5520, 293}, 370 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 371 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 372 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 373 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 374 {140, 5700, 521}, 375 {144, 5720, DFS_TX_LEAKAGE_MIN} 376 } }, 377 378 {116, 5580, 379 {{36, 5180, 661}, {40, 5200, 661}, 380 {44, 5220, 624}, {48, 5240, 624}, 381 {52, 5260, 634}, {56, 5280, 634}, 382 {60, 5300, 611}, {64, 5320, 611}, 383 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, 384 {108, 5540, 217}, {112, 5560, 217}, 385 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 386 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 387 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 388 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, 389 {144, 5720, DFS_TX_LEAKAGE_MIN} 390 } }, 391 392 {120, 5600, 393 {{36, 5180, 667}, {40, 5200, 667}, 394 {44, 5220, 645}, {48, 5240, 645}, 395 {52, 5260, 633}, {56, 5280, 633}, 396 {60, 5300, 619}, {64, 5320, 619}, 397 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, 398 {108, 5540, 291}, {112, 5560, 291}, 399 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 400 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 401 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 402 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, 403 {144, 5720, DFS_TX_LEAKAGE_MIN} 404 } }, 405 406 {124, 5620, 407 {{36, 5180, 676}, {40, 5200, 676}, 408 {44, 5220, 668}, {48, 5240, 668}, 409 {52, 5260, 595}, {56, 5280, 595}, 410 {60, 5300, 622}, {64, 5320, 622}, 411 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, 412 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 413 {116, 5580, 225}, {120, 5600, 225}, 414 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 415 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 416 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, 417 {144, 5720, DFS_TX_LEAKAGE_MIN} 418 } }, 419 420 {128, 5640, 421 {{36, 5180, 678}, {40, 5200, 678}, 422 {44, 5220, 664}, {48, 5240, 664}, 423 {52, 5260, 651}, {56, 5280, 651}, 424 {60, 5300, 643}, {64, 5320, 643}, 425 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, 426 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 427 {116, 5580, 293}, {120, 5600, 293}, 428 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 429 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 430 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, 431 {144, 5720, DFS_TX_LEAKAGE_MIN} 432 } }, 433 434 {132, 5660, 435 {{36, 5180, 689}, {40, 5200, 689}, 436 {44, 5220, 669}, {48, 5240, 669}, 437 {52, 5260, 662}, {56, 5280, 662}, 438 {60, 5300, 609}, {64, 5320, 609}, 439 {100, 5500, 538}, {104, 5520, 538}, 440 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 441 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 442 {124, 5620, 247}, {128, 5640, 247}, 443 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 444 {140, 5700, DFS_TX_LEAKAGE_MIN}, 445 {144, 5720, DFS_TX_LEAKAGE_MIN} 446 } }, 447 448 {136, 5680, 449 {{36, 5180, 703}, {40, 5200, 703}, 450 {44, 5220, 688}, {48, 5240, DFS_TX_LEAKAGE_MIN}, 451 {52, 5260, 671}, {56, 5280, 671}, 452 {60, 5300, 658}, {64, 5320, 658}, 453 {100, 5500, 504}, {104, 5520, 504}, 454 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 455 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 456 {124, 5620, 289}, {128, 5640, 289}, 457 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 458 {140, 5700, DFS_TX_LEAKAGE_MIN}, 459 {144, 5720, DFS_TX_LEAKAGE_MIN} 460 } }, 461 462 {140, 5700, 463 {{36, 5180, 695}, {40, 5200, 695}, 464 {44, 5220, 684}, {48, 5240, 684}, 465 {52, 5260, 664}, {56, 5280, 664}, 466 {60, 5300, 658}, {64, 5320, 658}, 467 {100, 5500, 601}, {104, 5520, 601}, 468 {108, 5540, 545}, {112, 5560, 545}, 469 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 470 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 471 {132, 5660, 262}, {136, 5680, 262}, 472 {140, 5700, DFS_TX_LEAKAGE_MIN}, 473 {144, 5720, DFS_TX_LEAKAGE_MIN} 474 } }, 475 476 {144, 5720, 477 {{36, 5180, 695}, {40, 5200, 695}, 478 {44, 5220, 684}, {48, 5240, 684}, 479 {52, 5260, 664}, {56, 5280, 664}, 480 {60, 5300, 658}, {64, 5320, 658}, 481 {100, 5500, 601}, {104, 5520, 601}, 482 {108, 5540, 545}, {112, 5560, 545}, 483 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 484 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 485 {132, 5660, 262}, {136, 5680, 262}, 486 {140, 5700, DFS_TX_LEAKAGE_MIN}, 487 {144, 5720, DFS_TX_LEAKAGE_MIN} 488 } }, 489 }; 490 491 /* channel tx leakage table - ht20 */ 492 struct dfs_matrix_tx_leak_info ht20_chan[] = { 493 {52, 5260, 494 {{36, 5180,DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, 286}, 495 {44, 5220, 225}, {48,5240, 121}, 496 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 497 {60, 5300, 300}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN}, 498 {100, 5500, 637}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 499 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 500 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 501 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 502 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 503 {140, 5700, DFS_TX_LEAKAGE_MAX}, 504 {144, 5720, DFS_TX_LEAKAGE_MIN} 505 } }, 506 507 {56, 5280, 508 {{36, 5180, 468}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 509 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, 206}, 510 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 511 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 512 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 513 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 514 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 515 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 516 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 517 {140, 5700, DFS_TX_LEAKAGE_MAX}, 518 {144, 5720, DFS_TX_LEAKAGE_MIN} 519 } }, 520 521 {60, 5300, 522 {{36, 5180, 507}, {40, 5200, 440}, 523 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48,5240, 313}, 524 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 525 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 526 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 527 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 528 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 529 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 530 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 531 {140, 5700, DFS_TX_LEAKAGE_MAX}, 532 {144, 5720, DFS_TX_LEAKAGE_MIN} 533 } }, 534 535 {64, 5320 , 536 {{36, 5180, 516}, {40, 5200, 520}, 537 {44, 5220, 506}, {48, 5240,DFS_TX_LEAKAGE_AUTO_MIN}, 538 {52, 5260, 301}, {56, 5280, 258}, 539 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 540 {100, 5500, 620}, {104, 5520, 617}, 541 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 542 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 543 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 544 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 545 {140, 5700, DFS_TX_LEAKAGE_MAX}, 546 {144, 5720, DFS_TX_LEAKAGE_MIN} 547 } }, 548 549 {100, 5500, 550 {{36, 5180, 616}, {40, 5200, 601}, 551 {44, 5220, 604}, {48, 5240, 589}, 552 {52, 5260, 612}, {56, 5280, 592}, 553 {60, 5300, 590}, {64, 5320, 582}, 554 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, 131}, 555 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 556 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, 522}, 557 {124, 5620, 571}, {128, 5640, 589}, 558 {132, 5660, 593}, {136, 5680, 598}, 559 {140, 5700, 594}, 560 {144, 5720, DFS_TX_LEAKAGE_MIN}, 561 } }, 562 563 {104, 5520, 564 {{36, 5180, 622}, {40, 5200, 624}, 565 {44, 5220, 618}, {48, 5240, 610}, 566 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 567 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 568 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 569 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 463}, 570 {116, 5580, 483}, {120, 5600, 503}, 571 {124, 5620, 523}, {128, 5640, 565}, 572 {132, 5660, 570}, {136, 5680, 588}, 573 {140, 5700, 585}, 574 {144, 5720, DFS_TX_LEAKAGE_MIN}, 575 } }, 576 577 {108, 5540, 578 {{36, 5180, 620}, {40, 5200, 638}, 579 {44, 5220, 611}, {48, 5240, 614}, 580 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 581 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 582 {100, 5500, 477}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 583 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 584 {116, 5580, 477}, {120, 5600, 497}, 585 {124, 5620, 517}, {128, 5640, 537}, 586 {132, 5660, 557}, {136, 5680, 577}, 587 {140, 5700, 603}, 588 {144, 5720, DFS_TX_LEAKAGE_MIN}, 589 } }, 590 591 {112, 5560, 592 {{36, 5180, 636}, {40, 5200, 623}, 593 {44, 5220, 638}, {48, 5240, 628}, 594 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 595 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, 606}, 596 {100, 5500, 501}, {104, 5520, 481}, 597 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 598 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, 481}, 599 {124, 5620, 501}, {128, 5640, 421}, 600 {132, 5660, 541}, {136, 5680, 561}, 601 {140, 5700, 583}, 602 {144, 5720, DFS_TX_LEAKAGE_MIN}, 603 } }, 604 605 {116, 5580, 606 {{36, 5180, 646}, {40, 5200, 648}, 607 {44, 5220, 633}, {48, 5240, 634}, 608 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 609 {60, 5300, 615}, {64, 5320, 594}, 610 {100, 5500, 575}, {104, 5520, 554}, 611 {108, 5540, 534}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 612 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 613 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 614 {132, 5660, 534}, {136, 5680, 554}, 615 {140, 5700, 574}, 616 {144, 5720, DFS_TX_LEAKAGE_MIN}, 617 } }, 618 619 {120, 5600, 620 {{36, 5180, 643}, {40, 5200, 649}, 621 {44, 5220, 654}, {48, 5240, 629}, 622 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, 621}, 623 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 624 {100, 5500, 565}, {104, 5520, 545}, 625 {108, 5540, 525}, {112, 5560, 505}, 626 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 627 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 505}, 628 {132, 5660, 525}, {136, 5680, 545}, 629 {140, 5700, 565}, 630 {144, 5720, DFS_TX_LEAKAGE_MIN}, 631 } }, 632 633 {124, 5620, 634 {{36, 5180, 638}, {40, 5200, 657}, 635 {44, 5220, 663}, {48, 5240, 649}, 636 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 637 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 638 {100, 5500, 581}, {104, 5520, 561}, 639 {108, 5540, 541}, {112, 5560, 521}, 640 {116, 5580, 499}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 641 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 642 {132, 5660, 499}, {136, 5680, 519}, 643 {140, 5700, 539}, 644 {144, 5720, DFS_TX_LEAKAGE_MIN} 645 } }, 646 647 {128, 5640, 648 {{36, 5180, 651}, {40, 5200, 651}, 649 {44, 5220, 674}, {48, 5240, 640}, 650 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 651 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 652 {100, 5500, 603}, {104, 5520, 560}, 653 {108, 5540, 540}, {112, 5560, 520}, 654 {116, 5580, 499}, {120, 5600, 479}, 655 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 656 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, 479}, 657 {140, 5700, 499}, 658 {144, 5720, DFS_TX_LEAKAGE_MIN} 659 } }, 660 661 {132, 5660, 662 {{36, 5180, 643}, {40, 5200, 668}, 663 {44, 5220, 651}, {48, 5240, 657}, 664 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 665 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 666 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, 602}, 667 {108, 5540, 578}, {112,5560, 570}, 668 {116, 5580, 550}, {120, 5600, 530}, 669 {124, 5620, 510}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 670 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 671 {140, 5700, 490}, 672 {144, 5720, DFS_TX_LEAKAGE_MIN} 673 } }, 674 675 {136,5680, 676 {{36, 5180, 654}, {40, 5200, 667}, 677 {44, 5220, 666}, {48, 5240, 642}, 678 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 679 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 680 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 681 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 596}, 682 {116, 5580, 555}, {120, 5600, 535}, 683 {124, 5620, 515}, {128, 5640, 495}, 684 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 685 {140, 5700, DFS_TX_LEAKAGE_MIN}, 686 {144, 5720, DFS_TX_LEAKAGE_MIN} 687 } }, 688 689 {140,5700, 690 {{36, 5180, 679}, {40, 5200, 673}, 691 {44, 5220, 667}, {48, 5240, 656}, 692 {52, 5260, 634}, {56, 5280, 663}, 693 {60, 5300, 662}, {64, 5320, 660}, 694 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 695 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590}, 696 {116, 5580, 573}, {120, 5600, 553}, 697 {124, 5620, 533}, {128, 5640, 513}, 698 {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 699 {140, 5700, DFS_TX_LEAKAGE_MIN}, 700 {144, 5720, DFS_TX_LEAKAGE_MIN} 701 } }, 702 703 {144,5720, 704 {{36, 5180, 679}, {40, 5200, 673}, 705 {44, 5220, 667}, {48, 5240, 656}, 706 {52, 5260, 634}, {56, 5280, 663}, 707 {60, 5300, 662}, {64, 5320, 660}, 708 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 709 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590}, 710 {116, 5580, 573}, {120, 5600, 553}, 711 {124, 5620, 533}, {128, 5640, 513}, 712 {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 713 {140, 5700, DFS_TX_LEAKAGE_MIN}, 714 {144, 5720, DFS_TX_LEAKAGE_MIN} 715 } }, 716 }; 717 718 /* 719 * dfs_find_target_channel_in_channel_matrix() - finds the leakage matrix 720 * @ch_width: target channel width 721 * @NOL_channel: the NOL channel whose leakage matrix is required 722 * @pTarget_chnl_mtrx: pointer to target channel matrix returned. 723 * 724 * This function gives the leakage matrix for given NOL channel and ch_width 725 * 726 * Return: TRUE or FALSE 727 */ 728 #ifdef CONFIG_CHAN_NUM_API 729 static bool 730 dfs_find_target_channel_in_channel_matrix(enum phy_ch_width ch_width, 731 uint8_t NOL_channel, 732 struct dfs_tx_leak_info **pTarget_chnl_mtrx) 733 { 734 struct dfs_tx_leak_info *target_chan_matrix = NULL; 735 struct dfs_matrix_tx_leak_info *pchan_matrix = NULL; 736 uint32_t nchan_matrix; 737 int i = 0; 738 739 switch (ch_width) { 740 case CH_WIDTH_20MHZ: 741 /* HT20 */ 742 pchan_matrix = ht20_chan; 743 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 744 break; 745 case CH_WIDTH_40MHZ: 746 /* HT40 */ 747 pchan_matrix = ht40_chan; 748 nchan_matrix = QDF_ARRAY_SIZE(ht40_chan); 749 break; 750 case CH_WIDTH_80MHZ: 751 /* HT80 */ 752 pchan_matrix = ht80_chan; 753 nchan_matrix = QDF_ARRAY_SIZE(ht80_chan); 754 break; 755 default: 756 /* handle exception and fall back to HT20 table */ 757 pchan_matrix = ht20_chan; 758 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 759 break; 760 } 761 762 for (i = 0; i < nchan_matrix; i++) { 763 /* find the SAP channel to map the leakage matrix */ 764 if (NOL_channel == pchan_matrix[i].channel) { 765 target_chan_matrix = pchan_matrix[i].chan_matrix; 766 break; 767 } 768 } 769 770 if (!target_chan_matrix) { 771 return false; 772 } else { 773 *pTarget_chnl_mtrx = target_chan_matrix; 774 return true; 775 } 776 } 777 #endif 778 779 /* 780 * dfs_find_target_channel_in_channel_matrix_for_freq() - finds the leakage 781 * matrix. 782 * @chan_width: target channel width 783 * @nol_channel: the NOL channel frequency whose leakage matrix is required 784 * @pTarget_chnl_mtrx: pointer to target channel matrix returned. 785 * 786 * This function gives the leakage matrix for given NOL channel and ch_width 787 * 788 * Return: TRUE or FALSE 789 */ 790 #ifdef CONFIG_CHAN_FREQ_API 791 static bool 792 dfs_find_target_channel_in_channel_matrix_for_freq(enum phy_ch_width chan_width, 793 uint16_t nol_freq, 794 struct dfs_tx_leak_info 795 **pTarget_chnl_mtrx) 796 { 797 struct dfs_tx_leak_info *target_chan_matrix = NULL; 798 struct dfs_matrix_tx_leak_info *pchan_matrix = NULL; 799 uint32_t nchan_matrix; 800 int i = 0; 801 802 switch (chan_width) { 803 case CH_WIDTH_20MHZ: 804 /* HT20 */ 805 pchan_matrix = ht20_chan; 806 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 807 break; 808 case CH_WIDTH_40MHZ: 809 /* HT40 */ 810 pchan_matrix = ht40_chan; 811 nchan_matrix = QDF_ARRAY_SIZE(ht40_chan); 812 break; 813 case CH_WIDTH_80MHZ: 814 /* HT80 */ 815 pchan_matrix = ht80_chan; 816 nchan_matrix = QDF_ARRAY_SIZE(ht80_chan); 817 break; 818 default: 819 /* handle exception and fall back to HT20 table */ 820 pchan_matrix = ht20_chan; 821 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 822 break; 823 } 824 825 for (i = 0; i < nchan_matrix; i++) { 826 /* find the SAP channel to map the leakage matrix */ 827 if (nol_freq == pchan_matrix[i].channel_freq) { 828 target_chan_matrix = pchan_matrix[i].chan_matrix; 829 break; 830 } 831 } 832 833 if (!target_chan_matrix) { 834 return false; 835 } else { 836 *pTarget_chnl_mtrx = target_chan_matrix; 837 return true; 838 } 839 } 840 #endif 841 842 #ifdef CONFIG_CHAN_NUM_API 843 QDF_STATUS 844 dfs_mark_leaking_ch(struct wlan_dfs *dfs, 845 enum phy_ch_width ch_width, 846 uint8_t temp_ch_lst_sz, 847 uint8_t *temp_ch_lst) 848 { 849 struct dfs_tx_leak_info *target_chan_matrix = NULL; 850 uint32_t num_channel = (CHAN_ENUM_5720 - CHAN_ENUM_5180) + 1; 851 uint32_t j = 0; 852 uint32_t k = 0; 853 uint8_t dfs_nol_channel; 854 struct dfs_nolelem *nol; 855 856 nol = dfs->dfs_nol; 857 while (nol) { 858 dfs_nol_channel = wlan_reg_freq_to_chan(dfs->dfs_pdev_obj, 859 nol->nol_freq); 860 if (false == dfs_find_target_channel_in_channel_matrix( 861 ch_width, dfs_nol_channel, 862 &target_chan_matrix)) { 863 /* 864 * should never happen, we should always find a table 865 * here, if we don't, need a fix here! 866 */ 867 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 868 "Couldn't find target channel matrix!"); 869 QDF_ASSERT(0); 870 return QDF_STATUS_E_FAILURE; 871 } 872 /* 873 * following is based on assumption that both temp_ch_lst 874 * and target channel matrix are in increasing order of 875 * ch_id 876 */ 877 for (j = 0, k = 0; j < temp_ch_lst_sz && k < num_channel;) { 878 if (temp_ch_lst[j] == 0) { 879 j++; 880 continue; 881 } 882 if (target_chan_matrix[k].leak_chan != temp_ch_lst[j]) { 883 k++; 884 continue; 885 } 886 /* 887 * check leakage from candidate channel 888 * to NOL channel 889 */ 890 if (target_chan_matrix[k].leak_lvl <= 891 dfs->tx_leakage_threshold) { 892 /* 893 * candidate channel will have 894 * bad leakage in NOL channel, 895 * remove from temp list 896 */ 897 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 898 "dfs: channel: %d will have bad leakage due to channel: %d\n", 899 dfs_nol_channel, temp_ch_lst[j]); 900 temp_ch_lst[j] = 0; 901 } 902 j++; 903 k++; 904 } 905 nol = nol->nol_next; 906 } /* end of loop that selects each NOL */ 907 908 return QDF_STATUS_SUCCESS; 909 } 910 #endif 911 912 #ifdef CONFIG_CHAN_FREQ_API 913 914 #ifdef CONFIG_BAND_6GHZ 915 #define END_CHAN_INDEX CHAN_ENUM_7115 916 #else 917 #define END_CHAN_INDEX CHAN_ENUM_5720 918 #endif 919 920 #define START_CHAN_INDEX CHAN_ENUM_5180 921 QDF_STATUS 922 dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, 923 enum phy_ch_width ch_width, 924 uint8_t temp_chan_lst_sz, 925 uint16_t *temp_freq_lst) 926 { 927 struct dfs_tx_leak_info *target_chan_matrix = NULL; 928 uint32_t num_channel = (END_CHAN_INDEX - START_CHAN_INDEX) + 1; 929 uint32_t j = 0; 930 uint32_t k = 0; 931 struct dfs_nolelem *nol; 932 933 nol = dfs->dfs_nol; 934 while (nol) { 935 if (false == dfs_find_target_channel_in_channel_matrix_for_freq( 936 ch_width, nol->nol_freq, 937 &target_chan_matrix)) { 938 /* 939 * should never happen, we should always find a table 940 * here, if we don't, need a fix here! 941 */ 942 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 943 "Couldn't find target channel matrix!"); 944 QDF_ASSERT(0); 945 return QDF_STATUS_E_FAILURE; 946 } 947 /* 948 * following is based on assumption that both temp_freq_lst 949 * and target channel matrix are in increasing order of 950 * ch_id 951 */ 952 for (j = 0, k = 0; j < temp_chan_lst_sz && k < num_channel;) { 953 if (temp_freq_lst[j] == 0) { 954 j++; 955 continue; 956 } 957 if (target_chan_matrix[k].leak_chan_freq != 958 temp_freq_lst[j]) { 959 k++; 960 continue; 961 } 962 /* 963 * check leakage from candidate channel 964 * to NOL channel 965 */ 966 if (target_chan_matrix[k].leak_lvl <= 967 dfs->tx_leakage_threshold) { 968 /* 969 * candidate channel will have 970 * bad leakage in NOL channel, 971 * remove from temp list 972 */ 973 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 974 "dfs: channel: %d will have bad leakage due to channel: %d\n", 975 nol->nol_freq, temp_freq_lst[j]); 976 temp_freq_lst[j] = 0; 977 } 978 j++; 979 k++; 980 } 981 nol = nol->nol_next; 982 } /* end of loop that selects each NOL */ 983 984 return QDF_STATUS_SUCCESS; 985 } 986 #endif 987 #else 988 #ifdef CONFIG_CHAN_NUM_API 989 QDF_STATUS 990 dfs_mark_leaking_ch(struct wlan_dfs *dfs, 991 enum phy_ch_width ch_width, 992 uint8_t temp_ch_lst_sz, 993 uint8_t *temp_ch_lst) 994 { 995 return QDF_STATUS_SUCCESS; 996 } 997 #endif 998 #ifdef CONFIG_CHAN_FREQ_API 999 QDF_STATUS 1000 dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, 1001 enum phy_ch_width ch_width, 1002 uint8_t temp_chan_lst_sz, 1003 uint16_t *temp_freq_lst) 1004 { 1005 return QDF_STATUS_SUCCESS; 1006 } 1007 #endif 1008 #endif 1009 1010 /** 1011 * dfs_populate_80mhz_available_channels()- Populate channels for 80MHz using 1012 * bitmap 1013 * @dfs: Pointer to DFS structure. 1014 * @bitmap: bitmap 1015 * @avail_freq_list: prepared channel list 1016 * 1017 * Prepare 80MHz channels from the bitmap. 1018 * 1019 * Return: channel count 1020 */ 1021 #ifdef CONFIG_CHAN_NUM_API 1022 static uint8_t dfs_populate_80mhz_available_channels( 1023 struct wlan_dfs *dfs, 1024 struct chan_bonding_bitmap *bitmap, 1025 uint8_t *avail_chnl) 1026 { 1027 uint8_t i = 0; 1028 uint8_t chnl_count = 0; 1029 uint8_t start_chan = 0; 1030 1031 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1032 start_chan = bitmap->chan_bonding_set[i].start_chan; 1033 if (bitmap->chan_bonding_set[i].chan_map == 1034 DFS_80MHZ_MASK) { 1035 avail_chnl[chnl_count++] = start_chan + 1036 (DFS_NEXT_5GHZ_CHANNEL * 0); 1037 avail_chnl[chnl_count++] = start_chan + 1038 (DFS_NEXT_5GHZ_CHANNEL * 1); 1039 avail_chnl[chnl_count++] = start_chan + 1040 (DFS_NEXT_5GHZ_CHANNEL * 2); 1041 avail_chnl[chnl_count++] = start_chan + 1042 (DFS_NEXT_5GHZ_CHANNEL * 3); 1043 } 1044 } 1045 1046 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1047 "channel count %d", chnl_count); 1048 1049 return chnl_count; 1050 } 1051 #endif 1052 1053 /* 1054 * dfs_populate_80mhz_available_channel_for_freq() - Populate 80MHZ channels 1055 * available for selection. 1056 * @dfs: Pointer to wlan_dfs. 1057 * @bitmap: Pointer to bonding channel bitmap. 1058 * @avail_freq_list: Pointer to frequency list of available channels. 1059 */ 1060 #ifdef CONFIG_CHAN_FREQ_API 1061 static uint8_t dfs_populate_80mhz_available_channel_for_freq( 1062 struct wlan_dfs *dfs, 1063 struct chan_bonding_bitmap *bitmap, 1064 uint16_t *avail_freq_list) 1065 { 1066 uint8_t i = 0; 1067 uint8_t chnl_count = 0; 1068 uint16_t start_chan_freq = 0; 1069 1070 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1071 start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; 1072 if (bitmap->chan_bonding_set[i].chan_map == 1073 DFS_80MHZ_MASK) { 1074 avail_freq_list[chnl_count++] = start_chan_freq + 1075 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0); 1076 avail_freq_list[chnl_count++] = start_chan_freq + 1077 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1); 1078 avail_freq_list[chnl_count++] = start_chan_freq + 1079 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2); 1080 avail_freq_list[chnl_count++] = start_chan_freq + 1081 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3); 1082 } 1083 } 1084 1085 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1086 "channel count %d", chnl_count); 1087 1088 return chnl_count; 1089 } 1090 #endif 1091 1092 /** 1093 * dfs_populate_40mhz_available_channels()- Populate channels for 40MHz using 1094 * bitmap 1095 * @dfs: Pointer to DFS structure. 1096 * @bitmap: bitmap 1097 * @avail_chnl: prepared channel list 1098 * 1099 * Prepare 40MHz channels from the bitmap. 1100 * 1101 * Return: channel count 1102 */ 1103 #ifdef CONFIG_CHAN_NUM_API 1104 static uint8_t dfs_populate_40mhz_available_channels( 1105 struct wlan_dfs *dfs, 1106 struct chan_bonding_bitmap *bitmap, 1107 uint8_t *avail_chnl) 1108 { 1109 uint8_t i = 0; 1110 uint8_t chnl_count = 0; 1111 uint8_t start_chan = 0; 1112 1113 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1114 start_chan = bitmap->chan_bonding_set[i].start_chan; 1115 if ((bitmap->chan_bonding_set[i].chan_map & 1116 DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) { 1117 avail_chnl[chnl_count++] = start_chan + 1118 (DFS_NEXT_5GHZ_CHANNEL * 0); 1119 avail_chnl[chnl_count++] = start_chan + 1120 (DFS_NEXT_5GHZ_CHANNEL * 1); 1121 } 1122 if ((bitmap->chan_bonding_set[i].chan_map & 1123 DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) { 1124 avail_chnl[chnl_count++] = start_chan + 1125 (DFS_NEXT_5GHZ_CHANNEL * 2); 1126 avail_chnl[chnl_count++] = start_chan + 1127 (DFS_NEXT_5GHZ_CHANNEL * 3); 1128 } 1129 } 1130 1131 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1132 "channel count %d", chnl_count); 1133 1134 return chnl_count; 1135 } 1136 #endif 1137 1138 #ifdef CONFIG_CHAN_FREQ_API 1139 static uint8_t 1140 dfs_populate_40mhz_available_channel_for_freq(struct wlan_dfs *dfs, 1141 struct chan_bonding_bitmap *bmap, 1142 uint16_t *avail_freq_list) 1143 { 1144 uint8_t i = 0; 1145 uint8_t chnl_count = 0; 1146 uint16_t start_chan_freq = 0; 1147 1148 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1149 start_chan_freq = bmap->chan_bonding_set[i].start_chan_freq; 1150 if ((bmap->chan_bonding_set[i].chan_map & 1151 DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) { 1152 avail_freq_list[chnl_count++] = start_chan_freq + 1153 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0); 1154 avail_freq_list[chnl_count++] = start_chan_freq + 1155 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1); 1156 } 1157 if ((bmap->chan_bonding_set[i].chan_map & 1158 DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) { 1159 avail_freq_list[chnl_count++] = start_chan_freq + 1160 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2); 1161 avail_freq_list[chnl_count++] = start_chan_freq + 1162 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3); 1163 } 1164 } 1165 1166 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1167 "channel count %d", chnl_count); 1168 1169 return chnl_count; 1170 } 1171 #endif 1172 1173 /** 1174 * dfs_populate_available_channels()- Populate channels based on width and 1175 * bitmap 1176 * @dfs: Pointer to DFS structure. 1177 * @bitmap: bitmap 1178 * @ch_width: channel width 1179 * @avail_chnl: prepared channel list 1180 * 1181 * Prepare channel list based on width and channel bitmap. 1182 * 1183 * Return: channel count 1184 */ 1185 #ifdef CONFIG_CHAN_NUM_API 1186 static uint8_t dfs_populate_available_channels( 1187 struct wlan_dfs *dfs, 1188 struct chan_bonding_bitmap *bitmap, 1189 uint8_t ch_width, 1190 uint8_t *avail_chnl) 1191 { 1192 switch (ch_width) { 1193 case DFS_CH_WIDTH_160MHZ: 1194 case DFS_CH_WIDTH_80P80MHZ: 1195 case DFS_CH_WIDTH_80MHZ: 1196 return dfs_populate_80mhz_available_channels( 1197 dfs, bitmap, avail_chnl); 1198 case DFS_CH_WIDTH_40MHZ: 1199 return dfs_populate_40mhz_available_channels( 1200 dfs, bitmap, avail_chnl); 1201 default: 1202 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1203 "Invalid ch_width %d", ch_width); 1204 break; 1205 } 1206 1207 return 0; 1208 } 1209 #endif 1210 1211 /** 1212 * dfs_populate_available_channel_for_freq()- Populate channels based on width 1213 * and bitmap. 1214 * @dfs: Pointer to DFS structure. 1215 * @bitmap: bitmap 1216 * @chan_width: channel width 1217 * @avail_freq_list: prepared channel list 1218 * 1219 * Prepare channel list based on width and channel bitmap. 1220 * 1221 * Return: channel count 1222 */ 1223 #ifdef CONFIG_CHAN_FREQ_API 1224 static uint8_t 1225 dfs_populate_available_channel_for_freq(struct wlan_dfs *dfs, 1226 struct chan_bonding_bitmap *bitmap, 1227 uint8_t chan_width, 1228 uint16_t *freq_list) 1229 { 1230 switch (chan_width) { 1231 case DFS_CH_WIDTH_160MHZ: 1232 case DFS_CH_WIDTH_80P80MHZ: 1233 case DFS_CH_WIDTH_80MHZ: 1234 return dfs_populate_80mhz_available_channel_for_freq(dfs, 1235 bitmap, 1236 freq_list); 1237 case DFS_CH_WIDTH_40MHZ: 1238 return dfs_populate_40mhz_available_channel_for_freq(dfs, 1239 bitmap, 1240 freq_list); 1241 default: 1242 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1243 "Invalid chan_width %d", chan_width); 1244 break; 1245 } 1246 1247 return 0; 1248 } 1249 #endif 1250 1251 /** 1252 * dfs_get_rand_from_lst()- Get random channel from a given channel list 1253 * @dfs: Pointer to DFS structure. 1254 * @ch_lst: channel list 1255 * @num_ch: number of channels 1256 * 1257 * Get random channel from given channel list. 1258 * 1259 * Return: channel number 1260 */ 1261 #ifdef CONFIG_CHAN_NUM_API 1262 static uint8_t dfs_get_rand_from_lst( 1263 struct wlan_dfs *dfs, 1264 uint8_t *ch_lst, 1265 uint8_t num_ch) 1266 { 1267 uint8_t i; 1268 uint32_t rand_byte = 0; 1269 1270 if (!num_ch || !ch_lst) { 1271 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 1272 "invalid param ch_lst %pK, num_ch = %d", 1273 ch_lst, num_ch); 1274 return 0; 1275 } 1276 1277 get_random_bytes((uint8_t *)&rand_byte, 1); 1278 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch; 1279 1280 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1281 "random channel %d", ch_lst[i]); 1282 1283 return ch_lst[i]; 1284 } 1285 #endif 1286 1287 /** 1288 * dfs_get_rand_from_lst_for_freq()- Get random channel from a given channel 1289 * list. 1290 * @dfs: Pointer to DFS structure. 1291 * @freq_lst: Frequency list 1292 * @num_chan: number of channels 1293 * 1294 * Get random channel from given channel list. 1295 * 1296 * Return: channel frequency. 1297 */ 1298 1299 #ifdef CONFIG_CHAN_FREQ_API 1300 static uint16_t dfs_get_rand_from_lst_for_freq(struct wlan_dfs *dfs, 1301 uint16_t *freq_lst, 1302 uint8_t num_chan) 1303 { 1304 uint8_t i; 1305 uint32_t rand_byte = 0; 1306 1307 if (!num_chan || !freq_lst) { 1308 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 1309 "invalid param freq_lst %pK, num_chan = %d", 1310 freq_lst, num_chan); 1311 return 0; 1312 } 1313 1314 get_random_bytes((uint8_t *)&rand_byte, 1); 1315 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_chan; 1316 1317 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1318 "random channel %d", freq_lst[i]); 1319 1320 return freq_lst[i]; 1321 } 1322 #endif 1323 1324 /** 1325 * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based 1326 * on given channel number 1327 * @dfs: Pointer to DFS structure. 1328 * @bitmap: bitmap 1329 * @channel: channel number 1330 * 1331 * Set channel bit in bitmap based on given channel number. 1332 * 1333 * Return: None 1334 */ 1335 #ifdef CONFIG_CHAN_NUM_API 1336 static void dfs_random_channel_sel_set_bitmap( 1337 struct wlan_dfs *dfs, 1338 struct chan_bonding_bitmap *bitmap, 1339 uint8_t channel) 1340 { 1341 int i = 0; 1342 int start_chan = 0; 1343 1344 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1345 start_chan = bitmap->chan_bonding_set[i].start_chan; 1346 if (channel >= start_chan && channel <= start_chan + 12) { 1347 bitmap->chan_bonding_set[i].chan_map |= 1348 (1 << ((channel - start_chan) / 1349 DFS_80_NUM_SUB_CHANNEL)); 1350 return; 1351 } 1352 } 1353 1354 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1355 "Channel=%d is not in the bitmap", channel); 1356 } 1357 #endif 1358 1359 /** 1360 * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based 1361 * on given channel number 1362 * @dfs: Pointer to DFS structure. 1363 * @bitmap: bitmap 1364 * @chan_freq: channel frequency 1365 * 1366 * Set channel bit in bitmap based on given channel frequency. 1367 * 1368 * Return: None 1369 */ 1370 #ifdef CONFIG_CHAN_FREQ_API 1371 #define FREQUENCY_BAND_LIMIT 60 1372 static void 1373 dfs_random_channel_sel_set_bitmap_for_freq(struct wlan_dfs *dfs, 1374 struct chan_bonding_bitmap *bitmap, 1375 uint16_t chan_freq) 1376 { 1377 int i = 0; 1378 int start_chan_freq = 0; 1379 1380 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1381 start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; 1382 if (chan_freq >= start_chan_freq && 1383 chan_freq <= start_chan_freq + 1384 FREQUENCY_BAND_LIMIT) { 1385 bitmap->chan_bonding_set[i].chan_map |= 1386 (1 << ((chan_freq - start_chan_freq) / 1387 DFS_80_NUM_SUB_CHANNEL_FREQ)); 1388 return; 1389 } 1390 } 1391 1392 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1393 "Frequency=%d is not in the bitmap", chan_freq); 1394 } 1395 #endif 1396 1397 /** 1398 * dfs_find_ch_with_fallback()- find random channel 1399 * @dfs: Pointer to DFS structure. 1400 * @ch_wd: channel width 1401 * @center_freq_seg1: center frequency of secondary segment. 1402 * @ch_lst: list of available channels. 1403 * @num_ch: number of channels in the list. 1404 * 1405 * Find random channel based on given channel width and channel list, 1406 * fallback to lower width if requested channel width not available. 1407 * 1408 * Return: channel number 1409 */ 1410 #ifdef CONFIG_CHAN_NUM_API 1411 static uint8_t dfs_find_ch_with_fallback( 1412 struct wlan_dfs *dfs, 1413 uint8_t *ch_wd, 1414 uint8_t *center_freq_seg1, 1415 uint8_t *ch_lst, 1416 uint32_t num_ch) 1417 { 1418 bool flag = false; 1419 uint32_t rand_byte = 0; 1420 struct chan_bonding_bitmap ch_map = { { {0} } }; 1421 uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0; 1422 uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; 1423 uint8_t final_lst[NUM_CHANNELS] = {0}; 1424 1425 /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ 1426 ch_map.chan_bonding_set[0].start_chan = 36; 1427 ch_map.chan_bonding_set[1].start_chan = 52; 1428 ch_map.chan_bonding_set[2].start_chan = 100; 1429 ch_map.chan_bonding_set[3].start_chan = 116; 1430 ch_map.chan_bonding_set[4].start_chan = 132; 1431 ch_map.chan_bonding_set[5].start_chan = 149; 1432 1433 for (i = 0; i < num_ch; i++) { 1434 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1435 "channel = %d added to bitmap", ch_lst[i]); 1436 dfs_random_channel_sel_set_bitmap(dfs, &ch_map, ch_lst[i]); 1437 } 1438 1439 /* populate available channel list from bitmap */ 1440 final_cnt = dfs_populate_available_channels(dfs, &ch_map, 1441 *ch_wd, final_lst); 1442 1443 /* If no valid ch bonding found, fallback */ 1444 if (final_cnt == 0) { 1445 if ((*ch_wd == DFS_CH_WIDTH_160MHZ) || 1446 (*ch_wd == DFS_CH_WIDTH_80P80MHZ) || 1447 (*ch_wd == DFS_CH_WIDTH_80MHZ)) { 1448 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1449 "from [%d] to 40Mhz", *ch_wd); 1450 *ch_wd = DFS_CH_WIDTH_40MHZ; 1451 } else if (*ch_wd == DFS_CH_WIDTH_40MHZ) { 1452 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1453 "from 40Mhz to 20MHz"); 1454 *ch_wd = DFS_CH_WIDTH_20MHZ; 1455 } 1456 return 0; 1457 } 1458 1459 /* ch count should be > 8 to switch new channel in 160Mhz band */ 1460 if (((*ch_wd == DFS_CH_WIDTH_160MHZ) || 1461 (*ch_wd == DFS_CH_WIDTH_80P80MHZ)) && 1462 (final_cnt < DFS_MAX_20M_SUB_CH)) { 1463 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1464 "from [%d] to 80Mhz", *ch_wd); 1465 *ch_wd = DFS_CH_WIDTH_80MHZ; 1466 return 0; 1467 } 1468 1469 if (*ch_wd == DFS_CH_WIDTH_160MHZ) { 1470 /* 1471 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128 1472 * and all the channels in these blocks are continuous 1473 * and separated by 4Mhz. 1474 */ 1475 for (i = 1; ((i < final_cnt)); i++) { 1476 if ((final_lst[i] - final_lst[i-1]) == 1477 DFS_NEXT_5GHZ_CHANNEL) 1478 count++; 1479 else 1480 count = 0; 1481 if (count == DFS_MAX_20M_SUB_CH - 1) { 1482 flag = true; 1483 new_160_start_ch = final_lst[i - count]; 1484 break; 1485 } 1486 } 1487 } else if (*ch_wd == DFS_CH_WIDTH_80P80MHZ) { 1488 flag = true; 1489 } 1490 1491 if ((flag == false) && (*ch_wd > DFS_CH_WIDTH_80MHZ)) { 1492 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1493 "from [%d] to 80Mhz", *ch_wd); 1494 *ch_wd = DFS_CH_WIDTH_80MHZ; 1495 return 0; 1496 } 1497 1498 if (*ch_wd == DFS_CH_WIDTH_160MHZ) { 1499 get_random_bytes((uint8_t *)&rand_byte, 1); 1500 rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) 1501 % DFS_MAX_20M_SUB_CH; 1502 target_channel = new_160_start_ch + (rand_byte * 1503 DFS_80_NUM_SUB_CHANNEL); 1504 } else if (*ch_wd == DFS_CH_WIDTH_80P80MHZ) { 1505 get_random_bytes((uint8_t *)&rand_byte, 1); 1506 index = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1507 final_cnt; 1508 target_channel = final_lst[index]; 1509 index -= (index % DFS_80_NUM_SUB_CHANNEL); 1510 primary_seg_start_ch = final_lst[index]; 1511 1512 /* reset channels associate with primary 80Mhz */ 1513 for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++) 1514 final_lst[i + index] = 0; 1515 /* select and calculate center freq for secondary segment */ 1516 for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) { 1517 if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] && 1518 (abs(primary_seg_start_ch - 1519 final_lst[i * DFS_80_NUM_SUB_CHANNEL]) > 1520 (DFS_MAX_20M_SUB_CH * 2))) { 1521 sec_seg_ch = 1522 final_lst[i * DFS_80_NUM_SUB_CHANNEL] + 1523 DFS_80MHZ_START_CENTER_CH_DIFF; 1524 break; 1525 } 1526 } 1527 1528 if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH)) 1529 *ch_wd = DFS_CH_WIDTH_160MHZ; 1530 else if (!sec_seg_ch) 1531 *ch_wd = DFS_CH_WIDTH_80MHZ; 1532 1533 *center_freq_seg1 = sec_seg_ch; 1534 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1535 "Center frequency seg1 = %d", sec_seg_ch); 1536 } else { 1537 target_channel = dfs_get_rand_from_lst(dfs, 1538 final_lst, final_cnt); 1539 } 1540 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1541 "target channel = %d", target_channel); 1542 1543 return target_channel; 1544 } 1545 #endif 1546 1547 #ifdef CONFIG_BAND_6GHZ 1548 /** 1549 * dfs_assign_6g_channels()- Assign the center frequency of the first 20 MHZ 1550 * channel in every 80MHz channel, present in the 6G band. 1551 * @ch_map: Pointer to ch_map. 1552 * 1553 * Return: Void 1554 */ 1555 static void dfs_assign_6g_channels(struct chan_bonding_bitmap *ch_map) 1556 { 1557 ch_map->chan_bonding_set[6].start_chan_freq = 5955; 1558 ch_map->chan_bonding_set[7].start_chan_freq = 6035; 1559 ch_map->chan_bonding_set[8].start_chan_freq = 6115; 1560 ch_map->chan_bonding_set[9].start_chan_freq = 6195; 1561 ch_map->chan_bonding_set[10].start_chan_freq = 6275; 1562 ch_map->chan_bonding_set[11].start_chan_freq = 6355; 1563 ch_map->chan_bonding_set[12].start_chan_freq = 6435; 1564 ch_map->chan_bonding_set[13].start_chan_freq = 6515; 1565 ch_map->chan_bonding_set[14].start_chan_freq = 6595; 1566 ch_map->chan_bonding_set[15].start_chan_freq = 6675; 1567 ch_map->chan_bonding_set[16].start_chan_freq = 6755; 1568 ch_map->chan_bonding_set[17].start_chan_freq = 6835; 1569 ch_map->chan_bonding_set[18].start_chan_freq = 6915; 1570 ch_map->chan_bonding_set[19].start_chan_freq = 6995; 1571 } 1572 #else 1573 static inline void dfs_assign_6g_channels(struct chan_bonding_bitmap *ch_map) 1574 { 1575 } 1576 #endif 1577 1578 /** 1579 * dfs_find_ch_with_fallback_for_freq()- find random channel 1580 * @dfs: Pointer to DFS structure. 1581 * @chan_wd: channel width 1582 * @center_freq_seg1: center frequency of secondary segment. 1583 * @freq_lst: list of available frequency. 1584 * @num_chan: number of channels in the list. 1585 * 1586 * Find random channel based on given channel width and channel list, 1587 * fallback to lower width if requested channel width not available. 1588 * 1589 * Return: channel frequency. 1590 */ 1591 #ifdef CONFIG_CHAN_FREQ_API 1592 static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs, 1593 uint8_t *chan_wd, 1594 qdf_freq_t *center_freq_seg1, 1595 uint16_t *freq_lst, 1596 uint32_t num_chan) 1597 { 1598 bool flag = false; 1599 uint32_t rand_byte = 0; 1600 struct chan_bonding_bitmap ch_map = { { {0} } }; 1601 uint8_t count = 0, i, index = 0, final_cnt = 0; 1602 uint16_t target_channel = 0; 1603 uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; 1604 uint16_t final_lst[NUM_CHANNELS] = {0}; 1605 1606 /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ 1607 ch_map.chan_bonding_set[0].start_chan_freq = 5180; 1608 ch_map.chan_bonding_set[1].start_chan_freq = 5260; 1609 ch_map.chan_bonding_set[2].start_chan_freq = 5500; 1610 ch_map.chan_bonding_set[3].start_chan_freq = 5580; 1611 ch_map.chan_bonding_set[4].start_chan_freq = 5660; 1612 ch_map.chan_bonding_set[5].start_chan_freq = 5745; 1613 1614 dfs_assign_6g_channels(&ch_map); 1615 for (i = 0; i < num_chan; i++) { 1616 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1617 "channel = %d added to bitmap", freq_lst[i]); 1618 dfs_random_channel_sel_set_bitmap_for_freq(dfs, &ch_map, 1619 freq_lst[i]); 1620 } 1621 1622 /* populate available channel list from bitmap */ 1623 final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map, 1624 *chan_wd, final_lst); 1625 1626 /* If no valid ch bonding found, fallback */ 1627 if (final_cnt == 0) { 1628 if ((*chan_wd == DFS_CH_WIDTH_160MHZ) || 1629 (*chan_wd == DFS_CH_WIDTH_80P80MHZ) || 1630 (*chan_wd == DFS_CH_WIDTH_80MHZ)) { 1631 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1632 "from [%d] to 40Mhz", *chan_wd); 1633 *chan_wd = DFS_CH_WIDTH_40MHZ; 1634 } else if (*chan_wd == DFS_CH_WIDTH_40MHZ) { 1635 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1636 "from 40Mhz to 20MHz"); 1637 *chan_wd = DFS_CH_WIDTH_20MHZ; 1638 } 1639 return 0; 1640 } 1641 1642 /* ch count should be > 8 to switch new channel in 160Mhz band */ 1643 if (((*chan_wd == DFS_CH_WIDTH_160MHZ) || 1644 (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) && 1645 (final_cnt < DFS_MAX_20M_SUB_CH)) { 1646 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1647 "from [%d] to 80Mhz", *chan_wd); 1648 *chan_wd = DFS_CH_WIDTH_80MHZ; 1649 return 0; 1650 } 1651 1652 if (*chan_wd == DFS_CH_WIDTH_160MHZ) { 1653 /* 1654 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128 1655 * and all the channels in these blocks are continuous 1656 * and separated by 4Mhz. 1657 */ 1658 for (i = 1; ((i < final_cnt)); i++) { 1659 if ((final_lst[i] - final_lst[i - 1]) == 1660 DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET) 1661 count++; 1662 else 1663 count = 0; 1664 if (count == DFS_MAX_20M_SUB_CH - 1) { 1665 flag = true; 1666 new_160_start_ch = final_lst[i - count]; 1667 break; 1668 } 1669 } 1670 } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { 1671 flag = true; 1672 } 1673 1674 if ((flag == false) && (*chan_wd > DFS_CH_WIDTH_80MHZ)) { 1675 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1676 "from [%d] to 80Mhz", *chan_wd); 1677 *chan_wd = DFS_CH_WIDTH_80MHZ; 1678 return 0; 1679 } 1680 1681 if (*chan_wd == DFS_CH_WIDTH_160MHZ) { 1682 get_random_bytes((uint8_t *)&rand_byte, 1); 1683 rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) 1684 % DFS_MAX_20M_SUB_CH; 1685 target_channel = new_160_start_ch + (rand_byte * 1686 DFS_80_NUM_SUB_CHANNEL_FREQ); 1687 } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { 1688 get_random_bytes((uint8_t *)&rand_byte, 1); 1689 index = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1690 final_cnt; 1691 target_channel = final_lst[index]; 1692 index -= (index % DFS_80_NUM_SUB_CHANNEL); 1693 primary_seg_start_ch = final_lst[index]; 1694 1695 /* reset channels associate with primary 80Mhz */ 1696 for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++) 1697 final_lst[i + index] = 0; 1698 /* select and calculate center freq for secondary segment */ 1699 for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) { 1700 if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] && 1701 (abs(primary_seg_start_ch - 1702 final_lst[i * DFS_80_NUM_SUB_CHANNEL]) > 1703 (DFS_80P80M_FREQ_DIFF * 2))) { 1704 sec_seg_ch = final_lst[i * 1705 DFS_80_NUM_SUB_CHANNEL] + 1706 DFS_80MHZ_START_CENTER_CH_FREQ_DIFF; 1707 break; 1708 } 1709 } 1710 1711 if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH)) 1712 *chan_wd = DFS_CH_WIDTH_160MHZ; 1713 else if (!sec_seg_ch) 1714 *chan_wd = DFS_CH_WIDTH_80MHZ; 1715 1716 *center_freq_seg1 = sec_seg_ch; 1717 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1718 "Center frequency seg1 = %d", sec_seg_ch); 1719 } else { 1720 target_channel = dfs_get_rand_from_lst_for_freq(dfs, 1721 final_lst, 1722 final_cnt); 1723 } 1724 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1725 "target channel = %d", target_channel); 1726 1727 return target_channel; 1728 } 1729 #endif 1730 1731 bool dfs_is_freq_in_nol(struct wlan_dfs *dfs, uint32_t freq) 1732 { 1733 struct dfs_nolelem *nol; 1734 1735 if (!dfs) { 1736 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "null dfs"); 1737 return false; 1738 } 1739 1740 nol = dfs->dfs_nol; 1741 while (nol) { 1742 if (freq == nol->nol_freq) { 1743 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1744 "%d is in nol", freq); 1745 return true; 1746 } 1747 nol = nol->nol_next; 1748 } 1749 1750 return false; 1751 } 1752 1753 /** 1754 * dfs_apply_rules()- prepare channel list based on flags 1755 * @dfs: dfs handler 1756 * @flags: channel flags 1757 * @random_chan_list: output channel list 1758 * @random_chan_cnt: output channel count 1759 * @ch_list: input channel list 1760 * @ch_cnt: input channel count 1761 * @dfs_region: dfs region 1762 * @acs_info: acs channel range information 1763 * 1764 * prepare channel list based on flags 1765 * 1766 * return: none 1767 */ 1768 #ifdef CONFIG_CHAN_NUM_API 1769 static void dfs_apply_rules(struct wlan_dfs *dfs, 1770 uint32_t flags, 1771 uint8_t *random_chan_list, 1772 uint32_t *random_chan_cnt, 1773 struct dfs_channel *ch_list, 1774 uint32_t ch_cnt, 1775 uint8_t dfs_region, 1776 struct dfs_acs_info *acs_info) 1777 { 1778 struct dfs_channel *chan; 1779 bool flag_no_weather = 0; 1780 bool flag_no_lower_5g = 0; 1781 bool flag_no_upper_5g = 0; 1782 bool flag_no_dfs_chan = 0; 1783 bool flag_no_2g_chan = 0; 1784 bool flag_no_5g_chan = 0; 1785 bool flag_no_japan_w53 = 0; 1786 int i; 1787 bool found = false; 1788 uint16_t j; 1789 1790 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags); 1791 flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? 1792 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 1793 1794 if (dfs_region == DFS_MKK_REGION_VAL) { 1795 flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH; 1796 flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH; 1797 flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH; 1798 } 1799 1800 flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH; 1801 flag_no_2g_chan = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH; 1802 flag_no_5g_chan = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH; 1803 1804 for (i = 0; i < ch_cnt; i++) { 1805 chan = &ch_list[i]; 1806 1807 if ((chan->dfs_ch_ieee == 0) || 1808 (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) { 1809 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1810 "invalid channel %d", chan->dfs_ch_ieee); 1811 continue; 1812 } 1813 1814 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { 1815 /* TODO : Skip all HT20 channels in the given mode */ 1816 if (chan->dfs_ch_ieee == 1817 dfs->dfs_curchan->dfs_ch_ieee) { 1818 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1819 "skip %d current operating channel", 1820 chan->dfs_ch_ieee); 1821 continue; 1822 } 1823 } 1824 1825 if (acs_info && acs_info->acs_mode) { 1826 for (j = 0; j < acs_info->num_of_channel; j++) { 1827 if (acs_info->chan_freq_list[j] == 1828 chan->dfs_ch_freq){ 1829 found = true; 1830 break; 1831 } 1832 } 1833 1834 if (!found) { 1835 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1836 "skip ch %d not in acs range", 1837 chan->dfs_ch_ieee); 1838 continue; 1839 } 1840 found = false; 1841 } 1842 1843 if (flag_no_2g_chan && 1844 chan->dfs_ch_ieee <= DFS_MAX_24GHZ_CHANNEL) { 1845 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1846 "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee); 1847 continue; 1848 } 1849 1850 if (flag_no_5g_chan && 1851 chan->dfs_ch_ieee > DFS_MAX_24GHZ_CHANNEL) { 1852 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1853 "skip 5 GHz channel=%d", chan->dfs_ch_ieee); 1854 continue; 1855 } 1856 1857 if (flag_no_weather) { 1858 if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) { 1859 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1860 "skip weather channel=%d", 1861 chan->dfs_ch_ieee); 1862 continue; 1863 } 1864 } 1865 1866 if (flag_no_lower_5g && 1867 DFS_IS_CHAN_JAPAN_INDOOR(chan->dfs_ch_ieee)) { 1868 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1869 "skip indoor channel=%d", chan->dfs_ch_ieee); 1870 continue; 1871 } 1872 1873 if (flag_no_upper_5g && 1874 DFS_IS_CHAN_JAPAN_OUTDOOR(chan->dfs_ch_ieee)) { 1875 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1876 "skip outdoor channel=%d", chan->dfs_ch_ieee); 1877 continue; 1878 } 1879 1880 if (flag_no_dfs_chan && 1881 (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) { 1882 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1883 "skip dfs channel=%d", chan->dfs_ch_ieee); 1884 continue; 1885 } 1886 1887 if (flag_no_japan_w53 && 1888 DFS_IS_CHAN_JAPAN_W53(chan->dfs_ch_ieee)) { 1889 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1890 "skip japan W53 channel=%d", 1891 chan->dfs_ch_ieee); 1892 continue; 1893 } 1894 1895 if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) { 1896 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1897 "skip nol channel=%d", chan->dfs_ch_ieee); 1898 continue; 1899 } 1900 1901 random_chan_list[*random_chan_cnt] = chan->dfs_ch_ieee; 1902 *random_chan_cnt += 1; 1903 } 1904 } 1905 #endif 1906 1907 /** 1908 * dfs_apply_rules_for_freq()- prepare channel list based on flags 1909 * @dfs: dfs handler 1910 * @flags: channel flags 1911 * @random_chan_freq_list: output channel list 1912 * @random_chan_cnt: output channel count 1913 * @chan_list: input channel list 1914 * @chan_cnt: input channel count 1915 * @dfs_region: dfs region 1916 * @acs_info: acs channel range information 1917 * 1918 * prepare channel list based on flags 1919 * 1920 * return: none 1921 */ 1922 #ifdef CONFIG_CHAN_FREQ_API 1923 static void dfs_apply_rules_for_freq(struct wlan_dfs *dfs, 1924 uint32_t flags, 1925 uint16_t *random_chan_freq_list, 1926 uint32_t *random_chan_cnt, 1927 struct dfs_channel *chan_list, 1928 uint32_t chan_cnt, 1929 uint8_t dfs_region, 1930 struct dfs_acs_info *acs_info) 1931 { 1932 struct dfs_channel *chan; 1933 bool flag_no_weather = 0; 1934 bool flag_no_lower_5g = 0; 1935 bool flag_no_upper_5g = 0; 1936 bool flag_no_dfs_chan = 0; 1937 bool flag_no_2g_chan = 0; 1938 bool flag_no_5g_chan = 0; 1939 bool flag_no_japan_w53 = 0; 1940 bool flag_no_6g_freq; 1941 int i; 1942 bool found = false; 1943 uint16_t j; 1944 uint16_t freq_list[NUM_CHANNELS_160MHZ]; 1945 uint8_t num_channels = 0; 1946 1947 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags); 1948 flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? 1949 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 1950 1951 if (dfs_region == DFS_MKK_REGION_VAL) { 1952 flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH; 1953 flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH; 1954 flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH; 1955 } 1956 1957 flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH; 1958 flag_no_2g_chan = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH; 1959 flag_no_5g_chan = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH; 1960 flag_no_6g_freq = flags & DFS_RANDOM_CH_FLAG_NO_6GHZ_CH; 1961 1962 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { 1963 num_channels = 1964 dfs_get_bonding_channel_without_seg_info_for_freq 1965 (dfs->dfs_curchan, freq_list); 1966 } 1967 1968 for (i = 0; i < chan_cnt; i++) { 1969 chan = &chan_list[i]; 1970 found = false; 1971 1972 if ((chan->dfs_ch_ieee == 0) || 1973 (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) { 1974 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1975 "invalid channel %d", chan->dfs_ch_ieee); 1976 continue; 1977 } 1978 1979 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { 1980 for (j = 0; j < num_channels; j++) { 1981 if (chan->dfs_ch_freq == freq_list[j]) { 1982 dfs_debug(dfs, 1983 WLAN_DEBUG_DFS_RANDOM_CHAN, 1984 "skip %d current operating channel", 1985 chan->dfs_ch_freq); 1986 found = true; 1987 break; 1988 } 1989 } 1990 1991 if (found) 1992 continue; 1993 } 1994 1995 if (acs_info && acs_info->acs_mode) { 1996 for (j = 0; j < acs_info->num_of_channel; j++) { 1997 if (acs_info->chan_freq_list[j] == 1998 chan->dfs_ch_freq) { 1999 found = true; 2000 break; 2001 } 2002 } 2003 2004 if (!found) { 2005 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2006 "skip ch freq %d not in acs range", 2007 chan->dfs_ch_freq); 2008 continue; 2009 } 2010 found = false; 2011 } 2012 2013 if (flag_no_2g_chan && 2014 chan->dfs_ch_freq <= DFS_MAX_24GHZ_CHANNEL_FREQ) { 2015 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2016 "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee); 2017 continue; 2018 } 2019 2020 if (flag_no_5g_chan && 2021 WLAN_REG_IS_5GHZ_CH_FREQ(chan->dfs_ch_freq)) { 2022 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2023 "skip 5 GHz channel=%d", chan->dfs_ch_ieee); 2024 continue; 2025 } 2026 2027 if (flag_no_weather) { 2028 if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) { 2029 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2030 "skip weather channel=%d", 2031 chan->dfs_ch_ieee); 2032 continue; 2033 } 2034 } 2035 2036 if (flag_no_lower_5g && 2037 DFS_IS_CHAN_JAPAN_INDOOR_FREQ(chan->dfs_ch_freq)) { 2038 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2039 "skip indoor channel=%d", chan->dfs_ch_ieee); 2040 continue; 2041 } 2042 2043 if (flag_no_upper_5g && 2044 DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(chan->dfs_ch_freq)) { 2045 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2046 "skip outdoor channel=%d", chan->dfs_ch_ieee); 2047 continue; 2048 } 2049 2050 if (flag_no_6g_freq && 2051 WLAN_REG_IS_6GHZ_CHAN_FREQ(chan->dfs_ch_freq)) { 2052 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2053 "skip 6 GHz channel=%d", chan->dfs_ch_ieee); 2054 continue; 2055 } 2056 2057 if (flag_no_dfs_chan && 2058 (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) { 2059 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2060 "skip dfs channel=%d", chan->dfs_ch_ieee); 2061 continue; 2062 } 2063 2064 if (flag_no_japan_w53 && 2065 DFS_IS_CHAN_JAPAN_W53_FREQ(chan->dfs_ch_freq)) { 2066 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2067 "skip japan W53 channel=%d", 2068 chan->dfs_ch_ieee); 2069 continue; 2070 } 2071 2072 if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) { 2073 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2074 "skip nol channel=%d", chan->dfs_ch_ieee); 2075 continue; 2076 } 2077 2078 random_chan_freq_list[*random_chan_cnt] = chan->dfs_ch_freq; 2079 *random_chan_cnt += 1; 2080 } 2081 } 2082 #endif 2083 2084 #ifdef CONFIG_CHAN_NUM_API 2085 uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, 2086 struct dfs_channel *ch_list, 2087 uint32_t ch_cnt, 2088 uint32_t flags, 2089 uint8_t *ch_wd, 2090 struct dfs_channel *cur_chan, 2091 uint8_t dfs_region, 2092 struct dfs_acs_info *acs_info) 2093 { 2094 int i = 0; 2095 uint8_t final_cnt = 0; 2096 uint8_t target_ch = 0; 2097 uint8_t *random_chan_list = NULL; 2098 uint32_t random_chan_cnt = 0; 2099 uint16_t flag_no_weather = 0; 2100 uint8_t *leakage_adjusted_lst; 2101 uint8_t final_lst[NUM_CHANNELS] = {0}; 2102 2103 if (!ch_list || !ch_cnt) { 2104 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2105 "Invalid params %pK, ch_cnt=%d", 2106 ch_list, ch_cnt); 2107 return 0; 2108 } 2109 2110 if (*ch_wd < DFS_CH_WIDTH_20MHZ || *ch_wd > DFS_CH_WIDTH_80P80MHZ) { 2111 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2112 "Invalid ch_wd %d", *ch_wd); 2113 return 0; 2114 } 2115 2116 random_chan_list = qdf_mem_malloc(ch_cnt * sizeof(*random_chan_list)); 2117 if (!random_chan_list) 2118 return 0; 2119 2120 dfs_apply_rules(dfs, flags, random_chan_list, &random_chan_cnt, 2121 ch_list, ch_cnt, dfs_region, acs_info); 2122 2123 flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? 2124 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 2125 2126 /* list adjusted after leakage has been marked */ 2127 leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt); 2128 if (!leakage_adjusted_lst) { 2129 qdf_mem_free(random_chan_list); 2130 return 0; 2131 } 2132 2133 do { 2134 qdf_mem_copy(leakage_adjusted_lst, random_chan_list, 2135 random_chan_cnt); 2136 if (QDF_IS_STATUS_ERROR(dfs_mark_leaking_ch(dfs, *ch_wd, 2137 random_chan_cnt, 2138 leakage_adjusted_lst))) { 2139 qdf_mem_free(random_chan_list); 2140 qdf_mem_free(leakage_adjusted_lst); 2141 return 0; 2142 } 2143 2144 if (*ch_wd == DFS_CH_WIDTH_20MHZ) { 2145 /* 2146 * PASS: 3 - from leakage_adjusted_lst, prepare valid 2147 * ch list and use random number from that 2148 */ 2149 for (i = 0; i < random_chan_cnt; i++) { 2150 if (leakage_adjusted_lst[i] == 0) 2151 continue; 2152 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2153 "dfs: Channel=%d added to available list", 2154 leakage_adjusted_lst[i]); 2155 final_lst[final_cnt] = leakage_adjusted_lst[i]; 2156 final_cnt++; 2157 } 2158 target_ch = dfs_get_rand_from_lst( 2159 dfs, final_lst, final_cnt); 2160 break; 2161 } 2162 2163 target_ch = dfs_find_ch_with_fallback(dfs, ch_wd, 2164 &cur_chan->dfs_ch_vhtop_ch_freq_seg2, 2165 leakage_adjusted_lst, 2166 random_chan_cnt); 2167 2168 /* 2169 * When flag_no_weather is set, avoid usage of Adjacent 2170 * weather radar channel in HT40 mode as extension channel 2171 * will be on 5600. 2172 */ 2173 if (flag_no_weather && 2174 (target_ch == 2175 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM) && 2176 (*ch_wd == DFS_CH_WIDTH_40MHZ)) { 2177 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2178 "skip weather adjacent ch=%d\n", 2179 target_ch); 2180 continue; 2181 } 2182 2183 if (target_ch) 2184 break; 2185 } while (true); 2186 2187 qdf_mem_free(random_chan_list); 2188 qdf_mem_free(leakage_adjusted_lst); 2189 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_ch = %d", target_ch); 2190 2191 return target_ch; 2192 } 2193 #endif 2194 2195 #ifdef CONFIG_CHAN_FREQ_API 2196 uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs, 2197 struct dfs_channel *chan_list, 2198 uint32_t chan_cnt, 2199 uint32_t flags, 2200 struct ch_params *chan_params, 2201 uint8_t dfs_region, 2202 struct dfs_acs_info *acs_info) 2203 { 2204 int i = 0; 2205 uint8_t final_cnt = 0; 2206 uint16_t target_freq = 0; 2207 uint16_t *random_chan_freq_list = NULL; 2208 uint32_t random_chan_cnt = 0; 2209 uint16_t flag_no_weather = 0; 2210 uint16_t *leakage_adjusted_lst; 2211 uint16_t final_lst[NUM_CHANNELS] = {0}; 2212 uint8_t *chan_wd = (uint8_t *)&chan_params->ch_width; 2213 2214 if (!chan_list || !chan_cnt) { 2215 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2216 "Invalid params %pK, chan_cnt=%d", 2217 chan_list, chan_cnt); 2218 return 0; 2219 } 2220 2221 if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_80P80MHZ) { 2222 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2223 "Invalid chan_wd %d", *chan_wd); 2224 return 0; 2225 } 2226 2227 random_chan_freq_list = 2228 qdf_mem_malloc(chan_cnt * sizeof(*random_chan_freq_list)); 2229 if (!random_chan_freq_list) 2230 return 0; 2231 2232 dfs_apply_rules_for_freq(dfs, flags, random_chan_freq_list, 2233 &random_chan_cnt, chan_list, chan_cnt, 2234 dfs_region, acs_info); 2235 flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? 2236 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 2237 2238 /* list adjusted after leakage has been marked */ 2239 leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt * 2240 sizeof(*leakage_adjusted_lst)); 2241 if (!leakage_adjusted_lst) { 2242 qdf_mem_free(random_chan_freq_list); 2243 return 0; 2244 } 2245 2246 do { 2247 int ret; 2248 2249 qdf_mem_copy(leakage_adjusted_lst, random_chan_freq_list, 2250 random_chan_cnt * sizeof(*leakage_adjusted_lst)); 2251 ret = dfs_mark_leaking_chan_for_freq(dfs, *chan_wd, 2252 random_chan_cnt, 2253 leakage_adjusted_lst); 2254 if (QDF_IS_STATUS_ERROR(ret)) { 2255 qdf_mem_free(random_chan_freq_list); 2256 qdf_mem_free(leakage_adjusted_lst); 2257 return 0; 2258 } 2259 2260 if (*chan_wd == DFS_CH_WIDTH_20MHZ) { 2261 /* 2262 * PASS: 3 - from leakage_adjusted_lst, prepare valid 2263 * ch list and use random number from that 2264 */ 2265 for (i = 0; i < random_chan_cnt; i++) { 2266 if (leakage_adjusted_lst[i] == 0) 2267 continue; 2268 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2269 "Channel=%d added to available list", 2270 leakage_adjusted_lst[i]); 2271 final_lst[final_cnt] = leakage_adjusted_lst[i]; 2272 final_cnt++; 2273 } 2274 target_freq = dfs_get_rand_from_lst_for_freq(dfs, 2275 final_lst, 2276 final_cnt); 2277 break; 2278 } 2279 target_freq = dfs_find_ch_with_fallback_for_freq( 2280 dfs, chan_wd, &chan_params->mhz_freq_seg1, 2281 leakage_adjusted_lst, random_chan_cnt); 2282 2283 /* Since notion of 80+80 is not present in the regulatory 2284 * channel the function may return invalid 80+80 channels for 2285 * some devices (e.g. Pine). Therefore, check if we need to 2286 * correct it by checking the following condition. 2287 */ 2288 if ((*chan_wd == DFS_CH_WIDTH_80P80MHZ) && 2289 (flags & DFS_RANDOM_CH_FLAG_RESTRICTED_80P80_ENABLED) && 2290 target_freq) { 2291 wlan_reg_set_channel_params_for_freq(dfs->dfs_pdev_obj, 2292 target_freq, 2293 0, chan_params); 2294 if (!(CHAN_WITHIN_RESTRICTED_80P80( 2295 chan_params->mhz_freq_seg0, 2296 chan_params->mhz_freq_seg1))) { 2297 *chan_wd = DFS_CH_WIDTH_160MHZ; 2298 target_freq = 2299 dfs_find_ch_with_fallback_for_freq( 2300 dfs, chan_wd, 2301 &chan_params->mhz_freq_seg1, 2302 leakage_adjusted_lst, 2303 random_chan_cnt); 2304 } 2305 } 2306 2307 /* 2308 * When flag_no_weather is set, avoid usage of Adjacent 2309 * weather radar channel in HT40 mode as extension channel 2310 * will be on 5600. 2311 */ 2312 if (flag_no_weather && 2313 (target_freq == 2314 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ) && 2315 (*chan_wd == DFS_CH_WIDTH_40MHZ)) { 2316 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 2317 "skip weather adjacent ch=%d\n", 2318 target_freq); 2319 continue; 2320 } 2321 2322 if (target_freq) 2323 break; 2324 } while (true); 2325 2326 qdf_mem_free(random_chan_freq_list); 2327 qdf_mem_free(leakage_adjusted_lst); 2328 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_freq = %d", 2329 target_freq); 2330 2331 return target_freq; 2332 } 2333 #endif 2334