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