1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "../dfs.h" 21 #include "../dfs_random_chan_sel.h" 22 #include <qdf_mc_timer.h> 23 #include <wlan_utility.h> 24 #include <wlan_reg_services_api.h> 25 #include "../dfs_process_radar_found_ind.h" 26 27 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 28 /* 29 * TODO: At present SAP Channel leakage matrix for ch 144 30 * is not available from system's team. So to play it safe 31 * and avoid crash if channel 144 is request, in following 32 * matrix channel 144 is added such that it will cause code 33 * to avoid selecting channel 144. 34 * 35 * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS 36 * PROVIDED BY SYSTEM'S TEAM. 37 */ 38 39 /* channel tx leakage table - ht80 */ 40 struct dfs_matrix_tx_leak_info ht80_chan[] = { 41 {52, 5260, 42 {{36, 5180, 148}, {40, 5200, 199}, 43 {44, 5520, 193}, {48, 5240, 197}, 44 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, 153}, 45 {60, 5300, 137}, {64, 5320, 134}, 46 {100, 5500, 358}, {104, 5520, 350}, 47 {108, 5540, 404}, {112, 5560, 344}, 48 {116, 5580, 424}, {120, 5600, 429}, 49 {124, 5620, 437}, {128, 5640, 435}, 50 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 51 {140, 5700, DFS_TX_LEAKAGE_MAX}, 52 {144, 5720, DFS_TX_LEAKAGE_MIN} 53 } }, 54 55 56 {56, 5280, 57 {{36, 5180, 171}, {40, 5200, 178}, 58 {44, 5220, 171}, {48, 5240, 178}, 59 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 60 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, 280}, 61 {100, 5500, 351}, {104, 5520, 376}, 62 {108, 5540, 362}, {112, 5560, 362}, 63 {116, 5580, 403}, {120, 5600, 397}, 64 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 65 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 66 {140, 5700, DFS_TX_LEAKAGE_MAX}, 67 {144, 5720, DFS_TX_LEAKAGE_MIN} 68 } }, 69 70 {60,5300, 71 {{36, 5180, 156}, {40, 5200, 146}, 72 {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN}, 73 {52, 5260, 180}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 74 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 75 {100, 5500, 376}, {104, 5520, 360}, 76 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 77 {116, 5580, 395}, {120, 5600, 399}, 78 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 79 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 80 {140, 5700, DFS_TX_LEAKAGE_MAX}, 81 {144, 5720, DFS_TX_LEAKAGE_MIN} 82 } }, 83 84 {64, 5320, 85 {{36, 5180, 217}, {40, 5200, 221}, 86 {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN}, 87 {52, 5260, 176}, {56, 5280, 176}, 88 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 89 {100, 5500, 384}, {104, 5520, 390}, 90 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 91 {116, 5580, 375}, {120, 5600, 374}, 92 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 93 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 94 {140, 5700, DFS_TX_LEAKAGE_MAX}, 95 {144, 5720, DFS_TX_LEAKAGE_MIN} 96 } }, 97 98 {100, 5500, 99 {{36, 5180, 357}, {40, 5200, 326}, 100 {44, 5220, 321}, {48, 5240, 326}, 101 {52, 5260, 378}, {56, 5280, 396}, 102 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 103 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 104 {108, 5540, 196}, {112, 5560, 116}, 105 {116, 5580, 166}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 106 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 107 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 108 {140, 5700, DFS_TX_LEAKAGE_MIN}, 109 {144, 5720, DFS_TX_LEAKAGE_MIN} 110 } }, 111 112 {104, 5520, 113 {{36, 5180, 325}, {40, 5200, 325}, 114 {44, 5220, 305}, {48, 5240, 352}, 115 {52, 5260, 411}, {56, 5280, 411}, 116 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 117 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 118 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 460}, 119 {116, 5580, 198}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 120 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 121 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 122 {140, 5700, DFS_TX_LEAKAGE_MIN}, 123 {144, 5720, DFS_TX_LEAKAGE_MIN} 124 } }, 125 126 {108, 5540, 127 {{36,5180, 304}, {40, 5200, 332}, 128 {44, 5220, 310}, {48, 5240, 335}, 129 {52, 5260, 431}, {56, 5280, 391}, 130 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 131 {100, 5500, 280}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 132 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 133 {116, 5580, 185}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 134 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 135 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 136 {140, 5700, DFS_TX_LEAKAGE_MIN}, 137 {144, 5720, DFS_TX_LEAKAGE_MIN} 138 } }, 139 140 {112,5560, 141 {{36, 5180, 327}, {40, 5200, 335}, 142 {44, 5220, 331}, {48, 5240, 345}, 143 {52, 5260, 367}, {56, 5280, 401}, 144 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 145 {100, 5500, 131}, {104, 5520, 132}, 146 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 147 {116, 5580, 189}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 148 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 149 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 150 {140, 5700, DFS_TX_LEAKAGE_MIN}, 151 {144, 5720, DFS_TX_LEAKAGE_MIN} 152 } }, 153 154 {116, 5580, 155 {{36, 5180, 384}, {40, 5200, 372}, 156 {44, 5220, 389}, {48, 5240, 396}, 157 {52, 5260, 348}, {56, 5280, 336}, 158 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 159 {100, 5500, 172}, {104, 5520, 169}, 160 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 161 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 162 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 163 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 164 {140, 5700, DFS_TX_LEAKAGE_MIN}, 165 {144, 5720, DFS_TX_LEAKAGE_MIN} 166 } }, 167 168 {120, 5600, 169 {{36, 5180, 395}, {40, 5200, 419}, 170 {44, 5220, 439}, {48, 5240, 407}, 171 {52, 5260, 321}, {56, 5280, 334}, 172 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 173 {100, 5500, 134}, {104, 5520, 186}, 174 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 175 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 176 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 159}, 177 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 178 {140, 5700, DFS_TX_LEAKAGE_MIN}, 179 {144, 5720, DFS_TX_LEAKAGE_MIN} 180 } }, 181 182 {124, 5620, 183 {{36, 5180, 469}, {40, 5200, 433}, 184 {44, 5220, 434}, {48, 5240, 435}, 185 {52, 5260, 332}, {56, 5280, 345}, 186 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 187 {100, 5500, 146}, {104, 5520, 177}, 188 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 189 {116, 5580, 350}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 190 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 138}, 191 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 192 {140, 5700, DFS_TX_LEAKAGE_MIN}, 193 {144, 5720, DFS_TX_LEAKAGE_MIN} 194 } }, 195 196 {128, 5640, 197 {{36, 5180, 408}, {40, 5200, 434}, 198 {44, 5220, 449}, {48, 5240, 444}, 199 {52, 5260, 341}, {56, 5280, 374}, 200 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 201 {100, 5500, 205}, {104, 5520, 208}, 202 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 203 {116, 5580, 142}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 204 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 205 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 206 {140, 5700, DFS_TX_LEAKAGE_MIN}, 207 {144, 5720, DFS_TX_LEAKAGE_MIN} 208 } }, 209 210 {132, 5660, 211 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, 212 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, 213 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 214 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 215 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 216 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 217 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 218 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 219 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 220 {140, 5700, DFS_TX_LEAKAGE_MIN}, 221 {144, 5720, DFS_TX_LEAKAGE_MIN} 222 } }, 223 224 {136, 5680, 225 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, 226 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, 227 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 228 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 229 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 230 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 231 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 232 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 233 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 234 {140, 5700, DFS_TX_LEAKAGE_MIN}, 235 {144, 5720, DFS_TX_LEAKAGE_MIN} 236 } }, 237 238 {140, 5700, 239 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, 240 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, 241 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 242 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 243 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 244 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 245 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 246 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 247 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 248 {144, 5720, DFS_TX_LEAKAGE_MIN} 249 } }, 250 251 {144, 5720, 252 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, 253 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, 254 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 255 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 256 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 257 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 258 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 259 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 260 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 261 {144, 5720, DFS_TX_LEAKAGE_MIN} 262 } }, 263 }; 264 265 /* channel tx leakage table - ht40 */ 266 struct dfs_matrix_tx_leak_info ht40_chan[] = { 267 {52, 5260, 268 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 269 {44, 5220, 230}, {48, 5240, 230}, 270 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 271 {60, 5300, DFS_TX_LEAKAGE_AUTO_MIN}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN}, 272 {100, 5500, 625}, {104, 5520, 323}, 273 {108, 5540, 646}, {112, 5560, 646}, 274 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 275 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 276 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 277 {140, 5700, DFS_TX_LEAKAGE_MAX}, 278 {144, 5720, DFS_TX_LEAKAGE_MIN} 279 } }, 280 281 {56, 5280, 282 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 283 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, 284 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 285 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 286 {100, 5500, 611}, {104, 5520, 611}, 287 {108, 5540, 617}, {112, 5560, 617}, 288 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 289 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 290 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 291 {140, 5700, DFS_TX_LEAKAGE_MAX}, 292 {144, 5720, DFS_TX_LEAKAGE_MIN} 293 } }, 294 295 {60, 5300, 296 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 297 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, 298 {52, 5260, 190}, {56, 5280, 190}, 299 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 300 {100, 5500, 608}, {104, 5520, 608}, 301 {108, 5540, 623}, {112, 5560, 623}, 302 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 303 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 304 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 305 {140, 5700, DFS_TX_LEAKAGE_MAX}, 306 {144, 5720, DFS_TX_LEAKAGE_MIN} 307 } }, 308 309 {64, 5320, 310 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 311 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, 312 {52, 5260, 295}, {56, 5280, 295}, 313 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 314 {100, 5500, 594}, {104, 5520, 594}, 315 {108, 5540, 625}, {112, 5560, 625}, 316 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 317 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 318 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 319 {140, 5700, DFS_TX_LEAKAGE_MAX}, 320 {144, 5720, DFS_TX_LEAKAGE_MIN} 321 } }, 322 323 {100, 5500, 324 {{36, 5180, 618}, {40, 5200, 618}, 325 {44, 5220, 604}, {48, 5240, 604}, 326 {52, 5260, 596}, {56, 5280, 596}, 327 {60, 5300, 584}, {64, 5320, 584}, 328 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 329 {108, 5540, 299}, {112, 5560, 299}, 330 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 331 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 332 {132, 5660, 538}, {136,5680, 538}, 333 {140, 5700, 598}, 334 {144, 5720, DFS_TX_LEAKAGE_MIN} 335 } }, 336 337 {104, 5520, 338 {{36, 5180, 636}, {40, 5200, 636}, 339 {44, 5220, 601}, {48, 5240, 601}, 340 {52, 5260, 616}, {56, 5280, 616}, 341 {60, 5300, 584}, {64, 5320, 584}, 342 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 343 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 344 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 345 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 346 {132, 5660, 553}, {136, 5680, 553}, 347 {140, 5700, 568}, 348 {144, 5720, DFS_TX_LEAKAGE_MIN} 349 } }, 350 351 {108, 5540, 352 {{36, 5180, 600}, {40, 5200, 600}, 353 {44, 5220, 627}, {48, 5240, 627}, 354 {52, 5260, 611}, {56, 5280, 611}, 355 {60, 5300, 611}, {64, 5320, 611}, 356 {100, 5500, 214}, {104, 5520, 214}, 357 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 358 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 359 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 360 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 361 {140, 5700, 534}, 362 {144, 5720, DFS_TX_LEAKAGE_MIN} 363 } }, 364 365 {112, 5560, 366 {{36, 5180, 645}, {40, 5200, 645}, 367 {44, 5220, 641}, {48, 5240, 641}, 368 {52, 5260, 618}, {56, 5280, 618}, 369 {60, 5300, 612}, {64, 5320, 612}, 370 {100, 5500, 293}, {104, 5520, 293}, 371 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 372 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 373 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 374 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 375 {140, 5700, 521}, 376 {144, 5720, DFS_TX_LEAKAGE_MIN} 377 } }, 378 379 {116, 5580, 380 {{36, 5180, 661}, {40, 5200, 661}, 381 {44, 5220, 624}, {48, 5240, 624}, 382 {52, 5260, 634}, {56, 5280, 634}, 383 {60, 5300, 611}, {64, 5320, 611}, 384 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, 385 {108, 5540, 217}, {112, 5560, 217}, 386 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 387 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 388 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 389 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, 390 {144, 5720, DFS_TX_LEAKAGE_MIN} 391 } }, 392 393 {120, 5600, 394 {{36, 5180, 667}, {40, 5200, 667}, 395 {44, 5220, 645}, {48, 5240, 645}, 396 {52, 5260, 633}, {56, 5280, 633}, 397 {60, 5300, 619}, {64, 5320, 619}, 398 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, 399 {108, 5540, 291}, {112, 5560, 291}, 400 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 401 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 402 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 403 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, 404 {144, 5720, DFS_TX_LEAKAGE_MIN} 405 } }, 406 407 {124, 5620, 408 {{36, 5180, 676}, {40, 5200, 676}, 409 {44, 5220, 668}, {48, 5240, 668}, 410 {52, 5260, 595}, {56, 5280, 595}, 411 {60, 5300, 622}, {64, 5320, 622}, 412 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, 413 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 414 {116, 5580, 225}, {120, 5600, 225}, 415 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 416 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, 417 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, 418 {144, 5720, DFS_TX_LEAKAGE_MIN} 419 } }, 420 421 {128, 5640, 422 {{36, 5180, 678}, {40, 5200, 678}, 423 {44, 5220, 664}, {48, 5240, 664}, 424 {52, 5260, 651}, {56, 5280, 651}, 425 {60, 5300, 643}, {64, 5320, 643}, 426 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, 427 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 428 {116, 5580, 293}, {120, 5600, 293}, 429 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 430 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 431 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, 432 {144, 5720, DFS_TX_LEAKAGE_MIN} 433 } }, 434 435 {132, 5660, 436 {{36, 5180, 689}, {40, 5200, 689}, 437 {44, 5220, 669}, {48, 5240, 669}, 438 {52, 5260, 662}, {56, 5280, 662}, 439 {60, 5300, 609}, {64, 5320, 609}, 440 {100, 5500, 538}, {104, 5520, 538}, 441 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 442 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 443 {124, 5620, 247}, {128, 5640, 247}, 444 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 445 {140, 5700, DFS_TX_LEAKAGE_MIN}, 446 {144, 5720, DFS_TX_LEAKAGE_MIN} 447 } }, 448 449 {136, 5680, 450 {{36, 5180, 703}, {40, 5200, 703}, 451 {44, 5220, 688}, {48, 5240, DFS_TX_LEAKAGE_MIN}, 452 {52, 5260, 671}, {56, 5280, 671}, 453 {60, 5300, 658}, {64, 5320, 658}, 454 {100, 5500, 504}, {104, 5520, 504}, 455 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 456 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 457 {124, 5620, 289}, {128, 5640, 289}, 458 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 459 {140, 5700, DFS_TX_LEAKAGE_MIN}, 460 {144, 5720, DFS_TX_LEAKAGE_MIN} 461 } }, 462 463 {140, 5700, 464 {{36, 5180, 695}, {40, 5200, 695}, 465 {44, 5220, 684}, {48, 5240, 684}, 466 {52, 5260, 664}, {56, 5280, 664}, 467 {60, 5300, 658}, {64, 5320, 658}, 468 {100, 5500, 601}, {104, 5520, 601}, 469 {108, 5540, 545}, {112, 5560, 545}, 470 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 471 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 472 {132, 5660, 262}, {136, 5680, 262}, 473 {140, 5700, DFS_TX_LEAKAGE_MIN}, 474 {144, 5720, DFS_TX_LEAKAGE_MIN} 475 } }, 476 477 {144, 5720, 478 {{36, 5180, 695}, {40, 5200, 695}, 479 {44, 5220, 684}, {48, 5240, 684}, 480 {52, 5260, 664}, {56, 5280, 664}, 481 {60, 5300, 658}, {64, 5320, 658}, 482 {100, 5500, 601}, {104, 5520, 601}, 483 {108, 5540, 545}, {112, 5560, 545}, 484 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, 485 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, 486 {132, 5660, 262}, {136, 5680, 262}, 487 {140, 5700, DFS_TX_LEAKAGE_MIN}, 488 {144, 5720, DFS_TX_LEAKAGE_MIN} 489 } }, 490 }; 491 492 /* channel tx leakage table - ht20 */ 493 struct dfs_matrix_tx_leak_info ht20_chan[] = { 494 {52, 5260, 495 {{36, 5180,DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, 286}, 496 {44, 5220, 225}, {48,5240, 121}, 497 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 498 {60, 5300, 300}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN}, 499 {100, 5500, 637}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 500 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 501 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 502 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 503 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 504 {140, 5700, DFS_TX_LEAKAGE_MAX}, 505 {144, 5720, DFS_TX_LEAKAGE_MIN} 506 } }, 507 508 {56, 5280, 509 {{36, 5180, 468}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, 510 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, 206}, 511 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 512 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 513 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 514 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 515 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 516 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 517 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 518 {140, 5700, DFS_TX_LEAKAGE_MAX}, 519 {144, 5720, DFS_TX_LEAKAGE_MIN} 520 } }, 521 522 {60, 5300, 523 {{36, 5180, 507}, {40, 5200, 440}, 524 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48,5240, 313}, 525 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, 526 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 527 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 528 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 529 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 530 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 531 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 532 {140, 5700, DFS_TX_LEAKAGE_MAX}, 533 {144, 5720, DFS_TX_LEAKAGE_MIN} 534 } }, 535 536 {64, 5320 , 537 {{36, 5180, 516}, {40, 5200, 520}, 538 {44, 5220, 506}, {48, 5240,DFS_TX_LEAKAGE_AUTO_MIN}, 539 {52, 5260, 301}, {56, 5280, 258}, 540 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, 541 {100, 5500, 620}, {104, 5520, 617}, 542 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, 543 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, 544 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, 545 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, 546 {140, 5700, DFS_TX_LEAKAGE_MAX}, 547 {144, 5720, DFS_TX_LEAKAGE_MIN} 548 } }, 549 550 {100, 5500, 551 {{36, 5180, 616}, {40, 5200, 601}, 552 {44, 5220, 604}, {48, 5240, 589}, 553 {52, 5260, 612}, {56, 5280, 592}, 554 {60, 5300, 590}, {64, 5320, 582}, 555 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, 131}, 556 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, 557 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, 522}, 558 {124, 5620, 571}, {128, 5640, 589}, 559 {132, 5660, 593}, {136, 5680, 598}, 560 {140, 5700, 594}, 561 {144, 5720, DFS_TX_LEAKAGE_MIN}, 562 } }, 563 564 {104, 5520, 565 {{36, 5180, 622}, {40, 5200, 624}, 566 {44, 5220, 618}, {48, 5240, 610}, 567 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 568 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 569 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 570 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 463}, 571 {116, 5580, 483}, {120, 5600, 503}, 572 {124, 5620, 523}, {128, 5640, 565}, 573 {132, 5660, 570}, {136, 5680, 588}, 574 {140, 5700, 585}, 575 {144, 5720, DFS_TX_LEAKAGE_MIN}, 576 } }, 577 578 {108, 5540, 579 {{36, 5180, 620}, {40, 5200, 638}, 580 {44, 5220, 611}, {48, 5240, 614}, 581 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 582 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 583 {100, 5500, 477}, {104, 5520, DFS_TX_LEAKAGE_MIN}, 584 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 585 {116, 5580, 477}, {120, 5600, 497}, 586 {124, 5620, 517}, {128, 5640, 537}, 587 {132, 5660, 557}, {136, 5680, 577}, 588 {140, 5700, 603}, 589 {144, 5720, DFS_TX_LEAKAGE_MIN}, 590 } }, 591 592 {112, 5560, 593 {{36, 5180, 636}, {40, 5200, 623}, 594 {44, 5220, 638}, {48, 5240, 628}, 595 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 596 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, 606}, 597 {100, 5500, 501}, {104, 5520, 481}, 598 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 599 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, 481}, 600 {124, 5620, 501}, {128, 5640, 421}, 601 {132, 5660, 541}, {136, 5680, 561}, 602 {140, 5700, 583}, 603 {144, 5720, DFS_TX_LEAKAGE_MIN}, 604 } }, 605 606 {116, 5580, 607 {{36, 5180, 646}, {40, 5200, 648}, 608 {44, 5220, 633}, {48, 5240, 634}, 609 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 610 {60, 5300, 615}, {64, 5320, 594}, 611 {100, 5500, 575}, {104, 5520, 554}, 612 {108, 5540, 534}, {112, 5560, DFS_TX_LEAKAGE_MIN}, 613 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 614 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 615 {132, 5660, 534}, {136, 5680, 554}, 616 {140, 5700, 574}, 617 {144, 5720, DFS_TX_LEAKAGE_MIN}, 618 } }, 619 620 {120, 5600, 621 {{36, 5180, 643}, {40, 5200, 649}, 622 {44, 5220, 654}, {48, 5240, 629}, 623 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, 621}, 624 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 625 {100, 5500, 565}, {104, 5520, 545}, 626 {108, 5540, 525}, {112, 5560, 505}, 627 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 628 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 505}, 629 {132, 5660, 525}, {136, 5680, 545}, 630 {140, 5700, 565}, 631 {144, 5720, DFS_TX_LEAKAGE_MIN}, 632 } }, 633 634 {124, 5620, 635 {{36, 5180, 638}, {40, 5200, 657}, 636 {44, 5220, 663}, {48, 5240, 649}, 637 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 638 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 639 {100, 5500, 581}, {104, 5520, 561}, 640 {108, 5540, 541}, {112, 5560, 521}, 641 {116, 5580, 499}, {120, 5600, DFS_TX_LEAKAGE_MIN}, 642 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 643 {132, 5660, 499}, {136, 5680, 519}, 644 {140, 5700, 539}, 645 {144, 5720, DFS_TX_LEAKAGE_MIN} 646 } }, 647 648 {128, 5640, 649 {{36, 5180, 651}, {40, 5200, 651}, 650 {44, 5220, 674}, {48, 5240, 640}, 651 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 652 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 653 {100, 5500, 603}, {104, 5520, 560}, 654 {108, 5540, 540}, {112, 5560, 520}, 655 {116, 5580, 499}, {120, 5600, 479}, 656 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 657 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, 479}, 658 {140, 5700, 499}, 659 {144, 5720, DFS_TX_LEAKAGE_MIN} 660 } }, 661 662 {132, 5660, 663 {{36, 5180, 643}, {40, 5200, 668}, 664 {44, 5220, 651}, {48, 5240, 657}, 665 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 666 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 667 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, 602}, 668 {108, 5540, 578}, {112,5560, 570}, 669 {116, 5580, 550}, {120, 5600, 530}, 670 {124, 5620, 510}, {128, 5640, DFS_TX_LEAKAGE_MIN}, 671 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 672 {140, 5700, 490}, 673 {144, 5720, DFS_TX_LEAKAGE_MIN} 674 } }, 675 676 {136,5680, 677 {{36, 5180, 654}, {40, 5200, 667}, 678 {44, 5220, 666}, {48, 5240, 642}, 679 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, 680 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, 681 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 682 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 596}, 683 {116, 5580, 555}, {120, 5600, 535}, 684 {124, 5620, 515}, {128, 5640, 495}, 685 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 686 {140, 5700, DFS_TX_LEAKAGE_MIN}, 687 {144, 5720, DFS_TX_LEAKAGE_MIN} 688 } }, 689 690 {140,5700, 691 {{36, 5180, 679}, {40, 5200, 673}, 692 {44, 5220, 667}, {48, 5240, 656}, 693 {52, 5260, 634}, {56, 5280, 663}, 694 {60, 5300, 662}, {64, 5320, 660}, 695 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 696 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590}, 697 {116, 5580, 573}, {120, 5600, 553}, 698 {124, 5620, 533}, {128, 5640, 513}, 699 {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 700 {140, 5700, DFS_TX_LEAKAGE_MIN}, 701 {144, 5720, DFS_TX_LEAKAGE_MIN} 702 } }, 703 704 {144,5720, 705 {{36, 5180, 679}, {40, 5200, 673}, 706 {44, 5220, 667}, {48, 5240, 656}, 707 {52, 5260, 634}, {56, 5280, 663}, 708 {60, 5300, 662}, {64, 5320, 660}, 709 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, 710 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590}, 711 {116, 5580, 573}, {120, 5600, 553}, 712 {124, 5620, 533}, {128, 5640, 513}, 713 {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN}, 714 {140, 5700, DFS_TX_LEAKAGE_MIN}, 715 {144, 5720, DFS_TX_LEAKAGE_MIN} 716 } }, 717 }; 718 719 /* 720 * dfs_find_target_channel_in_channel_matrix_for_freq() - finds the leakage 721 * matrix. 722 * @chan_width: target channel width 723 * @nol_channel: the NOL channel frequency whose leakage matrix is required 724 * @pTarget_chnl_mtrx: pointer to target channel matrix returned. 725 * 726 * This function gives the leakage matrix for given NOL channel and ch_width 727 * 728 * Return: TRUE or FALSE 729 */ 730 #ifdef CONFIG_CHAN_FREQ_API 731 static bool 732 dfs_find_target_channel_in_channel_matrix_for_freq(enum phy_ch_width chan_width, 733 uint16_t nol_freq, 734 struct dfs_tx_leak_info 735 **pTarget_chnl_mtrx) 736 { 737 struct dfs_tx_leak_info *target_chan_matrix = NULL; 738 struct dfs_matrix_tx_leak_info *pchan_matrix = NULL; 739 uint32_t nchan_matrix; 740 int i = 0; 741 742 switch (chan_width) { 743 case CH_WIDTH_20MHZ: 744 /* HT20 */ 745 pchan_matrix = ht20_chan; 746 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 747 break; 748 case CH_WIDTH_40MHZ: 749 /* HT40 */ 750 pchan_matrix = ht40_chan; 751 nchan_matrix = QDF_ARRAY_SIZE(ht40_chan); 752 break; 753 case CH_WIDTH_80MHZ: 754 /* HT80 */ 755 pchan_matrix = ht80_chan; 756 nchan_matrix = QDF_ARRAY_SIZE(ht80_chan); 757 break; 758 default: 759 /* handle exception and fall back to HT20 table */ 760 pchan_matrix = ht20_chan; 761 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 762 break; 763 } 764 765 for (i = 0; i < nchan_matrix; i++) { 766 /* find the SAP channel to map the leakage matrix */ 767 if (nol_freq == pchan_matrix[i].channel_freq) { 768 target_chan_matrix = pchan_matrix[i].chan_matrix; 769 break; 770 } 771 } 772 773 if (!target_chan_matrix) { 774 return false; 775 } else { 776 *pTarget_chnl_mtrx = target_chan_matrix; 777 return true; 778 } 779 } 780 #endif 781 782 #ifdef CONFIG_CHAN_FREQ_API 783 784 #ifdef CONFIG_BAND_6GHZ 785 #define END_CHAN_INDEX CHAN_ENUM_7115 786 #else 787 #define END_CHAN_INDEX CHAN_ENUM_5720 788 #endif 789 790 #define START_CHAN_INDEX CHAN_ENUM_5180 791 QDF_STATUS 792 dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, 793 enum phy_ch_width ch_width, 794 uint8_t temp_chan_lst_sz, 795 uint16_t *temp_freq_lst) 796 { 797 struct dfs_tx_leak_info *target_chan_matrix = NULL; 798 uint32_t num_channel = (END_CHAN_INDEX - START_CHAN_INDEX) + 1; 799 uint32_t j = 0; 800 uint32_t k = 0; 801 struct dfs_nolelem *nol; 802 803 nol = dfs->dfs_nol; 804 while (nol) { 805 if (false == dfs_find_target_channel_in_channel_matrix_for_freq( 806 ch_width, nol->nol_freq, 807 &target_chan_matrix)) { 808 /* 809 * should never happen, we should always find a table 810 * here, if we don't, need a fix here! 811 */ 812 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 813 "Couldn't find target channel matrix!"); 814 QDF_ASSERT(0); 815 return QDF_STATUS_E_FAILURE; 816 } 817 /* 818 * following is based on assumption that both temp_freq_lst 819 * and target channel matrix are in increasing order of 820 * ch_id 821 */ 822 for (j = 0, k = 0; j < temp_chan_lst_sz && k < num_channel;) { 823 if (temp_freq_lst[j] == 0) { 824 j++; 825 continue; 826 } 827 if (target_chan_matrix[k].leak_chan_freq != 828 temp_freq_lst[j]) { 829 k++; 830 continue; 831 } 832 /* 833 * check leakage from candidate channel 834 * to NOL channel 835 */ 836 if (target_chan_matrix[k].leak_lvl <= 837 dfs->tx_leakage_threshold) { 838 /* 839 * candidate channel will have 840 * bad leakage in NOL channel, 841 * remove from temp list 842 */ 843 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 844 "dfs: channel: %d will have bad leakage due to channel: %d\n", 845 nol->nol_freq, temp_freq_lst[j]); 846 temp_freq_lst[j] = 0; 847 } 848 j++; 849 k++; 850 } 851 nol = nol->nol_next; 852 } /* end of loop that selects each NOL */ 853 854 return QDF_STATUS_SUCCESS; 855 } 856 #endif 857 #else 858 #ifdef CONFIG_CHAN_FREQ_API 859 QDF_STATUS 860 dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, 861 enum phy_ch_width ch_width, 862 uint8_t temp_chan_lst_sz, 863 uint16_t *temp_freq_lst) 864 { 865 return QDF_STATUS_SUCCESS; 866 } 867 #endif 868 #endif 869 870 /* 871 * dfs_populate_80mhz_available_channel_for_freq() - Populate 80MHZ channels 872 * available for selection. 873 * @dfs: Pointer to wlan_dfs. 874 * @bitmap: Pointer to bonding channel bitmap. 875 * @avail_freq_list: Pointer to frequency list of available channels. 876 */ 877 #ifdef CONFIG_CHAN_FREQ_API 878 static uint8_t dfs_populate_80mhz_available_channel_for_freq( 879 struct wlan_dfs *dfs, 880 struct chan_bonding_bitmap *bitmap, 881 uint16_t *avail_freq_list) 882 { 883 uint8_t i = 0; 884 uint8_t chnl_count = 0; 885 uint16_t start_chan_freq = 0; 886 887 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 888 start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; 889 if (bitmap->chan_bonding_set[i].chan_map == 890 DFS_80MHZ_MASK) { 891 avail_freq_list[chnl_count++] = start_chan_freq + 892 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0); 893 avail_freq_list[chnl_count++] = start_chan_freq + 894 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1); 895 avail_freq_list[chnl_count++] = start_chan_freq + 896 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2); 897 avail_freq_list[chnl_count++] = start_chan_freq + 898 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3); 899 } 900 } 901 902 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 903 "channel count %d", chnl_count); 904 905 return chnl_count; 906 } 907 #endif 908 909 #ifdef CONFIG_CHAN_FREQ_API 910 static uint8_t 911 dfs_populate_40mhz_available_channel_for_freq(struct wlan_dfs *dfs, 912 struct chan_bonding_bitmap *bmap, 913 uint16_t *avail_freq_list) 914 { 915 uint8_t i = 0; 916 uint8_t chnl_count = 0; 917 uint16_t start_chan_freq = 0; 918 919 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 920 start_chan_freq = bmap->chan_bonding_set[i].start_chan_freq; 921 if ((bmap->chan_bonding_set[i].chan_map & 922 DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) { 923 avail_freq_list[chnl_count++] = start_chan_freq + 924 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0); 925 avail_freq_list[chnl_count++] = start_chan_freq + 926 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1); 927 } 928 if ((bmap->chan_bonding_set[i].chan_map & 929 DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) { 930 avail_freq_list[chnl_count++] = start_chan_freq + 931 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2); 932 avail_freq_list[chnl_count++] = start_chan_freq + 933 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3); 934 } 935 } 936 937 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 938 "channel count %d", chnl_count); 939 940 return chnl_count; 941 } 942 #endif 943 944 /** 945 * dfs_populate_available_channel_for_freq()- Populate channels based on width 946 * and bitmap. 947 * @dfs: Pointer to DFS structure. 948 * @bitmap: bitmap 949 * @chan_width: channel width 950 * @freq_list: prepared channel list 951 * 952 * Prepare channel list based on width and channel bitmap. 953 * 954 * Return: channel count 955 */ 956 #ifdef CONFIG_CHAN_FREQ_API 957 static uint8_t 958 dfs_populate_available_channel_for_freq(struct wlan_dfs *dfs, 959 struct chan_bonding_bitmap *bitmap, 960 uint16_t chan_width, 961 uint16_t *freq_list) 962 { 963 switch (chan_width) { 964 case DFS_CH_WIDTH_320MHZ: 965 case DFS_CH_WIDTH_160MHZ: 966 case DFS_CH_WIDTH_80P80MHZ: 967 case DFS_CH_WIDTH_80MHZ: 968 return dfs_populate_80mhz_available_channel_for_freq(dfs, 969 bitmap, 970 freq_list); 971 case DFS_CH_WIDTH_40MHZ: 972 return dfs_populate_40mhz_available_channel_for_freq(dfs, 973 bitmap, 974 freq_list); 975 default: 976 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 977 "Invalid chan_width %d", chan_width); 978 break; 979 } 980 981 return 0; 982 } 983 #endif 984 985 /** 986 * dfs_get_rand_from_lst_for_freq()- Get random channel from a given channel 987 * list. 988 * @dfs: Pointer to DFS structure. 989 * @freq_lst: Frequency list 990 * @num_chan: number of channels 991 * 992 * Get random channel from given channel list. 993 * 994 * Return: channel frequency. 995 */ 996 997 #ifdef CONFIG_CHAN_FREQ_API 998 static uint16_t dfs_get_rand_from_lst_for_freq(struct wlan_dfs *dfs, 999 uint16_t *freq_lst, 1000 uint8_t num_chan) 1001 { 1002 uint8_t i; 1003 uint32_t rand_byte = 0; 1004 1005 if (!num_chan || !freq_lst) { 1006 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, 1007 "invalid param freq_lst %pK, num_chan = %d", 1008 freq_lst, num_chan); 1009 return 0; 1010 } 1011 1012 get_random_bytes((uint8_t *)&rand_byte, 1); 1013 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_chan; 1014 1015 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1016 "random chan freq %d", freq_lst[i]); 1017 1018 return freq_lst[i]; 1019 } 1020 #endif 1021 1022 #ifdef CONFIG_CHAN_FREQ_API 1023 #define FREQUENCY_BAND_LIMIT 60 1024 1025 /** 1026 * dfs_random_channel_sel_set_bitmap_for_freq()- Set channel bit in bitmap based 1027 * on given channel number 1028 * @dfs: Pointer to DFS structure. 1029 * @bitmap: bitmap 1030 * @chan_freq: channel frequency 1031 * 1032 * Set channel bit in bitmap based on given channel frequency. 1033 * 1034 * Return: None 1035 */ 1036 static void 1037 dfs_random_channel_sel_set_bitmap_for_freq(struct wlan_dfs *dfs, 1038 struct chan_bonding_bitmap *bitmap, 1039 uint16_t chan_freq) 1040 { 1041 int i = 0; 1042 int start_chan_freq = 0; 1043 1044 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1045 start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; 1046 if (chan_freq >= start_chan_freq && 1047 chan_freq <= start_chan_freq + 1048 FREQUENCY_BAND_LIMIT) { 1049 bitmap->chan_bonding_set[i].chan_map |= 1050 (1 << ((chan_freq - start_chan_freq) / 1051 DFS_80_NUM_SUB_CHANNEL_FREQ)); 1052 return; 1053 } 1054 } 1055 1056 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1057 "Frequency=%d is not in the bitmap", chan_freq); 1058 } 1059 #endif 1060 1061 #ifdef CONFIG_BAND_6GHZ 1062 /** 1063 * dfs_assign_6g_channels()- Assign the center frequency of the first 20 MHZ 1064 * channel in every 80MHz channel, present in the 6G band. 1065 * @ch_map: Pointer to ch_map. 1066 * 1067 * Return: Void 1068 */ 1069 static void dfs_assign_6g_channels(struct chan_bonding_bitmap *ch_map) 1070 { 1071 ch_map->chan_bonding_set[7].start_chan_freq = 5955; 1072 ch_map->chan_bonding_set[8].start_chan_freq = 6035; 1073 ch_map->chan_bonding_set[9].start_chan_freq = 6115; 1074 ch_map->chan_bonding_set[10].start_chan_freq = 6195; 1075 ch_map->chan_bonding_set[11].start_chan_freq = 6275; 1076 ch_map->chan_bonding_set[12].start_chan_freq = 6355; 1077 ch_map->chan_bonding_set[13].start_chan_freq = 6435; 1078 ch_map->chan_bonding_set[14].start_chan_freq = 6515; 1079 ch_map->chan_bonding_set[15].start_chan_freq = 6595; 1080 ch_map->chan_bonding_set[16].start_chan_freq = 6675; 1081 ch_map->chan_bonding_set[17].start_chan_freq = 6755; 1082 ch_map->chan_bonding_set[18].start_chan_freq = 6835; 1083 ch_map->chan_bonding_set[19].start_chan_freq = 6915; 1084 ch_map->chan_bonding_set[20].start_chan_freq = 6995; 1085 } 1086 #else 1087 static inline void dfs_assign_6g_channels(struct chan_bonding_bitmap *ch_map) 1088 { 1089 } 1090 #endif 1091 1092 /** 1093 * dfs_find_num_sub_channels_for_chwidth_320_160() - Find the max number 1094 * of sub channels for the given channel width (320/160) 1095 * @chan_width: Channel width 1096 * 1097 * Return - Number of sub-channels 1098 */ 1099 static uint8_t 1100 dfs_find_num_sub_channels_for_chwidth_320_160(uint16_t chan_width) 1101 { 1102 if (chan_width == DFS_CH_WIDTH_160MHZ) 1103 return DFS_MAX_NUM_160_SUBCHAN; 1104 else if (chan_width == DFS_CH_WIDTH_320MHZ) 1105 return DFS_MAX_NUM_240_SUBCHAN; 1106 1107 return 0; 1108 } 1109 1110 /** 1111 * dfs_find_next_chan_start_freq_for_320_160() - Find the next 160/320 channel's 1112 * start freq based on the available channel list. Validate the 1113 * continuity of the sub channels of 160/320M BW, if they are contiguous 1114 * declare channel to be found. Return the start_freq of the channel band found. 1115 * @chan_count: Total number of available channels. 1116 * @freq_list: Available list of frequency 1117 * @chan_width: Target channel width 1118 * @chan_found: Bool to indicate if channel is found 1119 * 1120 * Return: Next chan's start freq 1121 */ 1122 1123 static qdf_freq_t 1124 dfs_find_next_chan_start_freq_for_320_160(uint8_t chan_count, 1125 uint16_t *freq_list, 1126 uint16_t chan_width, bool *chan_found) 1127 { 1128 uint8_t i; 1129 uint8_t count = 0; 1130 qdf_freq_t next_chan_start_freq = 0; 1131 uint8_t num_sub_chans = 1132 dfs_find_num_sub_channels_for_chwidth_320_160(chan_width); 1133 1134 for (i = 1; i < chan_count; i++) { 1135 if ((freq_list[i] - freq_list[i - 1]) == 1136 DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET) 1137 count++; 1138 else 1139 count = 0; 1140 if (count == num_sub_chans - 1) { 1141 *chan_found = true; 1142 next_chan_start_freq = freq_list[i - count]; 1143 break; 1144 } 1145 } 1146 return next_chan_start_freq; 1147 } 1148 1149 /** 1150 * dfs_find_ch_with_fallback_for_freq()- find random channel 1151 * @dfs: Pointer to DFS structure. 1152 * @chan_wd: channel width 1153 * @center_freq_seg1: center frequency of secondary segment. 1154 * @freq_lst: list of available frequency. 1155 * @num_chan: number of channels in the list. 1156 * 1157 * Find random channel based on given channel width and channel list, 1158 * fallback to lower width if requested channel width not available. 1159 * 1160 * Return: channel frequency. 1161 */ 1162 #ifdef CONFIG_CHAN_FREQ_API 1163 static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs, 1164 uint16_t *chan_wd, 1165 qdf_freq_t *center_freq_seg1, 1166 uint16_t *freq_lst, 1167 uint32_t num_chan) 1168 { 1169 bool flag = false; 1170 uint32_t rand_byte = 0; 1171 struct chan_bonding_bitmap ch_map = { { {0} } }; 1172 uint8_t i, index = 0, final_cnt = 0; 1173 uint16_t target_channel = 0; 1174 uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_start_ch = 0; 1175 uint16_t final_lst[NUM_CHANNELS] = {0}; 1176 1177 /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ 1178 ch_map.chan_bonding_set[0].start_chan_freq = 5180; 1179 ch_map.chan_bonding_set[1].start_chan_freq = 5260; 1180 ch_map.chan_bonding_set[2].start_chan_freq = 5500; 1181 ch_map.chan_bonding_set[3].start_chan_freq = 5580; 1182 ch_map.chan_bonding_set[4].start_chan_freq = 5660; 1183 ch_map.chan_bonding_set[5].start_chan_freq = 5745; 1184 ch_map.chan_bonding_set[6].start_chan_freq = 5825; 1185 1186 dfs_assign_6g_channels(&ch_map); 1187 for (i = 0; i < num_chan; i++) { 1188 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1189 "channel = %d added to bitmap", freq_lst[i]); 1190 dfs_random_channel_sel_set_bitmap_for_freq(dfs, &ch_map, 1191 freq_lst[i]); 1192 } 1193 1194 /* populate available channel list from bitmap */ 1195 final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map, 1196 *chan_wd, final_lst); 1197 1198 /* If no valid 80mhz bonded chan found, fallback */ 1199 if (final_cnt == 0) { 1200 if ((*chan_wd == DFS_CH_WIDTH_320MHZ) || 1201 (*chan_wd == DFS_CH_WIDTH_160MHZ) || 1202 (*chan_wd == DFS_CH_WIDTH_80P80MHZ) || 1203 (*chan_wd == DFS_CH_WIDTH_80MHZ)) { 1204 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1205 "from [%d] to 40Mhz", *chan_wd); 1206 *chan_wd = DFS_CH_WIDTH_40MHZ; 1207 } else if (*chan_wd == DFS_CH_WIDTH_40MHZ) { 1208 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1209 "from 40Mhz to 20MHz"); 1210 *chan_wd = DFS_CH_WIDTH_20MHZ; 1211 } 1212 return 0; 1213 } 1214 1215 /* ch count should be > 8 to switch new channel in 160Mhz band */ 1216 if (((*chan_wd == DFS_CH_WIDTH_160MHZ) || 1217 (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) && 1218 (final_cnt < DFS_MAX_NUM_160_SUBCHAN)) { 1219 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1220 "from [%d] to 80Mhz", *chan_wd); 1221 *chan_wd = DFS_CH_WIDTH_80MHZ; 1222 return 0; 1223 } 1224 1225 /* ch count should be 12 to switch new 320 channel band (240MHZ) */ 1226 if (*chan_wd == DFS_CH_WIDTH_320MHZ) { 1227 if (final_cnt < DFS_MAX_NUM_240_SUBCHAN) { 1228 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1229 "from [%d] to 160Mhz", *chan_wd); 1230 *chan_wd = DFS_CH_WIDTH_160MHZ; 1231 return 0; 1232 } 1233 } 1234 1235 if (*chan_wd == DFS_CH_WIDTH_320MHZ || 1236 *chan_wd == DFS_CH_WIDTH_160MHZ) { 1237 /* 1238 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128 1239 * and all the channels in these blocks are continuous 1240 * and separated by 4Mhz. 1241 * Only 1 block of 240 channel is 1242 * available from 100 - 140 comprising of 12 sub 20 channels. 1243 * These are continuous and separated by 20MHZ in 1244 * frequency spectrum. 1245 */ 1246 new_start_ch = 1247 dfs_find_next_chan_start_freq_for_320_160(final_cnt, 1248 final_lst, 1249 *chan_wd, 1250 &flag); 1251 } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { 1252 flag = true; 1253 } 1254 1255 if (!flag) { 1256 if (*chan_wd == DFS_CH_WIDTH_320MHZ) { 1257 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1258 "from [%d] to 160Mhz", *chan_wd); 1259 *chan_wd = DFS_CH_WIDTH_160MHZ; 1260 return 0; 1261 } else if (*chan_wd == DFS_CH_WIDTH_160MHZ) { 1262 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1263 "from [%d] to 80Mhz", *chan_wd); 1264 *chan_wd = DFS_CH_WIDTH_80MHZ; 1265 return 0; 1266 } 1267 } 1268 1269 if (*chan_wd == DFS_CH_WIDTH_320MHZ || 1270 *chan_wd == DFS_CH_WIDTH_160MHZ) { 1271 get_random_bytes((uint8_t *)&rand_byte, 1); 1272 rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) 1273 % dfs_find_num_sub_channels_for_chwidth_320_160 1274 (*chan_wd); 1275 target_channel = new_start_ch + (rand_byte * 1276 DFS_80_NUM_SUB_CHANNEL_FREQ); 1277 } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { 1278 get_random_bytes((uint8_t *)&rand_byte, 1); 1279 index = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1280 final_cnt; 1281 target_channel = final_lst[index]; 1282 index -= (index % DFS_80_NUM_SUB_CHANNEL); 1283 primary_seg_start_ch = final_lst[index]; 1284 1285 /* reset channels associate with primary 80Mhz */ 1286 for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++) 1287 final_lst[i + index] = 0; 1288 /* select and calculate center freq for secondary segment */ 1289 for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) { 1290 if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] && 1291 (abs(primary_seg_start_ch - 1292 final_lst[i * DFS_80_NUM_SUB_CHANNEL]) > 1293 (DFS_80P80M_FREQ_DIFF * 2))) { 1294 sec_seg_ch = final_lst[i * 1295 DFS_80_NUM_SUB_CHANNEL] + 1296 DFS_80MHZ_START_CENTER_CH_FREQ_DIFF; 1297 break; 1298 } 1299 } 1300 1301 if (!sec_seg_ch && (final_cnt == DFS_MAX_NUM_160_SUBCHAN)) 1302 *chan_wd = DFS_CH_WIDTH_160MHZ; 1303 else if (!sec_seg_ch) 1304 *chan_wd = DFS_CH_WIDTH_80MHZ; 1305 1306 *center_freq_seg1 = sec_seg_ch; 1307 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1308 "Center frequency seg1 = %d", sec_seg_ch); 1309 } else { 1310 target_channel = dfs_get_rand_from_lst_for_freq(dfs, 1311 final_lst, 1312 final_cnt); 1313 } 1314 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1315 "target channel = %d", target_channel); 1316 1317 return target_channel; 1318 } 1319 #endif 1320 1321 bool dfs_is_freq_in_nol(struct wlan_dfs *dfs, uint32_t freq) 1322 { 1323 struct dfs_nolelem *nol; 1324 1325 if (!dfs) { 1326 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "null dfs"); 1327 return false; 1328 } 1329 1330 nol = dfs->dfs_nol; 1331 while (nol) { 1332 if (freq == nol->nol_freq) { 1333 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1334 "%d is in nol", freq); 1335 return true; 1336 } 1337 nol = nol->nol_next; 1338 } 1339 1340 return false; 1341 } 1342 1343 /** 1344 * dfs_apply_rules_for_freq()- prepare channel list based on flags 1345 * @dfs: dfs handler 1346 * @flags: channel flags 1347 * @random_chan_freq_list: output channel list 1348 * @random_chan_cnt: output channel count 1349 * @chan_list: input channel list 1350 * @chan_cnt: input channel count 1351 * @dfs_region: dfs region 1352 * @acs_info: acs channel range information 1353 * 1354 * prepare channel list based on flags 1355 * 1356 * return: none 1357 */ 1358 #ifdef CONFIG_CHAN_FREQ_API 1359 static void dfs_apply_rules_for_freq(struct wlan_dfs *dfs, 1360 uint32_t flags, 1361 uint16_t *random_chan_freq_list, 1362 uint32_t *random_chan_cnt, 1363 struct dfs_channel *chan_list, 1364 uint32_t chan_cnt, 1365 uint8_t dfs_region, 1366 struct dfs_acs_info *acs_info) 1367 { 1368 struct dfs_channel *chan; 1369 bool flag_no_weather = 0; 1370 bool flag_no_lower_5g = 0; 1371 bool flag_no_upper_5g = 0; 1372 bool flag_no_dfs_chan = 0; 1373 bool flag_no_2g_chan = 0; 1374 bool flag_no_5g_chan = 0; 1375 bool flag_no_japan_w53 = 0; 1376 bool flag_no_6g_freq; 1377 int i; 1378 bool found = false; 1379 uint16_t j; 1380 uint16_t freq_list[MAX_20MHZ_SUBCHANS]; 1381 uint8_t num_channels = 0; 1382 1383 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags); 1384 flag_no_weather = (dfs_region == DFS_ETSI_REGION) ? 1385 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 1386 1387 if (dfs_region == DFS_MKK_REGION || 1388 dfs_region == DFS_MKKN_REGION) { 1389 flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH; 1390 flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH; 1391 flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH; 1392 } 1393 1394 flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH; 1395 flag_no_2g_chan = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH; 1396 flag_no_5g_chan = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH; 1397 flag_no_6g_freq = flags & DFS_RANDOM_CH_FLAG_NO_6GHZ_CH; 1398 1399 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { 1400 num_channels = 1401 dfs_get_bonding_channel_without_seg_info_for_freq 1402 (dfs->dfs_curchan, freq_list); 1403 } 1404 1405 for (i = 0; i < chan_cnt; i++) { 1406 chan = &chan_list[i]; 1407 found = false; 1408 1409 if ((chan->dfs_ch_ieee == 0) || 1410 (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) { 1411 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1412 "invalid channel %d", chan->dfs_ch_ieee); 1413 continue; 1414 } 1415 1416 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { 1417 for (j = 0; j < num_channels; j++) { 1418 if (chan->dfs_ch_freq == freq_list[j]) { 1419 dfs_debug(dfs, 1420 WLAN_DEBUG_DFS_RANDOM_CHAN, 1421 "skip %d current operating channel", 1422 chan->dfs_ch_freq); 1423 found = true; 1424 break; 1425 } 1426 } 1427 1428 if (found) 1429 continue; 1430 } 1431 1432 if (acs_info && acs_info->acs_mode) { 1433 for (j = 0; j < acs_info->num_of_channel; j++) { 1434 if (acs_info->chan_freq_list[j] == 1435 chan->dfs_ch_freq) { 1436 found = true; 1437 break; 1438 } 1439 } 1440 1441 if (!found) { 1442 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1443 "skip ch freq %d not in acs range", 1444 chan->dfs_ch_freq); 1445 continue; 1446 } 1447 found = false; 1448 } 1449 1450 if (flag_no_2g_chan && 1451 chan->dfs_ch_freq <= DFS_MAX_24GHZ_CHANNEL_FREQ) { 1452 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1453 "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee); 1454 continue; 1455 } 1456 1457 if (flag_no_5g_chan && 1458 WLAN_REG_IS_5GHZ_CH_FREQ(chan->dfs_ch_freq)) { 1459 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1460 "skip 5 GHz channel=%d", chan->dfs_ch_ieee); 1461 continue; 1462 } 1463 1464 if (flag_no_weather) { 1465 if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) { 1466 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1467 "skip weather channel=%d", 1468 chan->dfs_ch_ieee); 1469 continue; 1470 } 1471 } 1472 1473 if (flag_no_lower_5g && 1474 DFS_IS_CHAN_JAPAN_INDOOR_FREQ(chan->dfs_ch_freq)) { 1475 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1476 "skip indoor channel=%d", chan->dfs_ch_ieee); 1477 continue; 1478 } 1479 1480 if (flag_no_upper_5g && 1481 DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(chan->dfs_ch_freq)) { 1482 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1483 "skip outdoor channel=%d", chan->dfs_ch_ieee); 1484 continue; 1485 } 1486 1487 if (flag_no_6g_freq && 1488 WLAN_REG_IS_6GHZ_CHAN_FREQ(chan->dfs_ch_freq)) { 1489 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1490 "skip 6 GHz channel=%d", chan->dfs_ch_ieee); 1491 continue; 1492 } 1493 1494 if (flag_no_dfs_chan && 1495 (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) { 1496 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1497 "skip dfs channel=%d", chan->dfs_ch_ieee); 1498 continue; 1499 } 1500 1501 if (flag_no_japan_w53 && 1502 DFS_IS_CHAN_JAPAN_W53_FREQ(chan->dfs_ch_freq)) { 1503 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1504 "skip japan W53 channel=%d", 1505 chan->dfs_ch_ieee); 1506 continue; 1507 } 1508 1509 if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) { 1510 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1511 "skip nol channel=%d", chan->dfs_ch_ieee); 1512 continue; 1513 } 1514 1515 random_chan_freq_list[*random_chan_cnt] = chan->dfs_ch_freq; 1516 *random_chan_cnt += 1; 1517 } 1518 } 1519 #endif 1520 1521 /** 1522 * dfs_remove_spruce_spur_channels_for_bw_20_40() - API to remove the 1523 * spur channels in spruce if current bw is 20/40MHz. 1524 * @freq_list: Input list from which spur channels are removed. 1525 * @freq_count: Input list count. 1526 * 1527 * return: void. 1528 */ 1529 static void 1530 dfs_remove_spruce_spur_channels_for_bw_20_40(uint16_t *freq_list, 1531 uint8_t freq_count) 1532 { 1533 uint8_t i; 1534 1535 for (i = 0; i < freq_count; i++) { 1536 if (DFS_IS_CHAN_SPRUCE_SPUR_FREQ_20_40_MHZ(freq_list[i])) 1537 freq_list[i] = 0; 1538 } 1539 } 1540 1541 #ifdef CONFIG_CHAN_FREQ_API 1542 uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs, 1543 struct dfs_channel *chan_list, 1544 uint32_t chan_cnt, 1545 uint32_t flags, 1546 struct ch_params *chan_params, 1547 uint8_t dfs_region, 1548 struct dfs_acs_info *acs_info) 1549 { 1550 int i = 0; 1551 uint8_t final_cnt = 0; 1552 uint16_t target_freq = 0; 1553 uint16_t *random_chan_freq_list = NULL; 1554 uint32_t random_chan_cnt = 0; 1555 uint16_t flag_no_weather = 0; 1556 uint16_t *leakage_adjusted_lst; 1557 uint16_t final_lst[NUM_CHANNELS] = {0}; 1558 uint16_t *chan_wd = (uint16_t *)&chan_params->ch_width; 1559 bool flag_no_spur_leakage_adj_chans = false; 1560 1561 if (!chan_list || !chan_cnt) { 1562 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1563 "Invalid params %pK, chan_cnt=%d", 1564 chan_list, chan_cnt); 1565 return 0; 1566 } 1567 1568 if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_320MHZ) { 1569 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1570 "Invalid chan_wd %d", *chan_wd); 1571 return 0; 1572 } 1573 1574 random_chan_freq_list = 1575 qdf_mem_malloc(chan_cnt * sizeof(*random_chan_freq_list)); 1576 if (!random_chan_freq_list) 1577 return 0; 1578 1579 dfs_apply_rules_for_freq(dfs, flags, random_chan_freq_list, 1580 &random_chan_cnt, chan_list, chan_cnt, 1581 dfs_region, acs_info); 1582 flag_no_weather = (dfs_region == DFS_ETSI_REGION) ? 1583 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 1584 flag_no_spur_leakage_adj_chans = 1585 flags & DFS_RANDOM_CH_FLAG_NO_SPRUCE_SPUR_ADJ_CH; 1586 1587 /* list adjusted after leakage has been marked */ 1588 leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt * 1589 sizeof(*leakage_adjusted_lst)); 1590 if (!leakage_adjusted_lst) { 1591 qdf_mem_free(random_chan_freq_list); 1592 return 0; 1593 } 1594 1595 if (flag_no_spur_leakage_adj_chans && 1596 (*chan_wd == DFS_CH_WIDTH_20MHZ || 1597 *chan_wd == DFS_CH_WIDTH_40MHZ)) 1598 dfs_remove_spruce_spur_channels_for_bw_20_40( 1599 random_chan_freq_list, 1600 random_chan_cnt); 1601 do { 1602 int ret; 1603 1604 qdf_mem_copy(leakage_adjusted_lst, random_chan_freq_list, 1605 random_chan_cnt * sizeof(*leakage_adjusted_lst)); 1606 ret = dfs_mark_leaking_chan_for_freq(dfs, *chan_wd, 1607 random_chan_cnt, 1608 leakage_adjusted_lst); 1609 if (QDF_IS_STATUS_ERROR(ret)) { 1610 qdf_mem_free(random_chan_freq_list); 1611 qdf_mem_free(leakage_adjusted_lst); 1612 return 0; 1613 } 1614 1615 if (*chan_wd == DFS_CH_WIDTH_20MHZ) { 1616 /* 1617 * PASS: 3 - from leakage_adjusted_lst, prepare valid 1618 * ch list and use random number from that 1619 */ 1620 for (i = 0; i < random_chan_cnt; i++) { 1621 if (leakage_adjusted_lst[i] == 0) 1622 continue; 1623 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1624 "Chan freq =%d added to available list", 1625 leakage_adjusted_lst[i]); 1626 final_lst[final_cnt] = leakage_adjusted_lst[i]; 1627 final_cnt++; 1628 } 1629 target_freq = dfs_get_rand_from_lst_for_freq(dfs, 1630 final_lst, 1631 final_cnt); 1632 break; 1633 } 1634 target_freq = dfs_find_ch_with_fallback_for_freq( 1635 dfs, chan_wd, &chan_params->mhz_freq_seg1, 1636 leakage_adjusted_lst, random_chan_cnt); 1637 1638 /* Since notion of 80+80 is not present in the regulatory 1639 * channel the function may return invalid 80+80 channels for 1640 * some devices (e.g. Pine). Therefore, check if we need to 1641 * correct it by checking the following condition. 1642 */ 1643 if ((*chan_wd == DFS_CH_WIDTH_80P80MHZ) && 1644 (flags & DFS_RANDOM_CH_FLAG_RESTRICTED_80P80_ENABLED) && 1645 target_freq) { 1646 wlan_reg_set_channel_params_for_pwrmode( 1647 dfs->dfs_pdev_obj, 1648 target_freq, 1649 0, chan_params, 1650 REG_CURRENT_PWR_MODE); 1651 if (!(CHAN_WITHIN_RESTRICTED_80P80( 1652 chan_params->mhz_freq_seg0, 1653 chan_params->mhz_freq_seg1))) { 1654 *chan_wd = DFS_CH_WIDTH_160MHZ; 1655 target_freq = 1656 dfs_find_ch_with_fallback_for_freq( 1657 dfs, chan_wd, 1658 &chan_params->mhz_freq_seg1, 1659 leakage_adjusted_lst, 1660 random_chan_cnt); 1661 } 1662 } 1663 1664 /* 1665 * When flag_no_weather is set, avoid usage of Adjacent 1666 * weather radar channel in HT40 mode as extension channel 1667 * will be on 5600. 1668 */ 1669 if (flag_no_weather && 1670 (target_freq == 1671 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ) && 1672 (*chan_wd == DFS_CH_WIDTH_40MHZ)) { 1673 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1674 "skip weather adjacent ch freq =%d\n", 1675 target_freq); 1676 continue; 1677 } 1678 1679 /* 1680 * Spur or leakage transmissions is observed in Spruce HW in 1681 * frequencies from 5260MHz to 5320MHz when one of the following 1682 * conditions is true, 1683 * i) The AP is transmitting in 52/56/60/64 in 80MHz mode and 1684 * then the AP moves to the adjacent channel 36/44/48 in 80MHz 1685 * mode and starts transmitting. 1686 * ii) The AP is transmitting in 36/44/48/52/56/60/64 in 160MHz 1687 * mode and then the AP moves to the adjacent channel 36/44/48 1688 * in 80MHz mode and starts transmitting. 1689 * 1690 * The random channel selection algorithm prevents the channel 1691 * movement mentioned above, thereby eliminating the leakage. 1692 */ 1693 if (flag_no_spur_leakage_adj_chans && 1694 DFS_IS_SPRUCE_SPUR_AVOID_FREQS(target_freq) && 1695 *chan_wd == DFS_CH_WIDTH_80MHZ) { 1696 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1697 "skip spruce spur causing (adjacent) channel=%hu", 1698 target_freq); 1699 continue; 1700 } 1701 1702 if (target_freq) 1703 break; 1704 } while (true); 1705 1706 qdf_mem_free(random_chan_freq_list); 1707 qdf_mem_free(leakage_adjusted_lst); 1708 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_freq = %d", 1709 target_freq); 1710 1711 return target_freq; 1712 } 1713 #endif 1714