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