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