1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 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 * matix 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 * @avail_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 /** 1023 * dfs_random_channel_sel_set_bitmap_for_freq()- Set channel bit in bitmap based 1024 * on given channel number 1025 * @dfs: Pointer to DFS structure. 1026 * @bitmap: bitmap 1027 * @chan_freq: channel frequency 1028 * 1029 * Set channel bit in bitmap based on given channel frequency. 1030 * 1031 * Return: None 1032 */ 1033 #ifdef CONFIG_CHAN_FREQ_API 1034 #define FREQUENCY_BAND_LIMIT 60 1035 static void 1036 dfs_random_channel_sel_set_bitmap_for_freq(struct wlan_dfs *dfs, 1037 struct chan_bonding_bitmap *bitmap, 1038 uint16_t chan_freq) 1039 { 1040 int i = 0; 1041 int start_chan_freq = 0; 1042 1043 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { 1044 start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; 1045 if (chan_freq >= start_chan_freq && 1046 chan_freq <= start_chan_freq + 1047 FREQUENCY_BAND_LIMIT) { 1048 bitmap->chan_bonding_set[i].chan_map |= 1049 (1 << ((chan_freq - start_chan_freq) / 1050 DFS_80_NUM_SUB_CHANNEL_FREQ)); 1051 return; 1052 } 1053 } 1054 1055 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1056 "Frequency=%d is not in the bitmap", chan_freq); 1057 } 1058 #endif 1059 1060 #ifdef CONFIG_BAND_6GHZ 1061 /** 1062 * dfs_assign_6g_channels()- Assign the center frequency of the first 20 MHZ 1063 * channel in every 80MHz channel, present in the 6G band. 1064 * @ch_map: Pointer to ch_map. 1065 * 1066 * Return: Void 1067 */ 1068 static void dfs_assign_6g_channels(struct chan_bonding_bitmap *ch_map) 1069 { 1070 ch_map->chan_bonding_set[7].start_chan_freq = 5955; 1071 ch_map->chan_bonding_set[8].start_chan_freq = 6035; 1072 ch_map->chan_bonding_set[9].start_chan_freq = 6115; 1073 ch_map->chan_bonding_set[10].start_chan_freq = 6195; 1074 ch_map->chan_bonding_set[11].start_chan_freq = 6275; 1075 ch_map->chan_bonding_set[12].start_chan_freq = 6355; 1076 ch_map->chan_bonding_set[13].start_chan_freq = 6435; 1077 ch_map->chan_bonding_set[14].start_chan_freq = 6515; 1078 ch_map->chan_bonding_set[15].start_chan_freq = 6595; 1079 ch_map->chan_bonding_set[16].start_chan_freq = 6675; 1080 ch_map->chan_bonding_set[17].start_chan_freq = 6755; 1081 ch_map->chan_bonding_set[18].start_chan_freq = 6835; 1082 ch_map->chan_bonding_set[19].start_chan_freq = 6915; 1083 ch_map->chan_bonding_set[20].start_chan_freq = 6995; 1084 } 1085 #else 1086 static inline void dfs_assign_6g_channels(struct chan_bonding_bitmap *ch_map) 1087 { 1088 } 1089 #endif 1090 1091 /** 1092 * dfs_find_num_sub_channels_for_chwidth_320_160() - Find the max number 1093 * of sub channels for the given channel width (320/160) 1094 * @chan_width: Channel width 1095 * 1096 * Return - Number of sub-channels 1097 */ 1098 static uint8_t 1099 dfs_find_num_sub_channels_for_chwidth_320_160(uint16_t chan_width) 1100 { 1101 if (chan_width == DFS_CH_WIDTH_160MHZ) 1102 return DFS_MAX_NUM_160_SUBCHAN; 1103 else if (chan_width == DFS_CH_WIDTH_320MHZ) 1104 return DFS_MAX_NUM_240_SUBCHAN; 1105 1106 return 0; 1107 } 1108 1109 /** 1110 * dfs_find_next_chan_start_freq_for_320_160() - Find the next 160/320 channel's 1111 * start freq based on the available channel list. Validate the 1112 * continuity of the sub channels of 160/320M BW, if they are contiguous 1113 * declare channel to be found. Return the start_freq of the channel band found. 1114 * @chan_count: Total number of available channels. 1115 * @freq_list: Available list of frequency 1116 * @chan_width: Target channel width 1117 * @chan_found: Bool to indicate if channel is found 1118 * 1119 * Return: Next chan's start freq 1120 */ 1121 1122 static qdf_freq_t 1123 dfs_find_next_chan_start_freq_for_320_160(uint8_t chan_count, 1124 uint16_t *freq_list, 1125 uint16_t chan_width, bool *chan_found) 1126 { 1127 uint8_t i; 1128 uint8_t count = 0; 1129 qdf_freq_t next_chan_start_freq = 0; 1130 uint8_t num_sub_chans = 1131 dfs_find_num_sub_channels_for_chwidth_320_160(chan_width); 1132 1133 for (i = 1; i < chan_count; i++) { 1134 if ((freq_list[i] - freq_list[i - 1]) == 1135 DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET) 1136 count++; 1137 else 1138 count = 0; 1139 if (count == num_sub_chans - 1) { 1140 *chan_found = true; 1141 next_chan_start_freq = freq_list[i - count]; 1142 break; 1143 } 1144 } 1145 return next_chan_start_freq; 1146 } 1147 1148 /** 1149 * dfs_find_ch_with_fallback_for_freq()- find random channel 1150 * @dfs: Pointer to DFS structure. 1151 * @chan_wd: channel width 1152 * @center_freq_seg1: center frequency of secondary segment. 1153 * @freq_lst: list of available frequency. 1154 * @num_chan: number of channels in the list. 1155 * 1156 * Find random channel based on given channel width and channel list, 1157 * fallback to lower width if requested channel width not available. 1158 * 1159 * Return: channel frequency. 1160 */ 1161 #ifdef CONFIG_CHAN_FREQ_API 1162 static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs, 1163 uint16_t *chan_wd, 1164 qdf_freq_t *center_freq_seg1, 1165 uint16_t *freq_lst, 1166 uint32_t num_chan) 1167 { 1168 bool flag = false; 1169 uint32_t rand_byte = 0; 1170 struct chan_bonding_bitmap ch_map = { { {0} } }; 1171 uint8_t i, index = 0, final_cnt = 0; 1172 uint16_t target_channel = 0; 1173 uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_start_ch = 0; 1174 uint16_t final_lst[NUM_CHANNELS] = {0}; 1175 1176 /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ 1177 ch_map.chan_bonding_set[0].start_chan_freq = 5180; 1178 ch_map.chan_bonding_set[1].start_chan_freq = 5260; 1179 ch_map.chan_bonding_set[2].start_chan_freq = 5500; 1180 ch_map.chan_bonding_set[3].start_chan_freq = 5580; 1181 ch_map.chan_bonding_set[4].start_chan_freq = 5660; 1182 ch_map.chan_bonding_set[5].start_chan_freq = 5745; 1183 ch_map.chan_bonding_set[6].start_chan_freq = 5825; 1184 1185 dfs_assign_6g_channels(&ch_map); 1186 for (i = 0; i < num_chan; i++) { 1187 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1188 "channel = %d added to bitmap", freq_lst[i]); 1189 dfs_random_channel_sel_set_bitmap_for_freq(dfs, &ch_map, 1190 freq_lst[i]); 1191 } 1192 1193 /* populate available channel list from bitmap */ 1194 final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map, 1195 *chan_wd, final_lst); 1196 1197 /* If no valid 80mhz bonded chan found, fallback */ 1198 if (final_cnt == 0) { 1199 if ((*chan_wd == DFS_CH_WIDTH_320MHZ) || 1200 (*chan_wd == DFS_CH_WIDTH_160MHZ) || 1201 (*chan_wd == DFS_CH_WIDTH_80P80MHZ) || 1202 (*chan_wd == DFS_CH_WIDTH_80MHZ)) { 1203 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1204 "from [%d] to 40Mhz", *chan_wd); 1205 *chan_wd = DFS_CH_WIDTH_40MHZ; 1206 } else if (*chan_wd == DFS_CH_WIDTH_40MHZ) { 1207 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1208 "from 40Mhz to 20MHz"); 1209 *chan_wd = DFS_CH_WIDTH_20MHZ; 1210 } 1211 return 0; 1212 } 1213 1214 /* ch count should be > 8 to switch new channel in 160Mhz band */ 1215 if (((*chan_wd == DFS_CH_WIDTH_160MHZ) || 1216 (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) && 1217 (final_cnt < DFS_MAX_NUM_160_SUBCHAN)) { 1218 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1219 "from [%d] to 80Mhz", *chan_wd); 1220 *chan_wd = DFS_CH_WIDTH_80MHZ; 1221 return 0; 1222 } 1223 1224 /* ch count should be 12 to switch new 320 channel band (240MHZ) */ 1225 if (*chan_wd == DFS_CH_WIDTH_320MHZ) { 1226 if (final_cnt < DFS_MAX_NUM_240_SUBCHAN) { 1227 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1228 "from [%d] to 160Mhz", *chan_wd); 1229 *chan_wd = DFS_CH_WIDTH_160MHZ; 1230 return 0; 1231 } 1232 } 1233 1234 if (*chan_wd == DFS_CH_WIDTH_320MHZ || 1235 *chan_wd == DFS_CH_WIDTH_160MHZ) { 1236 /* 1237 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128 1238 * and all the channels in these blocks are continuous 1239 * and separated by 4Mhz. 1240 * Only 1 block of 240 channel is 1241 * available from 100 - 140 comprising of 12 sub 20 channels. 1242 * These are continuous and separated by 20MHZ in 1243 * frequency spectrum. 1244 */ 1245 new_start_ch = 1246 dfs_find_next_chan_start_freq_for_320_160(final_cnt, 1247 final_lst, 1248 *chan_wd, 1249 &flag); 1250 } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { 1251 flag = true; 1252 } 1253 1254 if (!flag) { 1255 if (*chan_wd == DFS_CH_WIDTH_320MHZ) { 1256 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1257 "from [%d] to 160Mhz", *chan_wd); 1258 *chan_wd = DFS_CH_WIDTH_160MHZ; 1259 return 0; 1260 } else if (*chan_wd == DFS_CH_WIDTH_160MHZ) { 1261 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1262 "from [%d] to 80Mhz", *chan_wd); 1263 *chan_wd = DFS_CH_WIDTH_80MHZ; 1264 return 0; 1265 } 1266 } 1267 1268 if (*chan_wd == DFS_CH_WIDTH_320MHZ || 1269 *chan_wd == DFS_CH_WIDTH_160MHZ) { 1270 get_random_bytes((uint8_t *)&rand_byte, 1); 1271 rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) 1272 % dfs_find_num_sub_channels_for_chwidth_320_160 1273 (*chan_wd); 1274 target_channel = new_start_ch + (rand_byte * 1275 DFS_80_NUM_SUB_CHANNEL_FREQ); 1276 } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { 1277 get_random_bytes((uint8_t *)&rand_byte, 1); 1278 index = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1279 final_cnt; 1280 target_channel = final_lst[index]; 1281 index -= (index % DFS_80_NUM_SUB_CHANNEL); 1282 primary_seg_start_ch = final_lst[index]; 1283 1284 /* reset channels associate with primary 80Mhz */ 1285 for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++) 1286 final_lst[i + index] = 0; 1287 /* select and calculate center freq for secondary segment */ 1288 for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) { 1289 if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] && 1290 (abs(primary_seg_start_ch - 1291 final_lst[i * DFS_80_NUM_SUB_CHANNEL]) > 1292 (DFS_80P80M_FREQ_DIFF * 2))) { 1293 sec_seg_ch = final_lst[i * 1294 DFS_80_NUM_SUB_CHANNEL] + 1295 DFS_80MHZ_START_CENTER_CH_FREQ_DIFF; 1296 break; 1297 } 1298 } 1299 1300 if (!sec_seg_ch && (final_cnt == DFS_MAX_NUM_160_SUBCHAN)) 1301 *chan_wd = DFS_CH_WIDTH_160MHZ; 1302 else if (!sec_seg_ch) 1303 *chan_wd = DFS_CH_WIDTH_80MHZ; 1304 1305 *center_freq_seg1 = sec_seg_ch; 1306 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1307 "Center frequency seg1 = %d", sec_seg_ch); 1308 } else { 1309 target_channel = dfs_get_rand_from_lst_for_freq(dfs, 1310 final_lst, 1311 final_cnt); 1312 } 1313 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1314 "target channel = %d", target_channel); 1315 1316 return target_channel; 1317 } 1318 #endif 1319 1320 bool dfs_is_freq_in_nol(struct wlan_dfs *dfs, uint32_t freq) 1321 { 1322 struct dfs_nolelem *nol; 1323 1324 if (!dfs) { 1325 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "null dfs"); 1326 return false; 1327 } 1328 1329 nol = dfs->dfs_nol; 1330 while (nol) { 1331 if (freq == nol->nol_freq) { 1332 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1333 "%d is in nol", freq); 1334 return true; 1335 } 1336 nol = nol->nol_next; 1337 } 1338 1339 return false; 1340 } 1341 1342 /** 1343 * dfs_apply_rules_for_freq()- prepare channel list based on flags 1344 * @dfs: dfs handler 1345 * @flags: channel flags 1346 * @random_chan_freq_list: output channel list 1347 * @random_chan_cnt: output channel count 1348 * @chan_list: input channel list 1349 * @chan_cnt: input channel count 1350 * @dfs_region: dfs region 1351 * @acs_info: acs channel range information 1352 * 1353 * prepare channel list based on flags 1354 * 1355 * return: none 1356 */ 1357 #ifdef CONFIG_CHAN_FREQ_API 1358 static void dfs_apply_rules_for_freq(struct wlan_dfs *dfs, 1359 uint32_t flags, 1360 uint16_t *random_chan_freq_list, 1361 uint32_t *random_chan_cnt, 1362 struct dfs_channel *chan_list, 1363 uint32_t chan_cnt, 1364 uint8_t dfs_region, 1365 struct dfs_acs_info *acs_info) 1366 { 1367 struct dfs_channel *chan; 1368 bool flag_no_weather = 0; 1369 bool flag_no_lower_5g = 0; 1370 bool flag_no_upper_5g = 0; 1371 bool flag_no_dfs_chan = 0; 1372 bool flag_no_2g_chan = 0; 1373 bool flag_no_5g_chan = 0; 1374 bool flag_no_japan_w53 = 0; 1375 bool flag_no_6g_freq; 1376 int i; 1377 bool found = false; 1378 uint16_t j; 1379 uint16_t freq_list[MAX_20MHZ_SUBCHANS]; 1380 uint8_t num_channels = 0; 1381 1382 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags); 1383 flag_no_weather = (dfs_region == DFS_ETSI_REGION) ? 1384 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 1385 1386 if (dfs_region == DFS_MKK_REGION || 1387 dfs_region == DFS_MKKN_REGION) { 1388 flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH; 1389 flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH; 1390 flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH; 1391 } 1392 1393 flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH; 1394 flag_no_2g_chan = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH; 1395 flag_no_5g_chan = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH; 1396 flag_no_6g_freq = flags & DFS_RANDOM_CH_FLAG_NO_6GHZ_CH; 1397 1398 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { 1399 num_channels = 1400 dfs_get_bonding_channel_without_seg_info_for_freq 1401 (dfs->dfs_curchan, freq_list); 1402 } 1403 1404 for (i = 0; i < chan_cnt; i++) { 1405 chan = &chan_list[i]; 1406 found = false; 1407 1408 if ((chan->dfs_ch_ieee == 0) || 1409 (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) { 1410 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1411 "invalid channel %d", chan->dfs_ch_ieee); 1412 continue; 1413 } 1414 1415 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { 1416 for (j = 0; j < num_channels; j++) { 1417 if (chan->dfs_ch_freq == freq_list[j]) { 1418 dfs_debug(dfs, 1419 WLAN_DEBUG_DFS_RANDOM_CHAN, 1420 "skip %d current operating channel", 1421 chan->dfs_ch_freq); 1422 found = true; 1423 break; 1424 } 1425 } 1426 1427 if (found) 1428 continue; 1429 } 1430 1431 if (acs_info && acs_info->acs_mode) { 1432 for (j = 0; j < acs_info->num_of_channel; j++) { 1433 if (acs_info->chan_freq_list[j] == 1434 chan->dfs_ch_freq) { 1435 found = true; 1436 break; 1437 } 1438 } 1439 1440 if (!found) { 1441 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1442 "skip ch freq %d not in acs range", 1443 chan->dfs_ch_freq); 1444 continue; 1445 } 1446 found = false; 1447 } 1448 1449 if (flag_no_2g_chan && 1450 chan->dfs_ch_freq <= DFS_MAX_24GHZ_CHANNEL_FREQ) { 1451 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1452 "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee); 1453 continue; 1454 } 1455 1456 if (flag_no_5g_chan && 1457 WLAN_REG_IS_5GHZ_CH_FREQ(chan->dfs_ch_freq)) { 1458 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1459 "skip 5 GHz channel=%d", chan->dfs_ch_ieee); 1460 continue; 1461 } 1462 1463 if (flag_no_weather) { 1464 if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) { 1465 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1466 "skip weather channel=%d", 1467 chan->dfs_ch_ieee); 1468 continue; 1469 } 1470 } 1471 1472 if (flag_no_lower_5g && 1473 DFS_IS_CHAN_JAPAN_INDOOR_FREQ(chan->dfs_ch_freq)) { 1474 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1475 "skip indoor channel=%d", chan->dfs_ch_ieee); 1476 continue; 1477 } 1478 1479 if (flag_no_upper_5g && 1480 DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(chan->dfs_ch_freq)) { 1481 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1482 "skip outdoor channel=%d", chan->dfs_ch_ieee); 1483 continue; 1484 } 1485 1486 if (flag_no_6g_freq && 1487 WLAN_REG_IS_6GHZ_CHAN_FREQ(chan->dfs_ch_freq)) { 1488 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1489 "skip 6 GHz channel=%d", chan->dfs_ch_ieee); 1490 continue; 1491 } 1492 1493 if (flag_no_dfs_chan && 1494 (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) { 1495 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1496 "skip dfs channel=%d", chan->dfs_ch_ieee); 1497 continue; 1498 } 1499 1500 if (flag_no_japan_w53 && 1501 DFS_IS_CHAN_JAPAN_W53_FREQ(chan->dfs_ch_freq)) { 1502 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1503 "skip japan W53 channel=%d", 1504 chan->dfs_ch_ieee); 1505 continue; 1506 } 1507 1508 if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) { 1509 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1510 "skip nol channel=%d", chan->dfs_ch_ieee); 1511 continue; 1512 } 1513 1514 random_chan_freq_list[*random_chan_cnt] = chan->dfs_ch_freq; 1515 *random_chan_cnt += 1; 1516 } 1517 } 1518 #endif 1519 1520 /** 1521 * dfs_remove_spruce_spur_channels_for_bw_20_40() - API to remove the 1522 * spur channels in spruce if current bw is 20/40MHz. 1523 * @freq_list: Input list from which spur channels are removed. 1524 * @freq_count: Input list count. 1525 * 1526 * return: void. 1527 */ 1528 static void 1529 dfs_remove_spruce_spur_channels_for_bw_20_40(uint16_t *freq_list, 1530 uint8_t freq_count) 1531 { 1532 uint8_t i; 1533 1534 for (i = 0; i < freq_count; i++) { 1535 if (DFS_IS_CHAN_SPRUCE_SPUR_FREQ_20_40_MHZ(freq_list[i])) 1536 freq_list[i] = 0; 1537 } 1538 } 1539 1540 #ifdef CONFIG_CHAN_FREQ_API 1541 uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs, 1542 struct dfs_channel *chan_list, 1543 uint32_t chan_cnt, 1544 uint32_t flags, 1545 struct ch_params *chan_params, 1546 uint8_t dfs_region, 1547 struct dfs_acs_info *acs_info) 1548 { 1549 int i = 0; 1550 uint8_t final_cnt = 0; 1551 uint16_t target_freq = 0; 1552 uint16_t *random_chan_freq_list = NULL; 1553 uint32_t random_chan_cnt = 0; 1554 uint16_t flag_no_weather = 0; 1555 uint16_t *leakage_adjusted_lst; 1556 uint16_t final_lst[NUM_CHANNELS] = {0}; 1557 uint16_t *chan_wd = (uint16_t *)&chan_params->ch_width; 1558 bool flag_no_spur_leakage_adj_chans = false; 1559 1560 if (!chan_list || !chan_cnt) { 1561 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1562 "Invalid params %pK, chan_cnt=%d", 1563 chan_list, chan_cnt); 1564 return 0; 1565 } 1566 1567 if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_320MHZ) { 1568 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1569 "Invalid chan_wd %d", *chan_wd); 1570 return 0; 1571 } 1572 1573 random_chan_freq_list = 1574 qdf_mem_malloc(chan_cnt * sizeof(*random_chan_freq_list)); 1575 if (!random_chan_freq_list) 1576 return 0; 1577 1578 dfs_apply_rules_for_freq(dfs, flags, random_chan_freq_list, 1579 &random_chan_cnt, chan_list, chan_cnt, 1580 dfs_region, acs_info); 1581 flag_no_weather = (dfs_region == DFS_ETSI_REGION) ? 1582 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; 1583 flag_no_spur_leakage_adj_chans = 1584 flags & DFS_RANDOM_CH_FLAG_NO_SPRUCE_SPUR_ADJ_CH; 1585 1586 /* list adjusted after leakage has been marked */ 1587 leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt * 1588 sizeof(*leakage_adjusted_lst)); 1589 if (!leakage_adjusted_lst) { 1590 qdf_mem_free(random_chan_freq_list); 1591 return 0; 1592 } 1593 1594 if (flag_no_spur_leakage_adj_chans && 1595 (*chan_wd == DFS_CH_WIDTH_20MHZ || 1596 *chan_wd == DFS_CH_WIDTH_40MHZ)) 1597 dfs_remove_spruce_spur_channels_for_bw_20_40( 1598 random_chan_freq_list, 1599 random_chan_cnt); 1600 do { 1601 int ret; 1602 1603 qdf_mem_copy(leakage_adjusted_lst, random_chan_freq_list, 1604 random_chan_cnt * sizeof(*leakage_adjusted_lst)); 1605 ret = dfs_mark_leaking_chan_for_freq(dfs, *chan_wd, 1606 random_chan_cnt, 1607 leakage_adjusted_lst); 1608 if (QDF_IS_STATUS_ERROR(ret)) { 1609 qdf_mem_free(random_chan_freq_list); 1610 qdf_mem_free(leakage_adjusted_lst); 1611 return 0; 1612 } 1613 1614 if (*chan_wd == DFS_CH_WIDTH_20MHZ) { 1615 /* 1616 * PASS: 3 - from leakage_adjusted_lst, prepare valid 1617 * ch list and use random number from that 1618 */ 1619 for (i = 0; i < random_chan_cnt; i++) { 1620 if (leakage_adjusted_lst[i] == 0) 1621 continue; 1622 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1623 "Chan freq =%d added to available list", 1624 leakage_adjusted_lst[i]); 1625 final_lst[final_cnt] = leakage_adjusted_lst[i]; 1626 final_cnt++; 1627 } 1628 target_freq = dfs_get_rand_from_lst_for_freq(dfs, 1629 final_lst, 1630 final_cnt); 1631 break; 1632 } 1633 target_freq = dfs_find_ch_with_fallback_for_freq( 1634 dfs, chan_wd, &chan_params->mhz_freq_seg1, 1635 leakage_adjusted_lst, random_chan_cnt); 1636 1637 /* Since notion of 80+80 is not present in the regulatory 1638 * channel the function may return invalid 80+80 channels for 1639 * some devices (e.g. Pine). Therefore, check if we need to 1640 * correct it by checking the following condition. 1641 */ 1642 if ((*chan_wd == DFS_CH_WIDTH_80P80MHZ) && 1643 (flags & DFS_RANDOM_CH_FLAG_RESTRICTED_80P80_ENABLED) && 1644 target_freq) { 1645 wlan_reg_set_channel_params_for_pwrmode( 1646 dfs->dfs_pdev_obj, 1647 target_freq, 1648 0, chan_params, 1649 REG_CURRENT_PWR_MODE); 1650 if (!(CHAN_WITHIN_RESTRICTED_80P80( 1651 chan_params->mhz_freq_seg0, 1652 chan_params->mhz_freq_seg1))) { 1653 *chan_wd = DFS_CH_WIDTH_160MHZ; 1654 target_freq = 1655 dfs_find_ch_with_fallback_for_freq( 1656 dfs, chan_wd, 1657 &chan_params->mhz_freq_seg1, 1658 leakage_adjusted_lst, 1659 random_chan_cnt); 1660 } 1661 } 1662 1663 /* 1664 * When flag_no_weather is set, avoid usage of Adjacent 1665 * weather radar channel in HT40 mode as extension channel 1666 * will be on 5600. 1667 */ 1668 if (flag_no_weather && 1669 (target_freq == 1670 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ) && 1671 (*chan_wd == DFS_CH_WIDTH_40MHZ)) { 1672 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1673 "skip weather adjacent ch freq =%d\n", 1674 target_freq); 1675 continue; 1676 } 1677 1678 /* 1679 * Spur or leakage transmissions is observed in Spruce HW in 1680 * frequencies from 5260MHz to 5320MHz when one of the following 1681 * conditions is true, 1682 * i) The AP is transmitting in 52/56/60/64 in 80MHz mode and 1683 * then the AP moves to the adjacent channel 36/44/48 in 80MHz 1684 * mode and starts transmitting. 1685 * ii) The AP is transmitting in 36/44/48/52/56/60/64 in 160MHz 1686 * mode and then the AP moves to the adjacent channel 36/44/48 1687 * in 80MHz mode and starts transmitting. 1688 * 1689 * The random channel selection algorithm prevents the channel 1690 * movement mentioned above, thereby eliminating the leakage. 1691 */ 1692 if (flag_no_spur_leakage_adj_chans && 1693 DFS_IS_SPRUCE_SPUR_AVOID_FREQS(target_freq) && 1694 *chan_wd == DFS_CH_WIDTH_80MHZ) { 1695 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, 1696 "skip spruce spur causing (adjacent) channel=%hu", 1697 target_freq); 1698 continue; 1699 } 1700 1701 if (target_freq) 1702 break; 1703 } while (true); 1704 1705 qdf_mem_free(random_chan_freq_list); 1706 qdf_mem_free(leakage_adjusted_lst); 1707 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_freq = %d", 1708 target_freq); 1709 1710 return target_freq; 1711 } 1712 #endif 1713