1 /* 2 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. 3 * 4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc. 5 * 6 * 7 * Permission to use, copy, modify, and/or distribute this software for 8 * any purpose with or without fee is hereby granted, provided that the 9 * above copyright notice and this permission notice appear in all 10 * copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 * PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * This file was originally distributed by Qualcomm Atheros, Inc. 24 * under proprietary terms before Copyright ownership was assigned 25 * to the Linux Foundation. 26 */ 27 28 /*=========================================================================== 29 30 s a p F s m . C 31 32 OVERVIEW: 33 34 This software unit holds the implementation of the WLAN SAP Finite 35 State Machine modules 36 37 DEPENDENCIES: 38 39 Are listed for each API below. 40 ===========================================================================*/ 41 42 /*---------------------------------------------------------------------------- 43 * Include Files 44 * -------------------------------------------------------------------------*/ 45 #include "sap_internal.h" 46 /* Pick up the SME API definitions */ 47 #include "sme_api.h" 48 /* Pick up the PMC API definitions */ 49 #include "cds_utils.h" 50 #include "cds_ieee80211_common_i.h" 51 #include "cds_reg_service.h" 52 #include "qdf_util.h" 53 #include "cds_concurrency.h" 54 55 /*---------------------------------------------------------------------------- 56 * Preprocessor Definitions and Constants 57 * -------------------------------------------------------------------------*/ 58 59 /*---------------------------------------------------------------------------- 60 * Type Declarations 61 * -------------------------------------------------------------------------*/ 62 63 /*---------------------------------------------------------------------------- 64 * Global Data Definitions 65 * -------------------------------------------------------------------------*/ 66 67 /*---------------------------------------------------------------------------- 68 * External declarations for global context 69 * -------------------------------------------------------------------------*/ 70 #ifdef FEATURE_WLAN_CH_AVOID 71 extern sapSafeChannelType safe_channels[]; 72 #endif /* FEATURE_WLAN_CH_AVOID */ 73 74 /*---------------------------------------------------------------------------- 75 * Static Variable Definitions 76 * -------------------------------------------------------------------------*/ 77 78 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 79 /* 80 * TODO: At present SAP Channel leakage matrix for ch 144 81 * is not available from system's team. So to play it safe 82 * and avoid crash if channel 144 is request, in following 83 * matix channel 144 is added such that it will cause code 84 * to avoid selecting channel 144. 85 * 86 * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS 87 * PROVIDED BY SYSTEM'S TEAM. 88 */ 89 90 /* channel tx leakage table - ht80 */ 91 tSapChanMatrixInfo ht80_chan[] = { 92 {52, 93 {{36, 148}, {40, 199}, 94 {44, 193}, {48, 197}, 95 {52, SAP_TX_LEAKAGE_MIN}, {56, 153}, 96 {60, 137}, {64, 134}, 97 {100, 358}, {104, 350}, 98 {108, 404}, {112, 344}, 99 {116, 424}, {120, 429}, 100 {124, 437}, {128, 435}, 101 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 102 {140, SAP_TX_LEAKAGE_MAX}, 103 {144, SAP_TX_LEAKAGE_MIN} 104 } }, 105 106 107 {56, 108 {{36, 171}, {40, 178}, 109 {44, 171}, {48, 178}, 110 {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, 111 {60, SAP_TX_LEAKAGE_MIN}, {64, 280}, 112 {100, 351}, {104, 376}, 113 {108, 362}, {112, 362}, 114 {116, 403}, {120, 397}, 115 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 116 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 117 {140, SAP_TX_LEAKAGE_MAX}, 118 {144, SAP_TX_LEAKAGE_MIN} 119 } }, 120 121 {60, 122 {{36, 156}, {40, 146}, 123 {44, SAP_TX_LEAKAGE_MIN}, {48, SAP_TX_LEAKAGE_MIN}, 124 {52, 180}, {56, SAP_TX_LEAKAGE_MIN}, 125 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 126 {100, 376}, {104, 360}, 127 {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX}, 128 {116, 395}, {120, 399}, 129 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 130 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 131 {140, SAP_TX_LEAKAGE_MAX}, 132 {144, SAP_TX_LEAKAGE_MIN} 133 } }, 134 135 {64, 136 {{36, 217}, {40, 221}, 137 {44, SAP_TX_LEAKAGE_MIN}, {48, SAP_TX_LEAKAGE_MIN}, 138 {52, 176}, {56, 176}, 139 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 140 {100, 384}, {104, 390}, 141 {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX}, 142 {116, 375}, {120, 374}, 143 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 144 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 145 {140, SAP_TX_LEAKAGE_MAX}, 146 {144, SAP_TX_LEAKAGE_MIN} 147 } }, 148 149 {100, 150 {{36, 357}, {40, 326}, 151 {44, 321}, {48, 326}, 152 {52, 378}, {56, 396}, 153 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 154 {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN}, 155 {108, 196}, {112, 116}, 156 {116, 166}, {120, SAP_TX_LEAKAGE_MIN}, 157 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 158 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 159 {140, SAP_TX_LEAKAGE_MIN}, 160 {144, SAP_TX_LEAKAGE_MIN} 161 } }, 162 163 {104, 164 {{36, 325}, {40, 325}, 165 {44, 305}, {48, 352}, 166 {52, 411}, {56, 411}, 167 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 168 {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN}, 169 {108, SAP_TX_LEAKAGE_MIN}, {112, 460}, 170 {116, 198}, {120, SAP_TX_LEAKAGE_MIN}, 171 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 172 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 173 {140, SAP_TX_LEAKAGE_MIN}, 174 {144, SAP_TX_LEAKAGE_MIN} 175 } }, 176 177 {108, 178 {{36, 304}, {40, 332}, 179 {44, 310}, {48, 335}, 180 {52, 431}, {56, 391}, 181 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 182 {100, 280}, {104, SAP_TX_LEAKAGE_MIN}, 183 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 184 {116, 185}, {120, SAP_TX_LEAKAGE_MIN}, 185 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 186 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 187 {140, SAP_TX_LEAKAGE_MIN}, 188 {144, SAP_TX_LEAKAGE_MIN} 189 } }, 190 191 {112, 192 {{36, 327}, {40, 335}, 193 {44, 331}, {48, 345}, 194 {52, 367}, {56, 401}, 195 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 196 {100, 131}, {104, 132}, 197 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 198 {116, 189}, {120, SAP_TX_LEAKAGE_MIN}, 199 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 200 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 201 {140, SAP_TX_LEAKAGE_MIN}, 202 {144, SAP_TX_LEAKAGE_MIN} 203 } }, 204 205 {116, 206 {{36, 384}, {40, 372}, 207 {44, 389}, {48, 396}, 208 {52, 348}, {56, 336}, 209 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 210 {100, 172}, {104, 169}, 211 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 212 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 213 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 214 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 215 {140, SAP_TX_LEAKAGE_MIN}, 216 {144, SAP_TX_LEAKAGE_MIN} 217 } }, 218 219 {120, 220 {{36, 395}, {40, 419}, 221 {44, 439}, {48, 407}, 222 {52, 321}, {56, 334}, 223 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 224 {100, 134}, {104, 186}, 225 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 226 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 227 {124, SAP_TX_LEAKAGE_MIN}, {128, 159}, 228 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 229 {140, SAP_TX_LEAKAGE_MIN}, 230 {144, SAP_TX_LEAKAGE_MIN} 231 } }, 232 233 {124, 234 {{36, 469}, {40, 433}, 235 {44, 434}, {48, 435}, 236 {52, 332}, {56, 345}, 237 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 238 {100, 146}, {104, 177}, 239 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 240 {116, 350}, {120, SAP_TX_LEAKAGE_MIN}, 241 {124, SAP_TX_LEAKAGE_MIN}, {128, 138}, 242 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 243 {140, SAP_TX_LEAKAGE_MIN}, 244 {144, SAP_TX_LEAKAGE_MIN} 245 } }, 246 247 {128, 248 {{36, 408}, {40, 434}, 249 {44, 449}, {48, 444}, 250 {52, 341}, {56, 374}, 251 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 252 {100, 205}, {104, 208}, 253 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 254 {116, 142}, {120, SAP_TX_LEAKAGE_MIN}, 255 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 256 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 257 {140, SAP_TX_LEAKAGE_MIN}, 258 {144, SAP_TX_LEAKAGE_MIN} 259 } }, 260 261 {132, 262 {{36, SAP_TX_LEAKAGE_MAX}, {40, SAP_TX_LEAKAGE_MAX}, 263 {44, SAP_TX_LEAKAGE_MAX}, {48, SAP_TX_LEAKAGE_MAX}, 264 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 265 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 266 {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN}, 267 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 268 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 269 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 270 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 271 {140, SAP_TX_LEAKAGE_MIN}, 272 {144, SAP_TX_LEAKAGE_MIN} 273 } }, 274 275 {136, 276 {{36, SAP_TX_LEAKAGE_MAX}, {40, SAP_TX_LEAKAGE_MAX}, 277 {44, SAP_TX_LEAKAGE_MAX}, {48, SAP_TX_LEAKAGE_MAX}, 278 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 279 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 280 {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN}, 281 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 282 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 283 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 284 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 285 {140, SAP_TX_LEAKAGE_MIN}, 286 {144, SAP_TX_LEAKAGE_MIN} 287 } }, 288 289 {140, 290 {{36, SAP_TX_LEAKAGE_MAX}, {40, SAP_TX_LEAKAGE_MAX}, 291 {44, SAP_TX_LEAKAGE_MAX}, {48, SAP_TX_LEAKAGE_MAX}, 292 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 293 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 294 {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN}, 295 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 296 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 297 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 298 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 299 {144, SAP_TX_LEAKAGE_MIN} 300 } }, 301 }; 302 303 /* channel tx leakage table - ht40 */ 304 tSapChanMatrixInfo ht40_chan[] = { 305 {52, 306 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN}, 307 {44, 230}, {48, 230}, 308 {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, 309 {60, SAP_TX_LEAKAGE_AUTO_MIN}, {64, SAP_TX_LEAKAGE_AUTO_MIN}, 310 {100, 625}, {104, 323}, 311 {108, 646}, {112, 646}, 312 {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX}, 313 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 314 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 315 {140, SAP_TX_LEAKAGE_MAX}, 316 {144, SAP_TX_LEAKAGE_MIN} 317 } }, 318 319 {56, 320 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN}, 321 {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN}, 322 {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, 323 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 324 {100, 611}, {104, 611}, 325 {108, 617}, {112, 617}, 326 {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX}, 327 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 328 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 329 {140, SAP_TX_LEAKAGE_MAX}, 330 {144, SAP_TX_LEAKAGE_MIN} 331 } }, 332 333 {60, 334 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN}, 335 {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN}, 336 {52, 190}, {56, 190}, 337 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 338 {100, 608}, {104, 608}, 339 {108, 623}, {112, 623}, 340 {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX}, 341 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 342 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 343 {140, SAP_TX_LEAKAGE_MAX}, 344 {144, SAP_TX_LEAKAGE_MIN} 345 } }, 346 347 {64, 348 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN}, 349 {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN}, 350 {52, 295}, {56, 295}, 351 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 352 {100, 594}, {104, 594}, 353 {108, 625}, {112, 625}, 354 {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX}, 355 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 356 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 357 {140, SAP_TX_LEAKAGE_MAX}, 358 {144, SAP_TX_LEAKAGE_MIN} 359 } }, 360 361 {100, 362 {{36, 618}, {40, 618}, 363 {44, 604}, {48, 604}, 364 {52, 596}, {56, 596}, 365 {60, 584}, {64, 584}, 366 {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN}, 367 {108, 299}, {112, 299}, 368 {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN}, 369 {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN}, 370 {132, 538}, {136, 538}, 371 {140, 598}, 372 {144, SAP_TX_LEAKAGE_MIN} 373 } }, 374 375 {104, 376 {{36, 636}, {40, 636}, 377 {44, 601}, {48, 601}, 378 {52, 616}, {56, 616}, 379 {60, 584}, {64, 584}, 380 {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN}, 381 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 382 {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN}, 383 {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN}, 384 {132, 553}, {136, 553}, 385 {140, 568}, 386 {144, SAP_TX_LEAKAGE_MIN} 387 } }, 388 389 {108, 390 {{36, 600}, {40, 600}, 391 {44, 627}, {48, 627}, 392 {52, 611}, {56, 611}, 393 {60, 611}, {64, 611}, 394 {100, 214}, {104, 214}, 395 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 396 {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN}, 397 {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN}, 398 {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN}, 399 {140, 534}, 400 {144, SAP_TX_LEAKAGE_MIN} 401 } }, 402 403 {112, 404 {{36, 645}, {40, 645}, 405 {44, 641}, {48, 641}, 406 {52, 618}, {56, 618}, 407 {60, 612}, {64, 612}, 408 {100, 293}, {104, 293}, 409 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 410 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 411 {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN}, 412 {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN}, 413 {140, 521}, 414 {144, SAP_TX_LEAKAGE_MIN} 415 } }, 416 417 {116, 418 {{36, 661}, {40, 661}, 419 {44, 624}, {48, 624}, 420 {52, 634}, {56, 634}, 421 {60, 611}, {64, 611}, 422 {100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN}, 423 {108, 217}, {112, 217}, 424 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 425 {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN}, 426 {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN}, 427 {140, SAP_TX_LEAKAGE_AUTO_MIN}, 428 {144, SAP_TX_LEAKAGE_MIN} 429 } }, 430 431 {120, 432 {{36, 667}, {40, 667}, 433 {44, 645}, {48, 645}, 434 {52, 633}, {56, 633}, 435 {60, 619}, {64, 619}, 436 {100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN}, 437 {108, 291}, {112, 291}, 438 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 439 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 440 {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN}, 441 {140, SAP_TX_LEAKAGE_AUTO_MIN}, 442 {144, SAP_TX_LEAKAGE_MIN} 443 } }, 444 445 {124, 446 {{36, 676}, {40, 676}, 447 {44, 668}, {48, 668}, 448 {52, 595}, {56, 595}, 449 {60, 622}, {64, 622}, 450 {100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN}, 451 {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN}, 452 {116, 225}, {120, 225}, 453 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 454 {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN}, 455 {140, SAP_TX_LEAKAGE_AUTO_MIN}, 456 {144, SAP_TX_LEAKAGE_MIN} 457 } }, 458 459 {128, 460 {{36, 678}, {40, 678}, 461 {44, 664}, {48, 664}, 462 {52, 651}, {56, 651}, 463 {60, 643}, {64, 643}, 464 {100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN}, 465 {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN}, 466 {116, 293}, {120, 293}, 467 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 468 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 469 {140, SAP_TX_LEAKAGE_AUTO_MIN}, 470 {144, SAP_TX_LEAKAGE_MIN} 471 } }, 472 473 {132, 474 {{36, 689}, {40, 689}, 475 {44, 669}, {48, 669}, 476 {52, 662}, {56, 662}, 477 {60, 609}, {64, 609}, 478 {100, 538}, {104, 538}, 479 {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN}, 480 {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN}, 481 {124, 247}, {128, 247}, 482 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 483 {140, SAP_TX_LEAKAGE_MIN}, 484 {144, SAP_TX_LEAKAGE_MIN} 485 } }, 486 487 {136, 488 {{36, 703}, {40, 703}, 489 {44, 688}, {48, SAP_TX_LEAKAGE_MIN}, 490 {52, 671}, {56, 671}, 491 {60, 658}, {64, 658}, 492 {100, 504}, {104, 504}, 493 {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN}, 494 {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN}, 495 {124, 289}, {128, 289}, 496 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 497 {140, SAP_TX_LEAKAGE_MIN}, 498 {144, SAP_TX_LEAKAGE_MIN} 499 } }, 500 501 {140, 502 {{36, 695}, {40, 695}, 503 {44, 684}, {48, 684}, 504 {52, 664}, {56, 664}, 505 {60, 658}, {64, 658}, 506 {100, 601}, {104, 601}, 507 {108, 545}, {112, 545}, 508 {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN}, 509 {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN}, 510 {132, 262}, {136, 262}, 511 {140, SAP_TX_LEAKAGE_MIN}, 512 {144, SAP_TX_LEAKAGE_MIN} 513 } }, 514 515 }; 516 517 /* channel tx leakage table - ht20 */ 518 tSapChanMatrixInfo ht20_chan[] = { 519 {52, 520 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, 286}, 521 {44, 225}, {48, 121}, 522 {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, 523 {60, 300}, {64, SAP_TX_LEAKAGE_AUTO_MIN}, 524 {100, 637}, {104, SAP_TX_LEAKAGE_MAX}, 525 {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX}, 526 {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX}, 527 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 528 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 529 {140, SAP_TX_LEAKAGE_MAX}, 530 {144, SAP_TX_LEAKAGE_MIN} 531 } }, 532 533 {56, 534 {{36, 468}, {40, SAP_TX_LEAKAGE_AUTO_MIN}, 535 {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, 206}, 536 {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, 537 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 538 {100, SAP_TX_LEAKAGE_MAX}, {104, SAP_TX_LEAKAGE_MAX}, 539 {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX}, 540 {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX}, 541 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 542 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 543 {140, SAP_TX_LEAKAGE_MAX}, 544 {144, SAP_TX_LEAKAGE_MIN} 545 } }, 546 547 {60, 548 {{36, 507}, {40, 440}, 549 {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, 313}, 550 {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, 551 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 552 {100, SAP_TX_LEAKAGE_MAX}, {104, SAP_TX_LEAKAGE_MAX}, 553 {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX}, 554 {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX}, 555 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 556 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 557 {140, SAP_TX_LEAKAGE_MAX}, 558 {144, SAP_TX_LEAKAGE_MIN} 559 } }, 560 561 {64, 562 {{36, 516}, {40, 520}, 563 {44, 506}, {48, SAP_TX_LEAKAGE_AUTO_MIN}, 564 {52, 301}, {56, 258}, 565 {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, 566 {100, 620}, {104, 617}, 567 {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX}, 568 {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX}, 569 {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX}, 570 {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX}, 571 {140, SAP_TX_LEAKAGE_MAX}, 572 {144, SAP_TX_LEAKAGE_MIN} 573 } }, 574 575 {100, 576 {{36, 616}, {40, 601}, 577 {44, 604}, {48, 589}, 578 {52, 612}, {56, 592}, 579 {60, 590}, {64, 582}, 580 {100, SAP_TX_LEAKAGE_MIN}, {104, 131}, 581 {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN}, 582 {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, 522}, 583 {124, 571}, {128, 589}, 584 {132, 593}, {136, 598}, 585 {140, 594}, 586 {144, SAP_TX_LEAKAGE_MIN}, 587 } }, 588 589 {104, 590 {{36, 622}, {40, 624}, 591 {44, 618}, {48, 610}, 592 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 593 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 594 {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN}, 595 {108, SAP_TX_LEAKAGE_MIN}, {112, 463}, 596 {116, 483}, {120, 503}, 597 {124, 523}, {128, 565}, 598 {132, 570}, {136, 588}, 599 {140, 585}, 600 {144, SAP_TX_LEAKAGE_MIN}, 601 } }, 602 603 {108, 604 {{36, 620}, {40, 638}, 605 {44, 611}, {48, 614}, 606 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 607 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 608 {100, 477}, {104, SAP_TX_LEAKAGE_MIN}, 609 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 610 {116, 477}, {120, 497}, 611 {124, 517}, {128, 537}, 612 {132, 557}, {136, 577}, 613 {140, 603}, 614 {144, SAP_TX_LEAKAGE_MIN}, 615 } }, 616 617 {112, 618 {{36, 636}, {40, 623}, 619 {44, 638}, {48, 628}, 620 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 621 {60, SAP_TX_LEAKAGE_MAX}, {64, 606}, 622 {100, 501}, {104, 481}, 623 {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN}, 624 {116, SAP_TX_LEAKAGE_MIN}, {120, 481}, 625 {124, 501}, {128, 421}, 626 {132, 541}, {136, 561}, 627 {140, 583}, 628 {144, SAP_TX_LEAKAGE_MIN}, 629 } }, 630 631 {116, 632 {{36, 646}, {40, 648}, 633 {44, 633}, {48, 634}, 634 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 635 {60, 615}, {64, 594}, 636 {100, 575}, {104, 554}, 637 {108, 534}, {112, SAP_TX_LEAKAGE_MIN}, 638 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 639 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 640 {132, 534}, {136, 554}, 641 {140, 574}, 642 {144, SAP_TX_LEAKAGE_MIN}, 643 } }, 644 645 {120, 646 {{36, 643}, {40, 649}, 647 {44, 654}, {48, 629}, 648 {52, SAP_TX_LEAKAGE_MAX}, {56, 621}, 649 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 650 {100, 565}, {104, 545}, 651 {108, 525}, {112, 505}, 652 {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN}, 653 {124, SAP_TX_LEAKAGE_MIN}, {128, 505}, 654 {132, 525}, {136, 545}, 655 {140, 565}, 656 {144, SAP_TX_LEAKAGE_MIN}, 657 } }, 658 659 {124, 660 {{36, 638}, {40, 657}, 661 {44, 663}, {48, 649}, 662 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 663 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 664 {100, 581}, {104, 561}, 665 {108, 541}, {112, 521}, 666 {116, 499}, {120, SAP_TX_LEAKAGE_MIN}, 667 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 668 {132, 499}, {136, 519}, 669 {140, 539}, 670 {144, SAP_TX_LEAKAGE_MIN} 671 } }, 672 673 {128, 674 {{36, 651}, {40, 651}, 675 {44, 674}, {48, 640}, 676 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 677 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 678 {100, 603}, {104, 560}, 679 {108, 540}, {112, 520}, 680 {116, 499}, {120, 479}, 681 {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN}, 682 {132, SAP_TX_LEAKAGE_MIN}, {136, 479}, 683 {140, 499}, 684 {144, SAP_TX_LEAKAGE_MIN} 685 } }, 686 687 {132, 688 {{36, 643}, {40, 668}, 689 {44, 651}, {48, 657}, 690 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 691 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 692 {100, SAP_TX_LEAKAGE_MAX}, {104, 602}, 693 {108, 578}, {112, 570}, 694 {116, 550}, {120, 530}, 695 {124, 510}, {128, SAP_TX_LEAKAGE_MIN}, 696 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 697 {140, 490}, 698 {144, SAP_TX_LEAKAGE_MIN} 699 } }, 700 701 {136, 702 {{36, 654}, {40, 667}, 703 {44, 666}, {48, 642}, 704 {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, 705 {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, 706 {100, SAP_TX_LEAKAGE_MAX}, {104, SAP_TX_LEAKAGE_MAX}, 707 {108, SAP_TX_LEAKAGE_MAX}, {112, 596}, 708 {116, 555}, {120, 535}, 709 {124, 515}, {128, 495}, 710 {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN}, 711 {140, SAP_TX_LEAKAGE_MIN}, 712 {144, SAP_TX_LEAKAGE_MIN} 713 } }, 714 715 {140, 716 {{36, 679}, {40, 673}, 717 {44, 667}, {48, 656}, 718 {52, 634}, {56, 663}, 719 {60, 662}, {64, 660}, 720 {100, SAP_TX_LEAKAGE_MAX}, {104, SAP_TX_LEAKAGE_MAX}, 721 {108, SAP_TX_LEAKAGE_MAX}, {112, 590}, 722 {116, 573}, {120, 553}, 723 {124, 533}, {128, 513}, 724 {132, 490}, {136, SAP_TX_LEAKAGE_MIN}, 725 {140, SAP_TX_LEAKAGE_MIN}, 726 {144, SAP_TX_LEAKAGE_MIN} 727 } }, 728 }; 729 #endif /* WLAN_ENABLE_CHNL_MATRIX_RESTRICTION */ 730 731 /*---------------------------------------------------------------------------- 732 * Static Function Declarations and Definitions 733 * -------------------------------------------------------------------------*/ 734 #ifdef SOFTAP_CHANNEL_RANGE 735 static QDF_STATUS sap_get_channel_list(ptSapContext sapContext, 736 uint8_t **channelList, 737 uint8_t *numberOfChannels); 738 #endif 739 740 /*========================================================================== 741 FUNCTION sap_get_5ghz_channel_list 742 743 DESCRIPTION 744 Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] available 745 channels in the current regulatory domain. 746 747 DEPENDENCIES 748 NA. 749 750 PARAMETERS 751 752 IN 753 sapContext: SAP Context 754 755 RETURN VALUE 756 NA 757 758 SIDE EFFECTS 759 ============================================================================*/ 760 static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext); 761 762 /*========================================================================== 763 FUNCTION sapStopDfsCacTimer 764 765 DESCRIPTION 766 Function to sttop the DFS CAC timer when SAP is stopped 767 DEPENDENCIES 768 NA. 769 770 PARAMETERS 771 772 IN 773 sapContext: SAP Context 774 RETURN VALUE 775 DFS Timer start status 776 SIDE EFFECTS 777 ============================================================================*/ 778 779 static int sap_stop_dfs_cac_timer(ptSapContext sapContext); 780 781 /*========================================================================== 782 FUNCTION sapStartDfsCacTimer 783 784 DESCRIPTION 785 Function to start the DFS CAC timer when SAP is started on DFS Channel 786 DEPENDENCIES 787 NA. 788 789 PARAMETERS 790 791 IN 792 sapContext: SAP Context 793 RETURN VALUE 794 DFS Timer start status 795 SIDE EFFECTS 796 ============================================================================*/ 797 798 int sap_start_dfs_cac_timer(ptSapContext sapContext); 799 800 /** sap_hdd_event_to_string() - convert hdd event to string 801 * @event: eSapHddEvent event type 802 * 803 * This function converts eSapHddEvent into string 804 * 805 * Return: string for the @event. 806 */ 807 static uint8_t *sap_hdd_event_to_string(eSapHddEvent event) 808 { 809 switch (event) { 810 CASE_RETURN_STRING(eSAP_START_BSS_EVENT); 811 CASE_RETURN_STRING(eSAP_STOP_BSS_EVENT); 812 CASE_RETURN_STRING(eSAP_STA_ASSOC_IND); 813 CASE_RETURN_STRING(eSAP_STA_ASSOC_EVENT); 814 CASE_RETURN_STRING(eSAP_STA_REASSOC_EVENT); 815 CASE_RETURN_STRING(eSAP_STA_DISASSOC_EVENT); 816 CASE_RETURN_STRING(eSAP_STA_SET_KEY_EVENT); 817 CASE_RETURN_STRING(eSAP_STA_MIC_FAILURE_EVENT); 818 CASE_RETURN_STRING(eSAP_ASSOC_STA_CALLBACK_EVENT); 819 CASE_RETURN_STRING(eSAP_GET_WPSPBC_SESSION_EVENT); 820 CASE_RETURN_STRING(eSAP_WPS_PBC_PROBE_REQ_EVENT); 821 CASE_RETURN_STRING(eSAP_REMAIN_CHAN_READY); 822 CASE_RETURN_STRING(eSAP_SEND_ACTION_CNF); 823 CASE_RETURN_STRING(eSAP_DISCONNECT_ALL_P2P_CLIENT); 824 CASE_RETURN_STRING(eSAP_MAC_TRIG_STOP_BSS_EVENT); 825 CASE_RETURN_STRING(eSAP_UNKNOWN_STA_JOIN); 826 CASE_RETURN_STRING(eSAP_MAX_ASSOC_EXCEEDED); 827 CASE_RETURN_STRING(eSAP_CHANNEL_CHANGE_EVENT); 828 CASE_RETURN_STRING(eSAP_DFS_CAC_START); 829 CASE_RETURN_STRING(eSAP_DFS_CAC_END); 830 CASE_RETURN_STRING(eSAP_DFS_PRE_CAC_END); 831 CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT); 832 CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC); 833 CASE_RETURN_STRING(eSAP_DFS_NOL_GET); 834 CASE_RETURN_STRING(eSAP_DFS_NOL_SET); 835 CASE_RETURN_STRING(eSAP_DFS_NO_AVAILABLE_CHANNEL); 836 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 837 CASE_RETURN_STRING(eSAP_ACS_SCAN_SUCCESS_EVENT); 838 #endif 839 CASE_RETURN_STRING(eSAP_ACS_CHANNEL_SELECTED); 840 default: 841 return "eSAP_HDD_EVENT_UNKNOWN"; 842 } 843 } 844 845 /*---------------------------------------------------------------------------- 846 * Externalized Function Definitions 847 * -------------------------------------------------------------------------*/ 848 849 /*---------------------------------------------------------------------------- 850 * Function Declarations and Documentation 851 * -------------------------------------------------------------------------*/ 852 853 /*========================================================================== 854 FUNCTION sap_event_init 855 856 DESCRIPTION 857 Function for initializing sWLAN_SAPEvent structure 858 859 DEPENDENCIES 860 NA. 861 862 PARAMETERS 863 864 IN 865 sapEvent : State machine event 866 867 RETURN VALUE 868 869 None 870 871 SIDE EFFECTS 872 ============================================================================*/ 873 static inline void sap_event_init(ptWLAN_SAPEvent sapEvent) 874 { 875 sapEvent->event = eSAP_MAC_SCAN_COMPLETE; 876 sapEvent->params = 0; 877 sapEvent->u1 = 0; 878 sapEvent->u2 = 0; 879 } 880 881 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 882 /* 883 * sap_find_target_channel_in_channel_matrix() - finds the leakage matrix 884 * @sapContext: Pointer to vos global context structure 885 * @ch_width: target channel width 886 * @NOL_channel: the NOL channel whose leakage matrix is required 887 * @pTarget_chnl_mtrx: pointer to target channel matrix returned. 888 * 889 * This function gives the leakage matrix for given NOL channel and ch_width 890 * 891 * Return: TRUE or FALSE 892 */ 893 bool 894 sap_find_target_channel_in_channel_matrix(ptSapContext sapContext, 895 enum phy_ch_width ch_width, 896 uint8_t NOL_channel, 897 tSapTxLeakInfo **pTarget_chnl_mtrx) 898 { 899 tSapTxLeakInfo *target_chan_matrix = NULL; 900 tSapChanMatrixInfo *pchan_matrix = NULL; 901 uint32_t nchan_matrix; 902 int i = 0; 903 904 switch (ch_width) { 905 case CH_WIDTH_20MHZ: 906 /* HT20 */ 907 pchan_matrix = ht20_chan; 908 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 909 break; 910 case CH_WIDTH_40MHZ: 911 /* HT40 */ 912 pchan_matrix = ht40_chan; 913 nchan_matrix = QDF_ARRAY_SIZE(ht40_chan); 914 break; 915 case CH_WIDTH_80MHZ: 916 /* HT80 */ 917 pchan_matrix = ht80_chan; 918 nchan_matrix = QDF_ARRAY_SIZE(ht80_chan); 919 break; 920 default: 921 /* handle exception and fall back to HT20 table */ 922 pchan_matrix = ht20_chan; 923 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); 924 break; 925 } 926 927 for (i = 0; i < nchan_matrix; i++) { 928 /* find the SAP channel to map the leakage matrix */ 929 if (NOL_channel == pchan_matrix[i].channel) { 930 target_chan_matrix = pchan_matrix[i].chan_matrix; 931 break; 932 } 933 } 934 935 if (NULL == target_chan_matrix) { 936 return false; 937 } else { 938 *pTarget_chnl_mtrx = target_chan_matrix; 939 return true; 940 } 941 } 942 943 /** 944 * sap_mark_leaking_ch() - to mark channel leaking in to nol 945 * @sap_ctx: pointer to SAP context 946 * @ch_width: channel width 947 * @nol: nol info 948 * @temp_ch_lst_sz: the target channel list 949 * @temp_ch_lst: the target channel list 950 * 951 * This function removes the channels from temp channel list that 952 * (if selected as target channel) will cause leakage in one of 953 * the NOL channels 954 * 955 * Return: QDF_STATUS 956 */ 957 958 QDF_STATUS 959 sap_mark_leaking_ch(ptSapContext sap_ctx, 960 enum phy_ch_width ch_width, 961 tSapDfsNolInfo *nol, 962 uint8_t temp_ch_lst_sz, 963 uint8_t *temp_ch_lst) 964 { 965 tSapTxLeakInfo *target_chan_matrix = NULL; 966 uint32_t num_channel = (CHAN_ENUM_144 - CHAN_ENUM_36) + 1; 967 uint32_t i = 0; 968 uint32_t j = 0; 969 uint32_t k = 0; 970 uint8_t dfs_nol_channel; 971 972 973 /* traverse target_chan_matrix and */ 974 for (i = 0; i < NUM_5GHZ_CHANNELS ; i++) { 975 dfs_nol_channel = nol[i].dfs_channel_number; 976 if (nol[i].radar_status_flag == eSAP_DFS_CHANNEL_USABLE || 977 nol[i].radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE) { 978 /* not present in NOL */ 979 continue; 980 } 981 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 982 FL("sapdfs: processing NOL channel: %d"), 983 dfs_nol_channel); 984 if (false == sap_find_target_channel_in_channel_matrix( 985 sap_ctx, ch_width, dfs_nol_channel, 986 &target_chan_matrix)) { 987 /* 988 * should never happen, we should always find a table 989 * here, if we don't, need a fix here! 990 */ 991 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 992 FL("Couldn't find target channel matrix!")); 993 QDF_ASSERT(0); 994 return QDF_STATUS_E_FAILURE; 995 } 996 /* 997 * following is based on assumption that both temp_ch_lst 998 * and target channel matrix are in increasing order of 999 * ch_id 1000 */ 1001 for (j = 0, k = 0; j < temp_ch_lst_sz && k < num_channel;) { 1002 if (temp_ch_lst[j] == 0) { 1003 j++; 1004 continue; 1005 } 1006 if (target_chan_matrix[k].leak_chan != temp_ch_lst[j]) { 1007 k++; 1008 continue; 1009 } 1010 /* 1011 * check leakage from candidate channel 1012 * to NOL channel 1013 */ 1014 if (target_chan_matrix[k].leak_lvl <= 1015 SAP_TX_LEAKAGE_THRES) { 1016 /* 1017 * candidate channel will have 1018 * bad leakage in NOL channel, 1019 * remove from temp list 1020 */ 1021 QDF_TRACE(QDF_MODULE_ID_SAP, 1022 QDF_TRACE_LEVEL_INFO_LOW, 1023 FL("sapdfs: channel: %d will have bad leakage due to channel: %d\n"), 1024 dfs_nol_channel, temp_ch_lst[j]); 1025 temp_ch_lst[j] = 0; 1026 break; 1027 } 1028 j++; 1029 k++; 1030 } 1031 } /* end of loop that selects each NOL */ 1032 return QDF_STATUS_SUCCESS; 1033 } 1034 #endif /* end of WLAN_ENABLE_CHNL_MATRIX_RESTRICTION */ 1035 1036 /* 1037 * This function adds availabe channel to bitmap 1038 * 1039 * PARAMETERS 1040 * IN 1041 * pBitmap: bitmap to populate 1042 * channel: channel to set in bitmap 1043 */ 1044 static void sap_set_bitmap(chan_bonding_bitmap *pBitmap, uint8_t channel) 1045 { 1046 int i = 0; 1047 int start_channel = 0; 1048 for (i = 0; i < MAX_80MHZ_BANDS; i++) { 1049 start_channel = pBitmap->chanBondingSet[i].startChannel; 1050 if (channel >= start_channel && channel <= start_channel + 12) { 1051 pBitmap->chanBondingSet[i].channelMap |= 1052 1 << ((channel - start_channel) / 4); 1053 return; 1054 } 1055 } 1056 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1057 FL("Channel=%d is not in the bitmap"), channel); 1058 } 1059 1060 /** 1061 * sap_populate_available_channels() - To populate available channel 1062 * @bitmap: bitmap to populate 1063 * @ch_width: channel width 1064 * @avail_chnl: available channel list to populate 1065 * 1066 * This function reads the bitmap and populates available channel 1067 * list according to channel bonding mode. This will be called for 1068 * 80 MHz and 40 Mhz only. For 20 MHz no need for bitmap hence list 1069 * is directly created while parsing the main list 1070 * 1071 * Return: number of channels found 1072 */ 1073 static uint8_t sap_populate_available_channels(chan_bonding_bitmap *bitmap, 1074 enum phy_ch_width ch_width, 1075 uint8_t *avail_chnl) 1076 { 1077 uint8_t i = 0; 1078 uint8_t chnl_count = 0; 1079 uint8_t start_channel = 0; 1080 1081 switch (ch_width) { 1082 /* VHT80 */ 1083 case CH_WIDTH_160MHZ: 1084 case CH_WIDTH_80P80MHZ: 1085 case CH_WIDTH_80MHZ: 1086 for (i = 0; i < MAX_80MHZ_BANDS; i++) { 1087 start_channel = bitmap->chanBondingSet[i].startChannel; 1088 if (bitmap->chanBondingSet[i].channelMap == 1089 SAP_80MHZ_MASK) { 1090 avail_chnl[chnl_count++] = start_channel; 1091 avail_chnl[chnl_count++] = start_channel + 4; 1092 avail_chnl[chnl_count++] = start_channel + 8; 1093 avail_chnl[chnl_count++] = start_channel + 12; 1094 } 1095 } 1096 break; 1097 /* HT40 */ 1098 case CH_WIDTH_40MHZ: 1099 for (i = 0; i < MAX_80MHZ_BANDS; i++) { 1100 start_channel = bitmap->chanBondingSet[i].startChannel; 1101 if ((bitmap->chanBondingSet[i].channelMap & 1102 SAP_40MHZ_MASK_L) == SAP_40MHZ_MASK_L) { 1103 avail_chnl[chnl_count++] = start_channel; 1104 avail_chnl[chnl_count++] = start_channel + 4; 1105 } 1106 if ((bitmap->chanBondingSet[i].channelMap & 1107 SAP_40MHZ_MASK_H) == SAP_40MHZ_MASK_H) { 1108 avail_chnl[chnl_count++] = start_channel + 8; 1109 avail_chnl[chnl_count++] = start_channel + 12; 1110 } 1111 } 1112 break; 1113 default: 1114 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1115 FL("Invalid case.")); 1116 break; 1117 } 1118 1119 return chnl_count; 1120 } 1121 1122 /* 1123 * FUNCTION sap_dfs_is_w53_invalid 1124 * 1125 * DESCRIPTION Checks if the passed channel is W53 and returns if 1126 * SAP W53 opearation is allowed. 1127 * 1128 * DEPENDENCIES PARAMETERS 1129 * IN hHAL : HAL pointer 1130 * channelID: Channel Number to be verified 1131 * 1132 * RETURN VALUE : bool 1133 * true: If W53 operation is disabled 1134 * false: If W53 operation is enabled 1135 * 1136 * SIDE EFFECTS 1137 */ 1138 bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID) 1139 { 1140 tpAniSirGlobal pMac; 1141 1142 pMac = PMAC_STRUCT(hHal); 1143 if (NULL == pMac) { 1144 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1145 FL("invalid pMac")); 1146 return false; 1147 } 1148 1149 /* 1150 * Check for JAPAN W53 Channel operation capability 1151 */ 1152 if (true == pMac->sap.SapDfsInfo.is_dfs_w53_disabled && 1153 true == IS_CHAN_JAPAN_W53(channelID)) { 1154 return true; 1155 } 1156 1157 return false; 1158 } 1159 1160 /* 1161 * FUNCTION sap_dfs_is_channel_in_preferred_location 1162 * 1163 * DESCRIPTION Checks if the passed channel is in accordance with preferred 1164 * Channel location settings. 1165 * 1166 * DEPENDENCIES PARAMETERS 1167 * IN hHAL : HAL pointer 1168 * channelID: Channel Number to be verified 1169 * 1170 * RETURN VALUE :bool 1171 * true:If Channel location is same as the preferred location 1172 * false:If Channel location is not same as the preferred location 1173 * 1174 * SIDE EFFECTS 1175 */ 1176 bool sap_dfs_is_channel_in_preferred_location(tHalHandle hHal, uint8_t channelID) 1177 { 1178 tpAniSirGlobal pMac; 1179 1180 pMac = PMAC_STRUCT(hHal); 1181 if (NULL == pMac) { 1182 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1183 FL("invalid pMac")); 1184 return true; 1185 } 1186 if ((SAP_CHAN_PREFERRED_INDOOR == 1187 pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) && 1188 (true == IS_CHAN_JAPAN_OUTDOOR(channelID))) { 1189 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1190 FL 1191 ("CHAN=%d is Outdoor so invalid,preferred Indoor only"), 1192 channelID); 1193 return false; 1194 } else if ((SAP_CHAN_PREFERRED_OUTDOOR == 1195 pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) 1196 && (true == IS_CHAN_JAPAN_INDOOR(channelID))) { 1197 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1198 FL 1199 ("CHAN=%d is Indoor so invalid,preferred Outdoor only"), 1200 channelID); 1201 return false; 1202 } 1203 1204 return true; 1205 } 1206 1207 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 1208 /** 1209 * sap_check_in_avoid_ch_list() - checks if given channel present is channel 1210 * avoidance list 1211 * 1212 * @sap_ctx: sap context. 1213 * @channel: channel to be checked in sap_ctx's avoid ch list 1214 * 1215 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on 1216 * which MDM device's AP with MCC was detected. This function checks if given 1217 * channel is present in that list. 1218 * 1219 * Return: true, if channel was present, false othersie. 1220 */ 1221 bool sap_check_in_avoid_ch_list(ptSapContext sap_ctx, uint8_t channel) 1222 { 1223 uint8_t i = 0; 1224 struct sap_avoid_channels_info *ie_info = 1225 &sap_ctx->sap_detected_avoid_ch_ie; 1226 for (i = 0; i < sizeof(ie_info->channels); i++) 1227 if (ie_info->channels[i] == channel) 1228 return true; 1229 return false; 1230 } 1231 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 1232 1233 /** 1234 * sap_apply_rules() - validates channels in sap_ctx channel list 1235 * @sap_ctx: sap context pointer 1236 * 1237 * This function takes the channel list in sap_ctx and marks invalid channel 1238 * based on following rules: 1239 * -> invalid due to different reg domain dfs channel list 1240 * -> already present in NOL 1241 * -> outside ACS range or not 1242 * -> not usable due to another SAP operating MCC mode in same channel 1243 * -> preferred location is indoors or outdoors 1244 * 1245 * Return: number of valid channels after applying all the rules 1246 */ 1247 static uint8_t sap_apply_rules(ptSapContext sap_ctx) 1248 { 1249 uint8_t num_valid_ch, dfs_region, i = 0, ch_id; 1250 tAll5GChannelList *sap_all_ch = &sap_ctx->SapAllChnlList; 1251 bool is_ch_nol = false; 1252 bool is_out_of_range = false; 1253 tpAniSirGlobal mac_ctx; 1254 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 1255 uint8_t preferred_location; 1256 1257 if (NULL == hal) { 1258 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1259 FL("hal pointer NULL")); 1260 return 0; 1261 } 1262 1263 mac_ctx = PMAC_STRUCT(hal); 1264 if (NULL == mac_ctx) { 1265 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1266 FL("mac_ctx pointer NULL")); 1267 return 0; 1268 } 1269 1270 preferred_location = 1271 mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location; 1272 cds_get_dfs_region(&dfs_region); 1273 /* loop to check ACS range or NOL channels */ 1274 num_valid_ch = sap_all_ch->numChannel; 1275 for (i = 0; i < sap_all_ch->numChannel; i++) { 1276 ch_id = sap_all_ch->channelList[i].channel; 1277 1278 /* 1279 * IN MKK DFS REGION CHECK IF THE FOLLOWING TWO 1280 * TWO RULES APPLY AND FILTER THE AVAILABLE CHANNELS 1281 * ACCORDINGLY. 1282 * 1283 * 1. If we are operating in Japan regulatory domain 1284 * Check if Japan W53 Channel operation is NOT 1285 * allowed and if its not allowed then mark all the 1286 * W53 channels as Invalid. 1287 * 1288 * 2. If we are operating in Japan regulatory domain 1289 * Check if channel switch between Indoor/Outdoor 1290 * is allowed. If it is not allowed then limit 1291 * the avaiable channels to Indoor or Outdoor 1292 * channels only based up on the SAP Channel location 1293 * indicated by "sap_operating_channel_location" param. 1294 */ 1295 if (DFS_MKK_REGION == dfs_region) { 1296 /* 1297 * Check for JAPAN W53 Channel operation capability 1298 */ 1299 if (true == sap_dfs_is_w53_invalid(hal, ch_id)) { 1300 QDF_TRACE(QDF_MODULE_ID_SAP, 1301 QDF_TRACE_LEVEL_INFO_LOW, 1302 FL("index:%d, Channel=%d Invalid,Japan W53 Disabled"), 1303 i, ch_id); 1304 sap_all_ch->channelList[i].valid = false; 1305 num_valid_ch--; 1306 continue; 1307 } 1308 1309 /* 1310 * If SAP's preferred channel location is Indoor 1311 * then set all the outdoor channels in the domain 1312 * to invalid.If the preferred channel location is 1313 * outdoor then set all the Indoor channels in the 1314 * domain to Invalid. 1315 */ 1316 if (false == 1317 sap_dfs_is_channel_in_preferred_location(hal, 1318 ch_id)) { 1319 QDF_TRACE(QDF_MODULE_ID_SAP, 1320 QDF_TRACE_LEVEL_INFO_LOW, 1321 FL("CHAN=%d is invalid,preferred Channel Location %d Only"), 1322 ch_id, preferred_location); 1323 sap_all_ch->channelList[i].valid = false; 1324 num_valid_ch--; 1325 continue; 1326 } 1327 } 1328 1329 if (cds_get_channel_state(ch_id) == CHANNEL_STATE_DFS) { 1330 is_ch_nol = sap_dfs_is_channel_in_nol_list(sap_ctx, 1331 ch_id, PHY_SINGLE_CHANNEL_CENTERED); 1332 if (true == is_ch_nol) { 1333 /* 1334 * Mark this channel invalid since it is still 1335 * in DFS Non-Occupancy-Period which is 30 mins. 1336 */ 1337 QDF_TRACE(QDF_MODULE_ID_SAP, 1338 QDF_TRACE_LEVEL_INFO_LOW, 1339 FL("index: %d, Channel = %d Present in NOL LIST"), 1340 i, ch_id); 1341 sap_all_ch->channelList[i].valid = false; 1342 num_valid_ch--; 1343 continue; 1344 } 1345 } 1346 1347 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 1348 /* avoid ch on which another MDM AP in MCC mode is detected */ 1349 if (mac_ctx->sap.sap_channel_avoidance 1350 && sap_ctx->sap_detected_avoid_ch_ie.present) { 1351 if (sap_check_in_avoid_ch_list(sap_ctx, ch_id)) { 1352 QDF_TRACE(QDF_MODULE_ID_SAP, 1353 QDF_TRACE_LEVEL_INFO_LOW, 1354 FL("index: %d, Channel = %d, avoided due to presence of another AP+AP MCC device in same channel."), 1355 i, ch_id); 1356 sap_all_ch->channelList[i].valid = false; 1357 } 1358 } 1359 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 1360 1361 /* check if the channel is within ACS channel range */ 1362 is_out_of_range = sap_acs_channel_check(sap_ctx, ch_id); 1363 if (true == is_out_of_range) { 1364 /* 1365 * mark this channel invalid since it is out of ACS 1366 * channel range 1367 */ 1368 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1369 FL("index: %d, Channel = %d out of ACS channel range"), 1370 i, ch_id); 1371 sap_all_ch->channelList[i].valid = false; 1372 num_valid_ch--; 1373 continue; 1374 } 1375 } /* end of check for NOL or ACS channels */ 1376 return num_valid_ch; 1377 } 1378 1379 /** 1380 * select_rand_from_lst() - selects random channel from given list 1381 * @mac_ctx: mac context pointer 1382 * @ch_lst: channel list 1383 * @num_ch: number of channels 1384 * 1385 * Return: new target channel randomly selected 1386 */ 1387 static uint8_t select_rand_from_lst(tpAniSirGlobal mac_ctx, uint8_t *ch_lst, 1388 uint8_t num_ch) 1389 { 1390 uint32_t rand_byte = 0; 1391 uint8_t i, target_channel, non_dfs_num_ch = 0, dfs_num_ch = 0; 1392 uint8_t dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; 1393 uint8_t non_dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; 1394 if (num_ch) { 1395 for (i = 0; i < num_ch; i++) { 1396 if (CDS_IS_DFS_CH(ch_lst[i])) 1397 dfs_ch[dfs_num_ch++] = ch_lst[i]; 1398 else 1399 non_dfs_ch[non_dfs_num_ch++] = ch_lst[i]; 1400 } 1401 } else { 1402 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1403 FL("No target channel found")); 1404 return 0; 1405 } 1406 1407 cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); 1408 1409 /* Give preference to non-DFS channel */ 1410 if (!mac_ctx->f_prefer_non_dfs_on_radar) { 1411 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch; 1412 target_channel = ch_lst[i]; 1413 } else if (non_dfs_num_ch) { 1414 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1415 non_dfs_num_ch; 1416 target_channel = non_dfs_ch[i]; 1417 } else { 1418 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % dfs_num_ch; 1419 target_channel = dfs_ch[i]; 1420 } 1421 1422 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1423 FL("sapdfs: New Channel width = %d"), 1424 mac_ctx->sap.SapDfsInfo.new_chanWidth); 1425 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1426 FL("sapdfs: target_channel = %d"), target_channel); 1427 1428 return target_channel; 1429 } 1430 1431 /** 1432 * sap_find_ch_wh_fallback() - find given channel width from given list of 1433 * channels 1434 * @mac_ctx: mac context pointer 1435 * @ch_wd: channel width to find 1436 * @ch_lst: list of channels 1437 * @num_ch: number of channels 1438 * 1439 * This function tries to find given channel width and returns new target ch. 1440 * If not found updates ch_wd to next lower channel width. 1441 * 1442 * Return: new target channel if successful, 0 otherwise 1443 */ 1444 static uint8_t sap_find_ch_wh_fallback(tpAniSirGlobal mac_ctx, 1445 enum phy_ch_width *ch_wd, 1446 uint8_t *ch_lst, 1447 uint8_t num_ch) 1448 { 1449 bool flag = false; 1450 uint32_t rand_byte = 0; 1451 chan_bonding_bitmap ch_map = { { {0} } }; 1452 uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0; 1453 uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; 1454 uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; 1455 1456 /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ 1457 ch_map.chanBondingSet[0].startChannel = 36; 1458 ch_map.chanBondingSet[1].startChannel = 52; 1459 ch_map.chanBondingSet[2].startChannel = 100; 1460 ch_map.chanBondingSet[3].startChannel = 116; 1461 ch_map.chanBondingSet[4].startChannel = 132; 1462 ch_map.chanBondingSet[5].startChannel = 149; 1463 1464 /* now loop through leakage free list */ 1465 for (i = 0; i < num_ch; i++) { 1466 /* add tmp ch to bitmap */ 1467 if (ch_lst[i] == 0) 1468 continue; 1469 1470 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 1471 FL("sapdfs: Channel=%d added to bitmap"), 1472 ch_lst[i]); 1473 sap_set_bitmap(&ch_map, ch_lst[i]); 1474 } 1475 1476 /* populate available channel list from bitmap */ 1477 final_cnt = sap_populate_available_channels(&ch_map, *ch_wd, final_lst); 1478 /* If no valid ch bonding found, fallback */ 1479 if (final_cnt == 0) { 1480 if ((*ch_wd == CH_WIDTH_160MHZ) || 1481 (*ch_wd == CH_WIDTH_80P80MHZ) || 1482 (*ch_wd == CH_WIDTH_80MHZ)) { 1483 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 1484 FL("sapdfs:Changing chanWidth from [%d] to 40Mhz"), 1485 *ch_wd); 1486 *ch_wd = CH_WIDTH_40MHZ; 1487 } else if (*ch_wd == CH_WIDTH_40MHZ) { 1488 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 1489 FL("sapdfs:No 40MHz cb found, falling to 20MHz")); 1490 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 1491 FL("sapdfs:Changing chanWidth from [%d] to [%d]"), 1492 *ch_wd, CH_WIDTH_20MHZ); 1493 *ch_wd = CH_WIDTH_20MHZ; 1494 } 1495 return 0; 1496 } 1497 1498 /* ch count should be > 8 to switch new channel in 160Mhz band */ 1499 if (((*ch_wd == CH_WIDTH_160MHZ) || (*ch_wd == CH_WIDTH_80P80MHZ)) && 1500 (final_cnt < SIR_DFS_MAX_20M_SUB_CH)) { 1501 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 1502 FL("sapdfs:Changing chanWidth from [%d] to [%d]"), 1503 *ch_wd, CH_WIDTH_80MHZ); 1504 *ch_wd = CH_WIDTH_80MHZ; 1505 return 0; 1506 } 1507 if (*ch_wd == CH_WIDTH_160MHZ) { 1508 /* 1509 * NA supports only 2 blocks for 160Mhz bandwidth i.e 36-64 & 1510 * 100-128 and all the channels in these blocks are continuous 1511 * and seperated by 4Mhz. 1512 */ 1513 for (i = 1; ((i < final_cnt)); i++) { 1514 if ((final_lst[i] - final_lst[i-1]) == 4) 1515 count++; 1516 else 1517 count = 0; 1518 if (count == SIR_DFS_MAX_20M_SUB_CH - 1) { 1519 flag = true; 1520 new_160_start_ch = final_lst[i-7]; 1521 break; 1522 } 1523 } 1524 } else if (*ch_wd == CH_WIDTH_80P80MHZ) { 1525 flag = true; 1526 } 1527 if ((flag == false) && (*ch_wd > CH_WIDTH_80MHZ)) { 1528 *ch_wd = CH_WIDTH_80MHZ; 1529 return 0; 1530 } 1531 1532 if (*ch_wd == CH_WIDTH_160MHZ) { 1533 cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); 1534 rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) 1535 % SIR_DFS_MAX_20M_SUB_CH; 1536 target_channel = new_160_start_ch + (rand_byte * 4); 1537 } else if (*ch_wd == CH_WIDTH_80P80MHZ) { 1538 cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); 1539 index = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1540 final_cnt; 1541 target_channel = final_lst[index]; 1542 index -= (index % 4); 1543 primary_seg_start_ch = final_lst[index]; 1544 1545 /* reset channels associate with primary 80Mhz */ 1546 for (i = 0; i < 4; i++) 1547 final_lst[i + index] = 0; 1548 /* select and calculate center freq for secondary segement */ 1549 for (i = 0; i < final_cnt / 4; i++) { 1550 if (final_lst[i * 4] && 1551 (abs(primary_seg_start_ch - final_lst[i * 4]) > 1552 (SIR_DFS_MAX_20M_SUB_CH * 2))) { 1553 sec_seg_ch = final_lst[i * 4] + 1554 SIR_80MHZ_START_CENTER_CH_DIFF; 1555 break; 1556 } 1557 } 1558 if (!sec_seg_ch && (final_cnt == SIR_DFS_MAX_20M_SUB_CH)) 1559 *ch_wd = CH_WIDTH_160MHZ; 1560 else if (!sec_seg_ch) 1561 *ch_wd = CH_WIDTH_80MHZ; 1562 1563 mac_ctx->sap.SapDfsInfo.new_ch_params.center_freq_seg1 1564 = sec_seg_ch; 1565 1566 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1567 FL("sapdfs: New Center Freq Seg1 = %d"), sec_seg_ch); 1568 } else { 1569 target_channel = select_rand_from_lst(mac_ctx, final_lst, 1570 final_cnt); 1571 } 1572 return target_channel; 1573 } 1574 1575 /** 1576 * sap_random_channel_sel() - This function randomly pick up an available 1577 * channel 1578 * @sap_ctx: sap context. 1579 * 1580 * This function first eliminates invalid channel, then selects random channel 1581 * using following algorithm: 1582 * PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules 1583 * PASS: 2 - now mark channels that will leak into NOL 1584 * PASS: 3 - from leakage_adjusted_lst, either select random channel (for 20MHz) 1585 * or find given channel width possible. if not found fallback to 1586 * lower channel width and try again. once given channel width found 1587 * use random channel from give possibilities. 1588 * Return: channel number picked 1589 */ 1590 static uint8_t sap_random_channel_sel(ptSapContext sap_ctx) 1591 { 1592 uint8_t j = 0, i = 0, final_cnt = 0, target_channel = 0; 1593 /* count and ch list after applying all rules */ 1594 uint8_t rule_adjusted_cnt, *rule_adjusted_lst; 1595 /* ch list after invalidating channels leaking into NOL */ 1596 uint8_t *leakage_adjusted_lst; 1597 /* final list of channel from which random channel will be selected */ 1598 uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; 1599 tAll5GChannelList *all_ch = &sap_ctx->SapAllChnlList; 1600 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 1601 tpAniSirGlobal mac_ctx; 1602 /* channel width for current iteration */ 1603 enum phy_ch_width ch_wd; 1604 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 1605 tSapDfsNolInfo *nol; 1606 #endif 1607 1608 if (NULL == hal) { 1609 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1610 FL("invalid hal")); 1611 return 0; 1612 } 1613 1614 mac_ctx = PMAC_STRUCT(hal); 1615 if (NULL == mac_ctx) { 1616 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1617 FL("invalid mac_ctx")); 1618 return 0; 1619 } 1620 1621 /* 1622 * Retrieve the original one and store it. 1623 * use the stored original value when you call this function next time 1624 * so fall back mechanism always starts with original ini value. 1625 */ 1626 if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) { 1627 ch_wd = sap_ctx->ch_width_orig; 1628 mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd; 1629 } else { 1630 ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth; 1631 } 1632 1633 if (sap_get_5ghz_channel_list(sap_ctx)) { 1634 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1635 FL("Getting 5Ghz channel list failed")); 1636 return 0; 1637 } 1638 1639 /* PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules */ 1640 rule_adjusted_cnt = sap_apply_rules(sap_ctx); 1641 if (0 == rule_adjusted_cnt) { 1642 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1643 FL("No channels left after applying rules.")); 1644 return 0; 1645 } 1646 1647 /* this is list we get after applying all rules */ 1648 rule_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt); 1649 1650 /* list adjusted after leakage has been marked */ 1651 leakage_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt); 1652 if (rule_adjusted_lst == NULL || leakage_adjusted_lst == NULL) { 1653 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1654 FL("sapdfs: memory alloc failed")); 1655 qdf_mem_free(rule_adjusted_lst); 1656 qdf_mem_free(leakage_adjusted_lst); 1657 return 0; 1658 } 1659 1660 /* copy valid ch from sap_ctx->all_ch_lst into rule_adjusted_lst */ 1661 for (i = 0, j = 0; i < all_ch->numChannel; i++) { 1662 if (!all_ch->channelList[i].valid) 1663 continue; 1664 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1665 FL("sapdfs: Adding Channel = %d to temp List"), 1666 all_ch->channelList[i].channel); 1667 rule_adjusted_lst[j++] = all_ch->channelList[i].channel; 1668 } 1669 1670 /* 1671 * do - while loop for fallback mechanism. at each channel width this 1672 * will try to find channel bonding, if not fall back to lower ch width 1673 */ 1674 do { 1675 /* save rules adjusted lst */ 1676 qdf_mem_copy(leakage_adjusted_lst, rule_adjusted_lst, 1677 rule_adjusted_cnt); 1678 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 1679 nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList; 1680 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1681 FL("sapdfs: Processing tmp ch list against NOL.")); 1682 /* PASS: 2 - now mark channels that will leak into NOL */ 1683 if (sap_mark_leaking_ch(sap_ctx, ch_wd, nol, rule_adjusted_cnt, 1684 leakage_adjusted_lst) != QDF_STATUS_SUCCESS) { 1685 qdf_mem_free(rule_adjusted_lst); 1686 qdf_mem_free(leakage_adjusted_lst); 1687 return 0; 1688 } 1689 #endif 1690 if (ch_wd == CH_WIDTH_20MHZ) { 1691 /* 1692 * PASS: 3 - from leakage_adjusted_lst, prepare valid 1693 * ch list and use random number from that 1694 */ 1695 for (i = 0; i < rule_adjusted_cnt; i++) { 1696 if (leakage_adjusted_lst[i] == 0) 1697 continue; 1698 QDF_TRACE(QDF_MODULE_ID_SAP, 1699 QDF_TRACE_LEVEL_DEBUG, 1700 FL("sapdfs: Channel=%d added to available list"), 1701 leakage_adjusted_lst[i]); 1702 final_lst[final_cnt] = leakage_adjusted_lst[i]; 1703 final_cnt++; 1704 } 1705 target_channel = select_rand_from_lst(mac_ctx, 1706 final_lst, final_cnt); 1707 break; 1708 } 1709 1710 /* 1711 * PASS: 3 - following function will check from valid channels 1712 * left if given ch_wd can be supported. if not reduce ch_wd 1713 * (fallback), then continue with reduced ch_wd 1714 */ 1715 target_channel = sap_find_ch_wh_fallback(mac_ctx, &ch_wd, 1716 leakage_adjusted_lst, 1717 rule_adjusted_cnt); 1718 /* 1719 * if target channel is 0, no channel bonding was found 1720 * ch_wd would have been updated for fallback 1721 */ 1722 if (0 == target_channel) 1723 continue; 1724 else 1725 break; 1726 } while (true); 1727 1728 if (target_channel) 1729 mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_wd; 1730 1731 qdf_mem_free(rule_adjusted_lst); 1732 qdf_mem_free(leakage_adjusted_lst); 1733 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1734 FL("sapdfs: New Channel width = %d"), 1735 mac_ctx->sap.SapDfsInfo.new_chanWidth); 1736 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1737 FL("sapdfs: target_channel = %d"), 1738 target_channel); 1739 return target_channel; 1740 } 1741 1742 bool sap_acs_channel_check(ptSapContext sapContext, uint8_t channelNumber) 1743 { 1744 int i = 0; 1745 if (!sapContext->acs_cfg->acs_mode) 1746 return false; 1747 1748 if ((channelNumber >= sapContext->acs_cfg->start_ch) || 1749 (channelNumber <= sapContext->acs_cfg->end_ch)) { 1750 if (!sapContext->acs_cfg->ch_list) { 1751 return false; 1752 } else { 1753 for (i = 0; i < sapContext->acs_cfg->ch_list_count; i++) 1754 if (channelNumber == 1755 sapContext->acs_cfg->ch_list[i]) 1756 return false; 1757 } 1758 } 1759 return true; 1760 } 1761 1762 /** 1763 * sap_mark_dfs_channels() - to mark dfs channel 1764 * @sapContext: pointer sap context 1765 * @channels: list of channels 1766 * @numChannels: number of channels 1767 * @time: time 1768 * 1769 * Mark the channels in NOL with time and eSAP_DFS_CHANNEL_UNAVAILABLE 1770 * 1771 * Return: none 1772 */ 1773 void sap_mark_dfs_channels(ptSapContext sapContext, uint8_t *channels, 1774 uint8_t numChannels, uint64_t time) 1775 { 1776 int i, j; 1777 tSapDfsNolInfo *psapDfsChannelNolList = NULL; 1778 uint8_t nRegDomainDfsChannels; 1779 tHalHandle hHal; 1780 tpAniSirGlobal pMac; 1781 1782 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 1783 if (NULL == channels) 1784 return; 1785 if (NULL == hHal) { 1786 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1787 FL("invalid hHal")); 1788 return; 1789 } 1790 pMac = PMAC_STRUCT(hHal); 1791 if (NULL == pMac) { 1792 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1793 FL("invalid pMac")); 1794 return; 1795 } 1796 1797 /* 1798 * Mark the current channel on which Radar is found 1799 * in the NOL list as eSAP_DFS_CHANNEL_UNAVAILABLE. 1800 */ 1801 psapDfsChannelNolList = pMac->sap.SapDfsInfo.sapDfsChannelNolList; 1802 nRegDomainDfsChannels = 1803 pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; 1804 1805 for (i = 0; i < numChannels; i++) { 1806 for (j = 0; j <= nRegDomainDfsChannels; j++) { 1807 if (!(psapDfsChannelNolList[j].dfs_channel_number == 1808 channels[i])) 1809 continue; 1810 /* 1811 * If channel is already in NOL, don't update it again. 1812 * This is useful when marking bonding channels which 1813 * are already unavailable. 1814 */ 1815 if (psapDfsChannelNolList[j].radar_status_flag == 1816 eSAP_DFS_CHANNEL_UNAVAILABLE) { 1817 QDF_TRACE(QDF_MODULE_ID_SAP, 1818 QDF_TRACE_LEVEL_INFO_HIGH, 1819 FL("Channel=%d already in NOL"), 1820 channels[i]); 1821 continue; 1822 } 1823 /* 1824 * Capture the Radar Found timestamp on the 1825 * Current Channel in ms. 1826 */ 1827 psapDfsChannelNolList[j].radar_found_timestamp = time; 1828 /* Mark the Channel to be unavailble for next 30 mins */ 1829 psapDfsChannelNolList[j].radar_status_flag = 1830 eSAP_DFS_CHANNEL_UNAVAILABLE; 1831 1832 QDF_TRACE(QDF_MODULE_ID_SAP, 1833 QDF_TRACE_LEVEL_INFO_HIGH, 1834 FL("Channel=%d Added to NOL LIST"), 1835 channels[i]); 1836 } 1837 } 1838 } 1839 1840 /* 1841 * This Function is to get bonding channels from primary channel. 1842 * 1843 */ 1844 uint8_t sap_get_bonding_channels(ptSapContext sapContext, uint8_t channel, 1845 uint8_t *channels, uint8_t size, 1846 ePhyChanBondState chanBondState) 1847 { 1848 tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 1849 tpAniSirGlobal pMac; 1850 uint8_t numChannel; 1851 1852 if (channels == NULL) 1853 return 0; 1854 1855 if (size < MAX_BONDED_CHANNELS) 1856 return 0; 1857 1858 if (NULL != hHal) { 1859 pMac = PMAC_STRUCT(hHal); 1860 } else 1861 return 0; 1862 1863 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 1864 FL("cbmode: %d, channel: %d"), chanBondState, channel); 1865 1866 switch (chanBondState) { 1867 case PHY_SINGLE_CHANNEL_CENTERED: 1868 numChannel = 1; 1869 channels[0] = channel; 1870 break; 1871 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 1872 numChannel = 2; 1873 channels[0] = channel - 4; 1874 channels[1] = channel; 1875 break; 1876 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 1877 numChannel = 2; 1878 channels[0] = channel; 1879 channels[1] = channel + 4; 1880 break; 1881 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: 1882 numChannel = 4; 1883 channels[0] = channel; 1884 channels[1] = channel + 4; 1885 channels[2] = channel + 8; 1886 channels[3] = channel + 12; 1887 break; 1888 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: 1889 numChannel = 4; 1890 channels[0] = channel - 4; 1891 channels[1] = channel; 1892 channels[2] = channel + 4; 1893 channels[3] = channel + 8; 1894 break; 1895 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: 1896 numChannel = 4; 1897 channels[0] = channel - 8; 1898 channels[1] = channel - 4; 1899 channels[2] = channel; 1900 channels[3] = channel + 4; 1901 break; 1902 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: 1903 numChannel = 4; 1904 channels[0] = channel - 12; 1905 channels[1] = channel - 8; 1906 channels[2] = channel - 4; 1907 channels[3] = channel; 1908 break; 1909 default: 1910 numChannel = 1; 1911 channels[0] = channel; 1912 break; 1913 } 1914 1915 return numChannel; 1916 } 1917 1918 /** 1919 * sap_dfs_check_if_channel_avaialable() - Check if a channel is out of NOL 1920 * @nol: Pointer to the Non-Occupancy List. 1921 * 1922 * This function Checks if a given channel is available or 1923 * usable or unavailable based on the time lapse since the 1924 * last radar time stamp. 1925 * 1926 * Return: true if channel available or usable, false if unavailable. 1927 */ 1928 static bool sap_dfs_check_if_channel_avaialable(tSapDfsNolInfo *nol) 1929 { 1930 uint64_t time_since_last_radar, time_when_radar_found, current_time = 0; 1931 uint64_t max_jiffies; 1932 1933 if ((nol->radar_status_flag == eSAP_DFS_CHANNEL_USABLE) || 1934 (nol->radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE)) { 1935 /* 1936 * Allow SAP operation on this channel 1937 * either the DFS channel has not been used 1938 * for SAP operation or it is available for 1939 * SAP operation since it is past 1940 * Non-Occupancy-Period so, return false. 1941 */ 1942 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1943 FL("Chan=%d not in NOL,CHAN AVAILABLE"), 1944 nol->dfs_channel_number); 1945 return true; 1946 } else if (nol->radar_status_flag == eSAP_DFS_CHANNEL_UNAVAILABLE) { 1947 /* 1948 * If a DFS Channel is UNAVAILABLE then 1949 * check to see if it is past 1950 * Non-occupancy-period 1951 * of 30 minutes. If it is past 30 mins then 1952 * mark the channel as AVAILABLE and return 1953 * false as the channel is not anymore in 1954 * NON-Occupancy-Period. 1955 */ 1956 time_when_radar_found = nol->radar_found_timestamp; 1957 current_time = cds_get_monotonic_boottime(); 1958 if (current_time < time_when_radar_found) { 1959 /* cds_get_monotonic_boottime() can overflow. 1960 * Jiffies is initialized such that 32 bit jiffies 1961 * value wrap 5 minutes after boot so jiffies wrap bugs 1962 * show up earlier 1963 */ 1964 max_jiffies = (uint64_t)UINT_MAX * 1000; 1965 time_since_last_radar = (max_jiffies - 1966 time_when_radar_found) + (current_time); 1967 } else { 1968 time_since_last_radar = current_time - 1969 time_when_radar_found; 1970 } 1971 if (time_since_last_radar >= SAP_DFS_NON_OCCUPANCY_PERIOD) { 1972 nol->radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE; 1973 nol->radar_found_timestamp = 0; 1974 1975 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1976 FL("Chan=%d not in NOL, Channel AVAILABLE"), 1977 nol->dfs_channel_number); 1978 return true; 1979 } else { 1980 /* 1981 * Channel is not still available for 1982 * SAP operation so return true; As the 1983 * Channel is still in 1984 * Non-occupancy-Period. 1985 */ 1986 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1987 FL("Chan=%d in NOL, Channel UNAVAILBLE"), 1988 nol->dfs_channel_number); 1989 return false; 1990 } 1991 } else { 1992 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1993 FL("Invalid Radar Status Flag")); 1994 } 1995 return true; 1996 } 1997 1998 /** 1999 * sap_dfs_is_channel_in_nol_list() - given bonded channel is available 2000 * @sap_context: Handle to SAP context. 2001 * @channel_number: Channel on which availability should be checked. 2002 * @chan_bondState: The channel bonding mode of the passed channel. 2003 * 2004 * This function Checks if a given bonded channel is available or 2005 * usable for DFS operation. 2006 * 2007 * Return: false if channel is available, true if channel is in NOL. 2008 */ 2009 bool 2010 sap_dfs_is_channel_in_nol_list(ptSapContext sap_context, 2011 uint8_t channel_number, 2012 ePhyChanBondState chan_bondState) 2013 { 2014 int i, j; 2015 tHalHandle h_hal = CDS_GET_HAL_CB(sap_context->p_cds_gctx); 2016 tpAniSirGlobal mac_ctx; 2017 uint8_t channels[MAX_BONDED_CHANNELS]; 2018 uint8_t num_channels; 2019 tSapDfsNolInfo *nol; 2020 tSapDfsInfo *dfs_info; 2021 bool channel_available; 2022 2023 if (NULL == h_hal) { 2024 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2025 FL("invalid h_hal")); 2026 return false; 2027 } else { 2028 mac_ctx = PMAC_STRUCT(h_hal); 2029 } 2030 2031 dfs_info = &mac_ctx->sap.SapDfsInfo; 2032 if ((dfs_info->numCurrentRegDomainDfsChannels == 0) || 2033 (dfs_info->numCurrentRegDomainDfsChannels > 2034 NUM_5GHZ_CHANNELS)) { 2035 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 2036 FL("invalid dfs channel count %d"), 2037 dfs_info->numCurrentRegDomainDfsChannels); 2038 return false; 2039 } 2040 2041 /* get the bonded channels */ 2042 num_channels = sap_get_bonding_channels(sap_context, channel_number, 2043 channels, MAX_BONDED_CHANNELS, chan_bondState); 2044 2045 /* check for NOL, first on will break the loop */ 2046 for (j = 0; j < num_channels; j++) { 2047 for (i = 0; i < dfs_info->numCurrentRegDomainDfsChannels; i++) { 2048 nol = &dfs_info->sapDfsChannelNolList[i]; 2049 if (nol->dfs_channel_number != channels[j]) 2050 continue; 2051 2052 channel_available = 2053 sap_dfs_check_if_channel_avaialable(nol); 2054 2055 if (channel_available == false) 2056 break; 2057 2058 } /* loop for dfs channels */ 2059 2060 if (i < dfs_info->numCurrentRegDomainDfsChannels) 2061 break; 2062 2063 } /* loop for bonded channels */ 2064 2065 /* 2066 * if any of the channel is not available, mark all available channels 2067 * as unavailable with same time stamp. 2068 */ 2069 if (j < num_channels && 2070 i < dfs_info->numCurrentRegDomainDfsChannels) { 2071 if (num_channels > MAX_BONDED_CHANNELS) { 2072 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 2073 FL("num_channel>MAX_BONDED_CHANNEL, reset")); 2074 num_channels = MAX_BONDED_CHANNELS; 2075 } 2076 nol = &dfs_info->sapDfsChannelNolList[i]; 2077 sap_mark_dfs_channels(sap_context, channels, num_channels, 2078 nol->radar_found_timestamp); 2079 2080 /* set DFS-NOL back to keep it update-to-date in CNSS */ 2081 sap_signal_hdd_event(sap_context, NULL, eSAP_DFS_NOL_SET, 2082 (void *) eSAP_STATUS_SUCCESS); 2083 2084 return true; 2085 } 2086 2087 return false; 2088 } 2089 2090 /** 2091 * sap_goto_channel_sel - Function for initiating scan request for SME 2092 * @sap_context: Sap Context value. 2093 * @sap_event: State machine event 2094 * @sap_do_acs_pre_start_bss: true, if ACS scan is issued pre start BSS 2095 * false, if ACS scan is issued post start BSS. 2096 * @check_for_connection_update: true, check and wait for connection update 2097 * false, do not perform connection update 2098 * 2099 * Initiates sme scan for ACS to pick a channel. 2100 * 2101 * Return: The QDF_STATUS code associated with performing the operation. 2102 */ 2103 QDF_STATUS sap_goto_channel_sel(ptSapContext sap_context, 2104 ptWLAN_SAPEvent sap_event, 2105 bool sap_do_acs_pre_start_bss, 2106 bool check_for_connection_update) 2107 { 2108 2109 /* Initiate a SCAN request */ 2110 QDF_STATUS qdf_ret_status; 2111 /* To be initialised if scan is required */ 2112 tCsrScanRequest scan_request; 2113 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 2114 tpAniSirGlobal mac_ctx; 2115 2116 #ifdef SOFTAP_CHANNEL_RANGE 2117 uint8_t *channel_list = NULL; 2118 uint8_t num_of_channels = 0; 2119 #endif 2120 tHalHandle h_hal; 2121 uint8_t con_ch; 2122 2123 h_hal = cds_get_context(QDF_MODULE_ID_SME); 2124 if (NULL == h_hal) { 2125 /* we have a serious problem */ 2126 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 2127 FL("invalid h_hal")); 2128 return QDF_STATUS_E_FAULT; 2129 } 2130 2131 mac_ctx = PMAC_STRUCT(h_hal); 2132 if (NULL == mac_ctx) { 2133 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2134 FL("Invalid MAC context")); 2135 return QDF_STATUS_E_FAILURE; 2136 } 2137 2138 if (cds_concurrent_beaconing_sessions_running()) { 2139 con_ch = 2140 sme_get_concurrent_operation_channel(h_hal); 2141 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 2142 if (con_ch && sap_context->channel == AUTO_CHANNEL_SELECT) { 2143 sap_context->dfs_ch_disable = true; 2144 } else if (con_ch && sap_context->channel != con_ch && 2145 CDS_IS_DFS_CH(sap_context->channel)) { 2146 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 2147 FL("MCC DFS not supported in AP_AP Mode")); 2148 return QDF_STATUS_E_ABORTED; 2149 } 2150 #endif 2151 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 2152 if (sap_context->cc_switch_mode != 2153 QDF_MCC_TO_SCC_SWITCH_DISABLE) { 2154 con_ch = sme_check_concurrent_channel_overlap(h_hal, 2155 sap_context->channel, 2156 sap_context->csr_roamProfile.phyMode, 2157 sap_context->cc_switch_mode); 2158 if (con_ch) { 2159 QDF_TRACE(QDF_MODULE_ID_SAP, 2160 QDF_TRACE_LEVEL_ERROR, 2161 "%s: Override ch %d to %d due to CC Intf", 2162 __func__, sap_context->channel, con_ch); 2163 sap_context->channel = con_ch; 2164 cds_set_channel_params(sap_context->channel, 0, 2165 &sap_context->ch_params); 2166 } 2167 } 2168 #endif 2169 } 2170 2171 if (cds_get_concurrency_mode() == (QDF_STA_MASK | QDF_SAP_MASK)) { 2172 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 2173 if (sap_context->channel == AUTO_CHANNEL_SELECT) 2174 sap_context->dfs_ch_disable = true; 2175 else if (CDS_IS_DFS_CH(sap_context->channel)) { 2176 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 2177 FL("DFS not supported in STA_AP Mode")); 2178 return QDF_STATUS_E_ABORTED; 2179 } 2180 #endif 2181 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 2182 if (sap_context->cc_switch_mode != 2183 QDF_MCC_TO_SCC_SWITCH_DISABLE) { 2184 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2185 FL("check for overlap: chan:%d mode:%d"), 2186 sap_context->channel, 2187 sap_context->csr_roamProfile.phyMode); 2188 con_ch = sme_check_concurrent_channel_overlap(h_hal, 2189 sap_context->channel, 2190 sap_context->csr_roamProfile.phyMode, 2191 sap_context->cc_switch_mode); 2192 if (con_ch && !CDS_IS_DFS_CH(con_ch)) { 2193 QDF_TRACE(QDF_MODULE_ID_SAP, 2194 QDF_TRACE_LEVEL_ERROR, 2195 "%s: Override ch %d to %d due to CC Intf", 2196 __func__, sap_context->channel, con_ch); 2197 sap_context->channel = con_ch; 2198 cds_set_channel_params(sap_context->channel, 0, 2199 &sap_context->ch_params); 2200 } 2201 } 2202 #endif 2203 } 2204 2205 if (sap_context->channel == AUTO_CHANNEL_SELECT) { 2206 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2207 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2208 FL("%s skip_acs_status = %d "), __func__, 2209 sap_context->acs_cfg->skip_scan_status); 2210 if (sap_context->acs_cfg->skip_scan_status != 2211 eSAP_SKIP_ACS_SCAN) { 2212 #endif 2213 qdf_mem_zero(&scan_request, sizeof(scan_request)); 2214 2215 /* 2216 * Set scanType to Active scan. FW takes care of using passive 2217 * scan for DFS and active for non DFS channels. 2218 */ 2219 scan_request.scanType = eSIR_ACTIVE_SCAN; 2220 2221 /* Set min and max channel time to zero */ 2222 scan_request.minChnTime = 0; 2223 scan_request.maxChnTime = 0; 2224 2225 /* Set BSSType to default type */ 2226 scan_request.BSSType = eCSR_BSS_TYPE_ANY; 2227 2228 #ifndef SOFTAP_CHANNEL_RANGE 2229 /*Scan all the channels */ 2230 scan_request.ChannelInfo.num_of_channels = 0; 2231 2232 scan_request.ChannelInfo.ChannelList = NULL; 2233 2234 scan_request.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; 2235 /* eCSR_SCAN_REQUEST_11D_SCAN; */ 2236 2237 #else 2238 2239 sap_get_channel_list(sap_context, &channel_list, 2240 &num_of_channels); 2241 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2242 if (num_of_channels != 0) { 2243 #endif 2244 /*Scan the channels in the list */ 2245 scan_request.ChannelInfo.numOfChannels = 2246 num_of_channels; 2247 2248 scan_request.ChannelInfo.ChannelList = 2249 channel_list; 2250 2251 scan_request.requestType = 2252 eCSR_SCAN_SOFTAP_CHANNEL_RANGE; 2253 2254 sap_context->channelList = channel_list; 2255 2256 #endif 2257 /* Set requestType to Full scan */ 2258 2259 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2260 FL("calling sme_scan_request")); 2261 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2262 if (sap_context->acs_cfg->skip_scan_status == 2263 eSAP_DO_NEW_ACS_SCAN) 2264 #endif 2265 sme_scan_flush_result(h_hal); 2266 if (true == sap_do_acs_pre_start_bss) { 2267 /* 2268 * when ID == 0 11D scan/active scan with callback, 2269 * min-maxChntime set in csrScanRequest()? 2270 * csrScanCompleteCallback callback 2271 * pContext scan_request_id filled up 2272 */ 2273 qdf_ret_status = sme_scan_request(h_hal, 2274 sap_context->sessionId, 2275 &scan_request, 2276 &wlansap_pre_start_bss_acs_scan_callback, 2277 sap_context); 2278 } else { 2279 /* 2280 * when ID == 0 11D scan/active scan with callback, 2281 * min-maxChntime set in csrScanRequest()? 2282 * csrScanCompleteCallback callback, 2283 * pContext scan_request_id filled up 2284 */ 2285 qdf_ret_status = sme_scan_request(h_hal, 2286 sap_context->sessionId, 2287 &scan_request, 2288 &wlansap_scan_callback, 2289 sap_context); 2290 } 2291 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 2292 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2293 FL("sme_scan_request fail %d!!!"), 2294 qdf_ret_status); 2295 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2296 FL("SAP Configuring default channel, Ch=%d"), 2297 sap_context->channel); 2298 /* In case of error, switch to default channel */ 2299 sap_context->channel = SAP_DEFAULT_24GHZ_CHANNEL; 2300 2301 #ifdef SOFTAP_CHANNEL_RANGE 2302 if (sap_context->channelList != NULL) { 2303 sap_context->channel = 2304 sap_context->channelList[0]; 2305 qdf_mem_free(sap_context-> 2306 channelList); 2307 sap_context->channelList = NULL; 2308 } 2309 #endif 2310 if (true == sap_do_acs_pre_start_bss) { 2311 /* 2312 * In case of ACS req before start Bss, 2313 * return failure so that the calling 2314 * fucntion can use the default channel. 2315 */ 2316 return QDF_STATUS_E_FAILURE; 2317 } else { 2318 /* Fill in the event structure */ 2319 sap_event_init(sap_event); 2320 /* Handle event */ 2321 qdf_status = sap_fsm(sap_context, sap_event); 2322 } 2323 } else { 2324 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2325 FL("return sme_ScanReq, scanID=%d, Ch=%d"), 2326 scan_request.scan_id, sap_context->channel); 2327 } 2328 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2329 } 2330 } else { 2331 sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN; 2332 } 2333 2334 if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) { 2335 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2336 FL("## %s SKIPPED ACS SCAN"), __func__); 2337 wlansap_scan_callback(h_hal, sap_context, 2338 sap_context->sessionId, 0, eCSR_SCAN_SUCCESS); 2339 } 2340 #endif 2341 } else { 2342 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2343 FL("for configured channel, Ch= %d"), 2344 sap_context->channel); 2345 2346 if (check_for_connection_update) { 2347 /* This wait happens in the hostapd context. The event 2348 * is set in the MC thread context. 2349 */ 2350 qdf_status = cds_update_and_wait_for_connection_update( 2351 sap_context->sessionId, 2352 sap_context->channel, 2353 SIR_UPDATE_REASON_START_AP); 2354 if (QDF_IS_STATUS_ERROR(qdf_status)) 2355 return qdf_status; 2356 } 2357 2358 if (sap_do_acs_pre_start_bss == true) { 2359 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2360 FL("ACS end due to Ch override. Sel Ch = %d"), 2361 sap_context->channel); 2362 sap_context->acs_cfg->pri_ch = sap_context->channel; 2363 sap_context->acs_cfg->ch_width = 2364 sap_context->ch_width_orig; 2365 sap_config_acs_result(h_hal, sap_context, 0); 2366 return QDF_STATUS_E_CANCELED; 2367 } else { 2368 /* 2369 * Fill in the event structure 2370 * Eventhough scan was not done, 2371 * means a user set channel was chosen 2372 */ 2373 sap_event_init(sap_event); 2374 /* Handle event */ 2375 qdf_status = sap_fsm(sap_context, sap_event); 2376 } 2377 } 2378 2379 /* 2380 * If scan failed, get default channel and advance state 2381 * machine as success with default channel 2382 * 2383 * Have to wait for the call back to be called to get the 2384 * channel cannot advance state machine here as said above 2385 */ 2386 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2387 FL("before exiting sap_goto_channel_sel channel=%d"), 2388 sap_context->channel); 2389 2390 return QDF_STATUS_SUCCESS; 2391 } 2392 2393 /** 2394 * sap_open_session() - Opens a SAP session 2395 * @hHal: Hal handle 2396 * @sapContext: Sap Context value 2397 * @session_id: Pointer to the session id 2398 * 2399 * Function for opening SME and SAP sessions when system is in SoftAP role 2400 * 2401 * Return: QDF_STATUS 2402 */ 2403 2404 #define SAP_OPEN_SESSION_TIMEOUT 2000 2405 QDF_STATUS sap_open_session(tHalHandle hHal, ptSapContext sapContext, 2406 uint32_t *session_id) 2407 { 2408 uint32_t type, subType; 2409 QDF_STATUS qdf_ret_status; 2410 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2411 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 2412 2413 if (sapContext->csr_roamProfile.csrPersona == QDF_P2P_GO_MODE) 2414 status = cds_get_vdev_types(QDF_P2P_GO_MODE, &type, &subType); 2415 else 2416 status = cds_get_vdev_types(QDF_SAP_MODE, &type, &subType); 2417 2418 if (QDF_STATUS_SUCCESS != status) { 2419 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 2420 "failed to get vdev type"); 2421 return QDF_STATUS_E_FAILURE; 2422 } 2423 2424 qdf_event_reset(&sapContext->sap_session_opened_evt); 2425 /* Open SME Session for Softap */ 2426 qdf_ret_status = sme_open_session(hHal, 2427 &wlansap_roam_callback, 2428 sapContext, 2429 sapContext->self_mac_addr, 2430 &sapContext->sessionId, type, subType); 2431 2432 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 2433 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2434 "Error: In %s calling sme_roam_connect status = %d", 2435 __func__, qdf_ret_status); 2436 2437 return QDF_STATUS_E_FAILURE; 2438 } 2439 2440 status = qdf_wait_single_event(&sapContext->sap_session_opened_evt, 2441 SAP_OPEN_SESSION_TIMEOUT); 2442 2443 if (!QDF_IS_STATUS_SUCCESS(status)) { 2444 cds_err("wait for sap open session event timed out"); 2445 return QDF_STATUS_E_FAILURE; 2446 } 2447 2448 pMac->sap.sapCtxList[sapContext->sessionId].sessionID = 2449 sapContext->sessionId; 2450 pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = sapContext; 2451 pMac->sap.sapCtxList[sapContext->sessionId].sapPersona = 2452 sapContext->csr_roamProfile.csrPersona; 2453 *session_id = sapContext->sessionId; 2454 sapContext->isSapSessionOpen = eSAP_TRUE; 2455 sapContext->is_pre_cac_on = false; 2456 sapContext->pre_cac_complete = false; 2457 sapContext->chan_before_pre_cac = 0; 2458 return QDF_STATUS_SUCCESS; 2459 } 2460 2461 /*========================================================================== 2462 FUNCTION sapGotoStarting 2463 2464 DESCRIPTION 2465 Function for initiating start bss request for SME 2466 2467 DEPENDENCIES 2468 NA. 2469 2470 PARAMETERS 2471 2472 IN 2473 sapContext : Sap Context value 2474 sapEvent : State machine event 2475 bssType : Type of bss to start, INRA AP 2476 status : Return the SAP status here 2477 2478 RETURN VALUE 2479 The QDF_STATUS code associated with performing the operation 2480 2481 QDF_STATUS_SUCCESS: Success 2482 2483 SIDE EFFECTS 2484 ============================================================================*/ 2485 QDF_STATUS sap_goto_starting(ptSapContext sapContext, ptWLAN_SAPEvent sapEvent, 2486 eCsrRoamBssType bssType) 2487 { 2488 /* tHalHandle */ 2489 tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 2490 QDF_STATUS qdf_ret_status; 2491 2492 /*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/ 2493 char key_material[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 2494 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, }; 2495 sapContext->key_type = 0x05; 2496 sapContext->key_length = 32; 2497 /* Need a key size define */ 2498 qdf_mem_copy(sapContext->key_material, key_material, 2499 sizeof(key_material)); 2500 2501 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s", 2502 __func__); 2503 2504 if (NULL == hHal) { 2505 /* we have a serious problem */ 2506 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 2507 "In %s, invalid hHal", __func__); 2508 return QDF_STATUS_E_FAULT; 2509 } 2510 2511 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, "%s: session: %d", 2512 __func__, sapContext->sessionId); 2513 2514 qdf_ret_status = sme_roam_connect(hHal, sapContext->sessionId, 2515 &sapContext->csr_roamProfile, 2516 &sapContext->csr_roamId); 2517 if (QDF_STATUS_SUCCESS != qdf_ret_status) 2518 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2519 "%s: Failed to issue sme_roam_connect", __func__); 2520 2521 return qdf_ret_status; 2522 } /* sapGotoStarting */ 2523 2524 /*========================================================================== 2525 FUNCTION sapGotoDisconnecting 2526 2527 DESCRIPTION 2528 Processing of SAP FSM Disconnecting state 2529 2530 DEPENDENCIES 2531 NA. 2532 2533 PARAMETERS 2534 2535 IN 2536 sapContext : Sap Context value 2537 status : Return the SAP status here 2538 2539 RETURN VALUE 2540 The QDF_STATUS code associated with performing the operation 2541 2542 QDF_STATUS_SUCCESS: Success 2543 2544 SIDE EFFECTS 2545 ============================================================================*/ 2546 QDF_STATUS sap_goto_disconnecting(ptSapContext sapContext) 2547 { 2548 QDF_STATUS qdf_ret_status; 2549 tHalHandle hHal; 2550 2551 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 2552 if (NULL == hHal) { 2553 /* we have a serious problem */ 2554 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2555 "In %s, invalid hHal", __func__); 2556 return QDF_STATUS_E_FAULT; 2557 } 2558 2559 sap_free_roam_profile(&sapContext->csr_roamProfile); 2560 qdf_ret_status = sme_roam_stop_bss(hHal, sapContext->sessionId); 2561 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 2562 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2563 "Error: In %s calling sme_roam_stop_bss status = %d", 2564 __func__, qdf_ret_status); 2565 return QDF_STATUS_E_FAILURE; 2566 } 2567 2568 return QDF_STATUS_SUCCESS; 2569 } 2570 2571 static QDF_STATUS sap_roam_session_close_callback(void *pContext) 2572 { 2573 ptSapContext sapContext = (ptSapContext) pContext; 2574 return sap_signal_hdd_event(sapContext, NULL, 2575 eSAP_STOP_BSS_EVENT, 2576 (void *) eSAP_STATUS_SUCCESS); 2577 } 2578 2579 /*========================================================================== 2580 FUNCTION sapGotoDisconnected 2581 2582 DESCRIPTION 2583 Function for setting the SAP FSM to Disconnection state 2584 2585 DEPENDENCIES 2586 NA. 2587 2588 PARAMETERS 2589 2590 IN 2591 sapContext : Sap Context value 2592 sapEvent : State machine event 2593 status : Return the SAP status here 2594 2595 RETURN VALUE 2596 The QDF_STATUS code associated with performing the operation 2597 2598 QDF_STATUS_SUCCESS: Success 2599 2600 SIDE EFFECTS 2601 ============================================================================*/ 2602 QDF_STATUS sap_goto_disconnected(ptSapContext sapContext) 2603 { 2604 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2605 tWLAN_SAPEvent sapEvent; 2606 /* Processing has to be coded */ 2607 /* Clean up stations from TL etc as AP BSS is shut down then set event */ 2608 sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS; /* hardcoded */ 2609 sapEvent.params = 0; 2610 sapEvent.u1 = 0; 2611 sapEvent.u2 = 0; 2612 /* Handle event */ 2613 qdf_status = sap_fsm(sapContext, &sapEvent); 2614 2615 return qdf_status; 2616 } 2617 2618 /** 2619 * sap_signal_hdd_event() - send event notification 2620 * @sap_ctx: Sap Context 2621 * @csr_roaminfo: Pointer to CSR roam information 2622 * @sap_hddevent: SAP HDD event 2623 * @context: to pass the element for future support 2624 * 2625 * Function for HDD to send the event notification using callback 2626 * 2627 * Return: QDF_STATUS 2628 */ 2629 QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx, 2630 tCsrRoamInfo *csr_roaminfo, eSapHddEvent sap_hddevent, 2631 void *context) 2632 { 2633 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 2634 tSap_Event sap_ap_event; /* This now encodes ALL event types */ 2635 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 2636 tpAniSirGlobal mac_ctx; 2637 tSirSmeChanInfo *chaninfo; 2638 tSap_StationAssocIndication *assoc_ind; 2639 tSap_StartBssCompleteEvent *bss_complete; 2640 struct sap_ch_selected_s *acs_selected; 2641 tSap_StationAssocReassocCompleteEvent *reassoc_complete; 2642 tSap_StationDisassocCompleteEvent *disassoc_comp; 2643 tSap_StationSetKeyCompleteEvent *key_complete; 2644 tSap_StationMICFailureEvent *mic_failure; 2645 2646 /* Format the Start BSS Complete event to return... */ 2647 if (NULL == sap_ctx->pfnSapEventCallback) { 2648 QDF_ASSERT(0); 2649 return QDF_STATUS_E_FAILURE; 2650 } 2651 if (NULL == hal) { 2652 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2653 FL("Invalid hal")); 2654 return QDF_STATUS_E_FAILURE; 2655 } 2656 mac_ctx = PMAC_STRUCT(hal); 2657 if (NULL == mac_ctx) { 2658 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2659 FL("Invalid MAC context")); 2660 return QDF_STATUS_E_FAILURE; 2661 } 2662 2663 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2664 FL("SAP event callback event = %s"), 2665 sap_hdd_event_to_string(sap_hddevent)); 2666 2667 switch (sap_hddevent) { 2668 case eSAP_STA_ASSOC_IND: 2669 /* TODO - Indicate the assoc request indication to OS */ 2670 sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_IND; 2671 assoc_ind = &sap_ap_event.sapevt.sapAssocIndication; 2672 2673 qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac); 2674 assoc_ind->staId = csr_roaminfo->staId; 2675 assoc_ind->status = 0; 2676 /* Required for indicating the frames to upper layer */ 2677 assoc_ind->beaconLength = csr_roaminfo->beaconLength; 2678 assoc_ind->beaconPtr = csr_roaminfo->beaconPtr; 2679 assoc_ind->assocReqLength = csr_roaminfo->assocReqLength; 2680 assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr; 2681 assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta; 2682 if (csr_roaminfo->u.pConnectedProfile != NULL) { 2683 assoc_ind->negotiatedAuthType = 2684 csr_roaminfo->u.pConnectedProfile->AuthType; 2685 assoc_ind->negotiatedUCEncryptionType = 2686 csr_roaminfo->u.pConnectedProfile->EncryptionType; 2687 assoc_ind->negotiatedMCEncryptionType = 2688 csr_roaminfo->u.pConnectedProfile->mcEncryptionType; 2689 assoc_ind->fAuthRequired = csr_roaminfo->fAuthRequired; 2690 } 2691 break; 2692 case eSAP_START_BSS_EVENT: 2693 sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT; 2694 bss_complete = &sap_ap_event.sapevt.sapStartBssCompleteEvent; 2695 2696 bss_complete->status = (eSapStatus) context; 2697 if (csr_roaminfo != NULL) 2698 bss_complete->staId = csr_roaminfo->staId; 2699 else 2700 bss_complete->staId = 0; 2701 2702 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2703 FL("(eSAP_START_BSS_EVENT): staId = %d"), 2704 bss_complete->staId); 2705 2706 bss_complete->operatingChannel = (uint8_t) sap_ctx->channel; 2707 bss_complete->sessionId = sap_ctx->sessionId; 2708 break; 2709 case eSAP_DFS_CAC_START: 2710 case eSAP_DFS_CAC_INTERRUPTED: 2711 case eSAP_DFS_CAC_END: 2712 case eSAP_DFS_PRE_CAC_END: 2713 case eSAP_DFS_RADAR_DETECT: 2714 case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC: 2715 case eSAP_DFS_NO_AVAILABLE_CHANNEL: 2716 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2717 case eSAP_ACS_SCAN_SUCCESS_EVENT: 2718 #endif 2719 sap_ap_event.sapHddEventCode = sap_hddevent; 2720 sap_ap_event.sapevt.sapStopBssCompleteEvent.status = 2721 (eSapStatus) context; 2722 break; 2723 2724 case eSAP_ACS_CHANNEL_SELECTED: 2725 sap_ap_event.sapHddEventCode = sap_hddevent; 2726 acs_selected = &sap_ap_event.sapevt.sap_ch_selected; 2727 if (eSAP_STATUS_SUCCESS == (eSapStatus)context) { 2728 acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; 2729 acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch; 2730 acs_selected->ch_width = sap_ctx->acs_cfg->ch_width; 2731 acs_selected->vht_seg0_center_ch = 2732 sap_ctx->acs_cfg->vht_seg0_center_ch; 2733 acs_selected->vht_seg1_center_ch = 2734 sap_ctx->acs_cfg->vht_seg1_center_ch; 2735 } else if (eSAP_STATUS_FAILURE == (eSapStatus)context) { 2736 acs_selected->pri_ch = 0; 2737 } 2738 break; 2739 2740 case eSAP_STOP_BSS_EVENT: 2741 sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT; 2742 sap_ap_event.sapevt.sapStopBssCompleteEvent.status = 2743 (eSapStatus) context; 2744 break; 2745 2746 case eSAP_STA_ASSOC_EVENT: 2747 case eSAP_STA_REASSOC_EVENT: 2748 reassoc_complete = 2749 &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent; 2750 2751 if (csr_roaminfo->fReassocReq) 2752 sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT; 2753 else 2754 sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT; 2755 2756 qdf_copy_macaddr(&reassoc_complete->staMac, 2757 &csr_roaminfo->peerMac); 2758 reassoc_complete->staId = csr_roaminfo->staId; 2759 reassoc_complete->statusCode = csr_roaminfo->statusCode; 2760 reassoc_complete->iesLen = csr_roaminfo->rsnIELen; 2761 qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE, 2762 csr_roaminfo->rsnIELen); 2763 2764 #ifdef FEATURE_WLAN_WAPI 2765 if (csr_roaminfo->wapiIELen) { 2766 uint8_t len = reassoc_complete->iesLen; 2767 reassoc_complete->iesLen += csr_roaminfo->wapiIELen; 2768 qdf_mem_copy(&reassoc_complete->ies[len], 2769 csr_roaminfo->pwapiIE, 2770 csr_roaminfo->wapiIELen); 2771 } 2772 #endif 2773 if (csr_roaminfo->addIELen) { 2774 uint8_t len = reassoc_complete->iesLen; 2775 reassoc_complete->iesLen += csr_roaminfo->addIELen; 2776 qdf_mem_copy(&reassoc_complete->ies[len], 2777 csr_roaminfo->paddIE, 2778 csr_roaminfo->addIELen); 2779 } 2780 2781 /* also fill up the channel info from the csr_roamInfo */ 2782 chaninfo = &reassoc_complete->chan_info; 2783 2784 chaninfo->chan_id = csr_roaminfo->chan_info.chan_id; 2785 chaninfo->mhz = csr_roaminfo->chan_info.mhz; 2786 chaninfo->info = csr_roaminfo->chan_info.info; 2787 chaninfo->band_center_freq1 = 2788 csr_roaminfo->chan_info.band_center_freq1; 2789 chaninfo->band_center_freq2 = 2790 csr_roaminfo->chan_info.band_center_freq2; 2791 chaninfo->reg_info_1 = 2792 csr_roaminfo->chan_info.reg_info_1; 2793 chaninfo->reg_info_2 = 2794 csr_roaminfo->chan_info.reg_info_2; 2795 chaninfo->nss = csr_roaminfo->chan_info.nss; 2796 chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags; 2797 2798 reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta; 2799 reassoc_complete->status = (eSapStatus) context; 2800 reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap; 2801 break; 2802 2803 case eSAP_STA_DISASSOC_EVENT: 2804 sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; 2805 disassoc_comp = 2806 &sap_ap_event.sapevt.sapStationDisassocCompleteEvent; 2807 2808 qdf_copy_macaddr(&disassoc_comp->staMac, 2809 &csr_roaminfo->peerMac); 2810 disassoc_comp->staId = csr_roaminfo->staId; 2811 if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED) 2812 disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC; 2813 else 2814 disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC; 2815 2816 disassoc_comp->statusCode = csr_roaminfo->statusCode; 2817 disassoc_comp->status = (eSapStatus) context; 2818 break; 2819 2820 case eSAP_STA_SET_KEY_EVENT: 2821 sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT; 2822 key_complete = 2823 &sap_ap_event.sapevt.sapStationSetKeyCompleteEvent; 2824 key_complete->status = (eSapStatus) context; 2825 qdf_copy_macaddr(&key_complete->peerMacAddr, 2826 &csr_roaminfo->peerMac); 2827 break; 2828 2829 case eSAP_STA_MIC_FAILURE_EVENT: 2830 sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT; 2831 mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent; 2832 2833 qdf_mem_copy(&mic_failure->srcMacAddr, 2834 csr_roaminfo->u.pMICFailureInfo->srcMacAddr, 2835 sizeof(tSirMacAddr)); 2836 qdf_mem_copy(&mic_failure->staMac.bytes, 2837 csr_roaminfo->u.pMICFailureInfo->taMacAddr, 2838 sizeof(tSirMacAddr)); 2839 qdf_mem_copy(&mic_failure->dstMacAddr.bytes, 2840 csr_roaminfo->u.pMICFailureInfo->dstMacAddr, 2841 sizeof(tSirMacAddr)); 2842 mic_failure->multicast = 2843 csr_roaminfo->u.pMICFailureInfo->multicast; 2844 mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1; 2845 mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId; 2846 qdf_mem_copy(mic_failure->TSC, 2847 csr_roaminfo->u.pMICFailureInfo->TSC, 2848 SIR_CIPHER_SEQ_CTR_SIZE); 2849 break; 2850 2851 case eSAP_ASSOC_STA_CALLBACK_EVENT: 2852 break; 2853 2854 case eSAP_WPS_PBC_PROBE_REQ_EVENT: 2855 sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT; 2856 2857 qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent. 2858 WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq, 2859 sizeof(tSirWPSPBCProbeReq)); 2860 break; 2861 2862 case eSAP_REMAIN_CHAN_READY: 2863 sap_ap_event.sapHddEventCode = eSAP_REMAIN_CHAN_READY; 2864 sap_ap_event.sapevt.sap_roc_ind.scan_id = 2865 sap_ctx->roc_ind_scan_id; 2866 break; 2867 case eSAP_SEND_ACTION_CNF: 2868 sap_ap_event.sapHddEventCode = eSAP_SEND_ACTION_CNF; 2869 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 2870 (eSapStatus) context; 2871 break; 2872 2873 case eSAP_DISCONNECT_ALL_P2P_CLIENT: 2874 sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT; 2875 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 2876 (eSapStatus) context; 2877 break; 2878 2879 case eSAP_MAC_TRIG_STOP_BSS_EVENT: 2880 sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT; 2881 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 2882 (eSapStatus) context; 2883 break; 2884 2885 case eSAP_UNKNOWN_STA_JOIN: 2886 sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN; 2887 qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin. 2888 macaddr.bytes, (void *) context, 2889 QDF_MAC_ADDR_SIZE); 2890 break; 2891 2892 case eSAP_MAX_ASSOC_EXCEEDED: 2893 sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED; 2894 qdf_copy_macaddr(&sap_ap_event.sapevt. 2895 sapMaxAssocExceeded.macaddr, 2896 &csr_roaminfo->peerMac); 2897 break; 2898 2899 case eSAP_CHANNEL_CHANGE_EVENT: 2900 /* 2901 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS 2902 * follows pri AP 2903 */ 2904 sap_ctx->acs_cfg->pri_ch = sap_ctx->channel; 2905 sap_ctx->acs_cfg->ch_width = 2906 sap_ctx->csr_roamProfile.ch_params.ch_width; 2907 sap_config_acs_result(hal, sap_ctx, 2908 sap_ctx->csr_roamProfile.ch_params.sec_ch_offset); 2909 2910 sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; 2911 2912 acs_selected = &sap_ap_event.sapevt.sap_ch_selected; 2913 acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; 2914 acs_selected->ht_sec_ch = 2915 sap_ctx->csr_roamProfile.ch_params.sec_ch_offset; 2916 acs_selected->ch_width = 2917 sap_ctx->csr_roamProfile.ch_params.ch_width; 2918 acs_selected->vht_seg0_center_ch = 2919 sap_ctx->csr_roamProfile.ch_params.center_freq_seg0; 2920 acs_selected->vht_seg1_center_ch = 2921 sap_ctx->csr_roamProfile.ch_params.center_freq_seg1; 2922 break; 2923 2924 case eSAP_DFS_NOL_GET: 2925 sap_ap_event.sapHddEventCode = eSAP_DFS_NOL_GET; 2926 sap_ap_event.sapevt.sapDfsNolInfo.sDfsList = 2927 NUM_5GHZ_CHANNELS * sizeof(tSapDfsNolInfo); 2928 sap_ap_event.sapevt.sapDfsNolInfo.pDfsList = (void *) 2929 (&mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList[0]); 2930 break; 2931 2932 case eSAP_DFS_NOL_SET: 2933 sap_ap_event.sapHddEventCode = eSAP_DFS_NOL_SET; 2934 sap_ap_event.sapevt.sapDfsNolInfo.sDfsList = 2935 mac_ctx->sap.SapDfsInfo.numCurrentRegDomainDfsChannels * 2936 sizeof(tSapDfsNolInfo); 2937 sap_ap_event.sapevt.sapDfsNolInfo.pDfsList = (void *) 2938 (&mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList[0]); 2939 break; 2940 case eSAP_ECSA_CHANGE_CHAN_IND: 2941 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2942 "In %s, SAP event callback event = %s", 2943 __func__, "eSAP_ECSA_CHANGE_CHAN_IND"); 2944 sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND; 2945 sap_ap_event.sapevt.sap_chan_cng_ind.new_chan = 2946 csr_roaminfo->target_channel; 2947 break; 2948 default: 2949 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2950 FL("SAP Unknown callback event = %d"), 2951 sap_hddevent); 2952 break; 2953 } 2954 qdf_status = (*sap_ctx->pfnSapEventCallback) 2955 (&sap_ap_event, sap_ctx->pUsrContext); 2956 2957 return qdf_status; 2958 2959 } 2960 2961 /*========================================================================== 2962 FUNCTION sap_find_valid_concurrent_session 2963 2964 DESCRIPTION 2965 This function will return sapcontext of any valid sap session. 2966 2967 PARAMETERS 2968 2969 IN 2970 hHal : HAL pointer 2971 2972 RETURN VALUE 2973 ptSapContext : valid sap context 2974 2975 SIDE EFFECTS 2976 NA 2977 ============================================================================*/ 2978 ptSapContext sap_find_valid_concurrent_session(tHalHandle hHal) 2979 { 2980 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 2981 uint8_t intf = 0; 2982 2983 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2984 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 2985 || 2986 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) && 2987 pMac->sap.sapCtxList[intf].pSapContext != NULL) { 2988 return pMac->sap.sapCtxList[intf].pSapContext; 2989 } 2990 } 2991 2992 return NULL; 2993 } 2994 2995 /** 2996 * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state 2997 * @handle: Global MAC handle 2998 * 2999 * Finds and gets the context of a SAP session in CAC wait state. 3000 * 3001 * Return: Valid SAP context on success, else NULL 3002 */ 3003 ptSapContext sap_find_cac_wait_session(tHalHandle handle) 3004 { 3005 tpAniSirGlobal mac = PMAC_STRUCT(handle); 3006 uint8_t i = 0; 3007 ptSapContext sapContext; 3008 3009 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3010 "%s", __func__); 3011 3012 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 3013 sapContext = (ptSapContext) mac->sap.sapCtxList[i].pSapContext; 3014 if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona) 3015 || 3016 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) && 3017 (sapContext) && 3018 (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) { 3019 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3020 "%s: found SAP in cac wait state", __func__); 3021 return sapContext; 3022 } 3023 if (sapContext) { 3024 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3025 "sapdfs: mode:%d intf:%d state:%d", 3026 mac->sap.sapCtxList[i].sapPersona, i, 3027 sapContext->sapsMachine); 3028 } 3029 } 3030 3031 return NULL; 3032 } 3033 3034 /*========================================================================== 3035 FUNCTION sap_close_session 3036 3037 DESCRIPTION 3038 This function will close all the sme sessions as well as zero-out the 3039 sap global structure 3040 3041 PARAMETERS 3042 3043 IN 3044 hHal : HAL pointer 3045 sapContext : Sap Context value 3046 callback : Roam Session close callback 3047 valid : Sap context is valid or no 3048 3049 RETURN VALUE 3050 The QDF_STATUS code associated with performing the operation 3051 QDF_STATUS_SUCCESS: Success 3052 3053 SIDE EFFECTS 3054 NA 3055 ============================================================================*/ 3056 QDF_STATUS sap_close_session(tHalHandle hHal, 3057 ptSapContext sapContext, 3058 csr_roamSessionCloseCallback callback, bool valid) 3059 { 3060 QDF_STATUS qdf_status; 3061 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3062 3063 if (false == valid) { 3064 qdf_status = sme_close_session(hHal, 3065 sapContext->sessionId, 3066 callback, NULL); 3067 } else { 3068 qdf_status = sme_close_session(hHal, 3069 sapContext->sessionId, 3070 callback, sapContext); 3071 } 3072 3073 sapContext->isCacStartNotified = false; 3074 sapContext->isCacEndNotified = false; 3075 pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = NULL; 3076 sapContext->isSapSessionOpen = false; 3077 sapContext->pre_cac_complete = false; 3078 sapContext->is_pre_cac_on = false; 3079 sapContext->chan_before_pre_cac = 0; 3080 3081 if (NULL == sap_find_valid_concurrent_session(hHal)) { 3082 /* If timer is running then stop the timer and destory it */ 3083 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3084 "sapdfs: no session are valid, so clearing dfs global structure"); 3085 /* 3086 * CAC timer will be initiated and started only when SAP starts 3087 * on DFS channel and it will be stopped and destroyed 3088 * immediately once the radar detected or timedout. So 3089 * as per design CAC timer should be destroyed after stop 3090 */ 3091 if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) { 3092 qdf_mc_timer_stop(&pMac->sap.SapDfsInfo. 3093 sap_dfs_cac_timer); 3094 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 3095 qdf_mc_timer_destroy( 3096 &pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 3097 } 3098 pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; 3099 sap_cac_reset_notify(hHal); 3100 qdf_mem_zero(&pMac->sap, sizeof(pMac->sap)); 3101 } 3102 3103 return qdf_status; 3104 } 3105 3106 /*========================================================================== 3107 FUNCTION sap_cac_reset_notify 3108 3109 DESCRIPTION Function will be called up on stop bss indication to clean up 3110 DFS global structure. 3111 3112 DEPENDENCIES PARAMETERS 3113 IN hHAL : HAL pointer 3114 3115 RETURN VALUE : void. 3116 3117 SIDE EFFECTS 3118 ============================================================================*/ 3119 void sap_cac_reset_notify(tHalHandle hHal) 3120 { 3121 uint8_t intf = 0; 3122 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3123 3124 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3125 ptSapContext pSapContext = 3126 (ptSapContext) pMac->sap.sapCtxList[intf].pSapContext; 3127 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3128 || 3129 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3130 && pMac->sap.sapCtxList[intf].pSapContext != NULL) { 3131 pSapContext->isCacStartNotified = false; 3132 pSapContext->isCacEndNotified = false; 3133 } 3134 } 3135 } 3136 3137 /*========================================================================== 3138 FUNCTION sap_cac_start_notify 3139 3140 DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event 3141 to HDD 3142 3143 DEPENDENCIES PARAMETERS 3144 IN hHAL : HAL pointer 3145 3146 RETURN VALUE : QDF_STATUS. 3147 3148 SIDE EFFECTS 3149 ============================================================================*/ 3150 QDF_STATUS sap_cac_start_notify(tHalHandle hHal) 3151 { 3152 uint8_t intf = 0; 3153 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3154 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3155 3156 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3157 ptSapContext pSapContext = 3158 (ptSapContext) pMac->sap.sapCtxList[intf].pSapContext; 3159 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3160 || 3161 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3162 && pMac->sap.sapCtxList[intf].pSapContext != NULL && 3163 (false == pSapContext->isCacStartNotified)) { 3164 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3165 "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%p]", 3166 pSapContext); 3167 3168 qdf_status = sap_signal_hdd_event(pSapContext, NULL, 3169 eSAP_DFS_CAC_START, 3170 (void *) 3171 eSAP_STATUS_SUCCESS); 3172 if (QDF_STATUS_SUCCESS != qdf_status) { 3173 QDF_TRACE(QDF_MODULE_ID_SAP, 3174 QDF_TRACE_LEVEL_ERROR, 3175 "In %s, failed setting isCacStartNotified on interface[%d]", 3176 __func__, intf); 3177 return qdf_status; 3178 } 3179 pSapContext->isCacStartNotified = true; 3180 } 3181 } 3182 return qdf_status; 3183 } 3184 3185 /** 3186 * wlansap_update_pre_cac_end() - Update pre cac end to upper layer 3187 * @sap_context: SAP context 3188 * @mac: Global MAC structure 3189 * @intf: Interface number 3190 * 3191 * Notifies pre cac end to upper layer 3192 * 3193 * Return: QDF_STATUS 3194 */ 3195 static QDF_STATUS wlansap_update_pre_cac_end(ptSapContext sap_context, 3196 tpAniSirGlobal mac, uint8_t intf) 3197 { 3198 QDF_STATUS qdf_status; 3199 3200 sap_context->isCacEndNotified = true; 3201 mac->sap.SapDfsInfo.sap_radar_found_status = false; 3202 sap_context->sapsMachine = eSAP_STARTED; 3203 3204 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3205 "In %s, pre cac end notify on %d: from state %s => %s", 3206 __func__, intf, "eSAP_DFS_CAC_WAIT", 3207 "eSAP_STARTED"); 3208 3209 qdf_status = sap_signal_hdd_event(sap_context, 3210 NULL, eSAP_DFS_PRE_CAC_END, 3211 (void *)eSAP_STATUS_SUCCESS); 3212 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3213 QDF_TRACE(QDF_MODULE_ID_SAP, 3214 QDF_TRACE_LEVEL_ERROR, 3215 "In %s, pre cac notify failed on intf %d", 3216 __func__, intf); 3217 return qdf_status; 3218 } 3219 3220 return QDF_STATUS_SUCCESS; 3221 } 3222 3223 /*========================================================================== 3224 FUNCTION sap_cac_end_notify 3225 3226 DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event 3227 to HDD 3228 3229 DEPENDENCIES PARAMETERS 3230 IN hHAL : HAL pointer 3231 3232 RETURN VALUE : QDF_STATUS. 3233 3234 SIDE EFFECTS 3235 ============================================================================*/ 3236 QDF_STATUS sap_cac_end_notify(tHalHandle hHal, tCsrRoamInfo *roamInfo) 3237 { 3238 uint8_t intf; 3239 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3240 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3241 3242 /* 3243 * eSAP_DFS_CHANNEL_CAC_END: 3244 * CAC Period elapsed and there was no radar 3245 * found so, SAP can continue beaconing. 3246 * sap_radar_found_status is set to 0 3247 */ 3248 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3249 ptSapContext pSapContext = 3250 (ptSapContext) pMac->sap.sapCtxList[intf].pSapContext; 3251 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3252 || 3253 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3254 && pMac->sap.sapCtxList[intf].pSapContext != NULL && 3255 (false == pSapContext->isCacEndNotified) && 3256 (pSapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) { 3257 pSapContext = pMac->sap.sapCtxList[intf].pSapContext; 3258 3259 /* If this is an end notification of a pre cac, the 3260 * SAP must not start beaconing and must delete the 3261 * temporary interface created for pre cac and switch 3262 * the original SAP to the pre CAC channel. 3263 */ 3264 if (pSapContext->is_pre_cac_on) { 3265 qdf_status = wlansap_update_pre_cac_end( 3266 pSapContext, pMac, intf); 3267 if (QDF_IS_STATUS_ERROR(qdf_status)) 3268 return qdf_status; 3269 /* pre CAC is not allowed with any concurrency. 3270 * So, we can break from here. 3271 */ 3272 break; 3273 } 3274 3275 qdf_status = sap_signal_hdd_event(pSapContext, NULL, 3276 eSAP_DFS_CAC_END, 3277 (void *) 3278 eSAP_STATUS_SUCCESS); 3279 if (QDF_STATUS_SUCCESS != qdf_status) { 3280 QDF_TRACE(QDF_MODULE_ID_SAP, 3281 QDF_TRACE_LEVEL_ERROR, 3282 "In %s, failed setting isCacEndNotified on interface[%d]", 3283 __func__, intf); 3284 return qdf_status; 3285 } 3286 pSapContext->isCacEndNotified = true; 3287 pMac->sap.SapDfsInfo.sap_radar_found_status = false; 3288 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3289 "sapdfs: Start beacon request on sapctx[%p]", 3290 pSapContext); 3291 3292 /* Start beaconing on the new channel */ 3293 wlansap_start_beacon_req(pSapContext); 3294 3295 /* Transition from eSAP_STARTING to eSAP_STARTED 3296 * (both without substates) 3297 */ 3298 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3299 "sapdfs: channel[%d] from state %s => %s", 3300 pSapContext->channel, "eSAP_STARTING", 3301 "eSAP_STARTED"); 3302 3303 pSapContext->sapsMachine = eSAP_STARTED; 3304 3305 /*Action code for transition */ 3306 qdf_status = sap_signal_hdd_event(pSapContext, roamInfo, 3307 eSAP_START_BSS_EVENT, 3308 (void *) 3309 eSAP_STATUS_SUCCESS); 3310 if (QDF_STATUS_SUCCESS != qdf_status) { 3311 QDF_TRACE(QDF_MODULE_ID_SAP, 3312 QDF_TRACE_LEVEL_ERROR, 3313 "In %s, failed setting isCacEndNotified on interface[%d]", 3314 __func__, intf); 3315 return qdf_status; 3316 } 3317 3318 /* Transition from eSAP_STARTING to eSAP_STARTED 3319 * (both without substates) 3320 */ 3321 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3322 "In %s, from state %s => %s", 3323 __func__, "eSAP_DFS_CAC_WAIT", 3324 "eSAP_STARTED"); 3325 } 3326 } 3327 /* 3328 * All APs are done with CAC timer, all APs should start beaconing. 3329 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets 3330 * say AP1 goes down and comes back on same DFS channel. In this case 3331 * AP1 shouldn't start CAC timer and start beacon immediately beacause 3332 * AP2 is already beaconing on this channel. This case will be handled 3333 * by checking against eSAP_DFS_SKIP_CAC while starting the timer. 3334 */ 3335 pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC; 3336 return qdf_status; 3337 } 3338 3339 /** 3340 * sap_fsm_state_disconnected() - utility function called from sap fsm 3341 * @sap_ctx: SAP context 3342 * @sap_event: SAP event buffer 3343 * @mac_ctx: global MAC context 3344 * @hal: HAL handle 3345 * 3346 * This function is called for state transition from "eSAP_DISCONNECTED" 3347 * 3348 * Return: QDF_STATUS 3349 */ 3350 static QDF_STATUS sap_fsm_state_disconnected(ptSapContext sap_ctx, 3351 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3352 tHalHandle hal) 3353 { 3354 uint32_t msg = sap_event->event; 3355 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3356 3357 if (msg == eSAP_HDD_START_INFRA_BSS) { 3358 /* 3359 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT 3360 * (both without substates) 3361 */ 3362 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3363 FL("new from state %s => %s: session:%d"), 3364 "eSAP_DISCONNECTED", "eSAP_CH_SELECT", 3365 sap_ctx->sessionId); 3366 3367 if (sap_ctx->isSapSessionOpen == eSAP_FALSE) { 3368 uint32_t type, subtype; 3369 if (sap_ctx->csr_roamProfile.csrPersona == 3370 QDF_P2P_GO_MODE) 3371 qdf_status = cds_get_vdev_types(QDF_P2P_GO_MODE, 3372 &type, &subtype); 3373 else 3374 qdf_status = cds_get_vdev_types(QDF_SAP_MODE, 3375 &type, 3376 &subtype); 3377 3378 if (QDF_STATUS_SUCCESS != qdf_status) { 3379 QDF_TRACE(QDF_MODULE_ID_SAP, 3380 QDF_TRACE_LEVEL_FATAL, 3381 "failed to get vdev type"); 3382 return QDF_STATUS_E_FAILURE; 3383 } 3384 /* Open SME Session for scan */ 3385 qdf_status = sme_open_session(hal, NULL, 3386 sap_ctx, sap_ctx->self_mac_addr, 3387 &sap_ctx->sessionId, type, subtype); 3388 if (QDF_STATUS_SUCCESS != qdf_status) { 3389 QDF_TRACE(QDF_MODULE_ID_SAP, 3390 QDF_TRACE_LEVEL_ERROR, 3391 FL("Error: calling sme_open_session")); 3392 return QDF_STATUS_E_FAILURE; 3393 } 3394 3395 sap_ctx->isSapSessionOpen = eSAP_TRUE; 3396 } 3397 3398 /* init dfs channel nol */ 3399 sap_init_dfs_channel_nol_list(sap_ctx); 3400 3401 /* Set SAP device role */ 3402 sap_ctx->sapsMachine = eSAP_CH_SELECT; 3403 3404 /* 3405 * Perform sme_ScanRequest. This scan request is post start bss 3406 * request so, set the third to false. 3407 */ 3408 qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false, 3409 true); 3410 3411 /* 3412 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT 3413 * (both without substates) 3414 */ 3415 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3416 FL("from state %s => %s"), 3417 "eSAP_DISCONNECTED", "eSAP_CH_SELECT"); 3418 } else if (msg == eSAP_DFS_CHANNEL_CAC_START) { 3419 /* 3420 * No need of state check here, caller is expected to perform 3421 * the checks before sending the event 3422 */ 3423 sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT; 3424 3425 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3426 FL("from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT")); 3427 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) { 3428 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3429 FL("sapdfs: starting dfs cac timer on sapctx[%p]"), 3430 sap_ctx); 3431 sap_start_dfs_cac_timer(sap_ctx); 3432 } 3433 3434 qdf_status = sap_cac_start_notify(hal); 3435 } else if (msg == eSAP_CHANNEL_SELECTION_RETRY) { 3436 /* Set SAP device role */ 3437 sap_ctx->sapsMachine = eSAP_CH_SELECT; 3438 3439 /* 3440 * Perform sme_ScanRequest. This scan request is post start bss 3441 * request so, set the third to false. 3442 */ 3443 qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false, 3444 false); 3445 } else { 3446 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3447 FL("in state %s, event msg %d"), 3448 "eSAP_DISCONNECTED", msg); 3449 } 3450 3451 return qdf_status; 3452 } 3453 3454 /** 3455 * sap_fsm_state_ch_select() - utility function called from sap fsm 3456 * @sap_ctx: SAP context 3457 * @sap_event: SAP event buffer 3458 * @mac_ctx: global MAC context 3459 * @hal: HAL handle 3460 * 3461 * This function is called for state transition from "eSAP_CH_SELECT" 3462 * 3463 * Return: QDF_STATUS 3464 */ 3465 static QDF_STATUS sap_fsm_state_ch_select(ptSapContext sap_ctx, 3466 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3467 tHalHandle hal) 3468 { 3469 uint32_t msg = sap_event->event; 3470 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3471 uint32_t cbmode; 3472 bool b_leak_chan = false; 3473 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 3474 uint8_t temp_chan; 3475 tSapDfsNolInfo *p_nol; 3476 #endif 3477 3478 if (msg == eSAP_MAC_SCAN_COMPLETE) { 3479 /* get the bonding mode */ 3480 if (sap_ctx->channel <= 14) 3481 cbmode = sme_get_cb_phy_state_from_cb_ini_value( 3482 sme_get_channel_bonding_mode24_g(hal)); 3483 else 3484 cbmode = sme_get_cb_phy_state_from_cb_ini_value( 3485 sme_get_channel_bonding_mode5_g(hal)); 3486 3487 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 3488 temp_chan = sap_ctx->channel; 3489 p_nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList; 3490 3491 sap_mark_leaking_ch(sap_ctx, 3492 cbmode, p_nol, 1, &temp_chan); 3493 3494 /* 3495 * if selelcted channel has leakage to channels 3496 * in NOL, the temp_chan will be reset 3497 */ 3498 b_leak_chan = (temp_chan != sap_ctx->channel); 3499 #endif 3500 /* 3501 * check if channel is in DFS_NOL or if the channel 3502 * has leakage to the channels in NOL 3503 */ 3504 if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel, 3505 cbmode) || b_leak_chan) { 3506 uint8_t ch; 3507 3508 /* find a new available channel */ 3509 ch = sap_random_channel_sel(sap_ctx); 3510 if (ch == 0) { 3511 /* No available channel found */ 3512 QDF_TRACE(QDF_MODULE_ID_SAP, 3513 QDF_TRACE_LEVEL_ERROR, 3514 FL("No available channel found!!!")); 3515 sap_signal_hdd_event(sap_ctx, NULL, 3516 eSAP_DFS_NO_AVAILABLE_CHANNEL, 3517 (void *)eSAP_STATUS_SUCCESS); 3518 return QDF_STATUS_E_FAULT; 3519 } 3520 3521 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3522 FL("channel %d is in NOL, StartBss on new channel %d"), 3523 sap_ctx->channel, ch); 3524 3525 sap_ctx->channel = ch; 3526 cds_set_channel_params(sap_ctx->channel, 3527 sap_ctx->secondary_ch, &sap_ctx->ch_params); 3528 } 3529 if (sap_ctx->channel > 14 && 3530 (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g || 3531 sap_ctx->csr_roamProfile.phyMode == 3532 eCSR_DOT11_MODE_11g_ONLY)) 3533 sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a; 3534 3535 /* 3536 * when AP2 is started while AP1 is performing ACS, we may not 3537 * have the AP1 channel yet.So here after the completion of AP2 3538 * ACS check if AP1 ACS resulting channel is DFS and if yes 3539 * override AP2 ACS scan result with AP1 DFS channel 3540 */ 3541 if (cds_concurrent_beaconing_sessions_running()) { 3542 uint16_t con_ch; 3543 3544 con_ch = sme_get_concurrent_operation_channel(hal); 3545 if (con_ch && CDS_IS_DFS_CH(con_ch)) 3546 sap_ctx->channel = con_ch; 3547 } 3548 3549 /* 3550 * Transition from eSAP_CH_SELECT to eSAP_STARTING 3551 * (both without substates) 3552 */ 3553 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3554 FL("from state %s => %s"), 3555 "eSAP_CH_SELECT", "eSAP_STARTING"); 3556 /* Channel selected. Now can sap_goto_starting */ 3557 sap_ctx->sapsMachine = eSAP_STARTING; 3558 /* Specify the channel */ 3559 sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels = 3560 1; 3561 sap_ctx->csr_roamProfile.ChannelInfo.ChannelList = 3562 &sap_ctx->csr_roamProfile.operationChannel; 3563 sap_ctx->csr_roamProfile.operationChannel = 3564 (uint8_t) sap_ctx->channel; 3565 sap_ctx->csr_roamProfile.ch_params.ch_width = 3566 sap_ctx->ch_params.ch_width; 3567 sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 = 3568 sap_ctx->ch_params.center_freq_seg0; 3569 sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 = 3570 sap_ctx->ch_params.center_freq_seg1; 3571 sap_ctx->csr_roamProfile.ch_params.sec_ch_offset = 3572 sap_ctx->ch_params.sec_ch_offset; 3573 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3574 FL("notify hostapd about channel selection: %d"), 3575 sap_ctx->channel); 3576 sap_signal_hdd_event(sap_ctx, NULL, 3577 eSAP_CHANNEL_CHANGE_EVENT, 3578 (void *) eSAP_STATUS_SUCCESS); 3579 qdf_status = sap_goto_starting(sap_ctx, sap_event, 3580 eCSR_BSS_TYPE_INFRA_AP); 3581 } else if (msg == eSAP_CHANNEL_SELECTION_FAILED) { 3582 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3583 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3584 FL("Cannot start BSS, ACS Fail")); 3585 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3586 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3587 sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT, 3588 (void *)eSAP_STATUS_FAILURE); 3589 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3590 "%s: BSS stopped when Ch select in Progress", __func__); 3591 } else { 3592 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3593 FL("in state %s, invalid event msg %d"), 3594 "eSAP_CH_SELECT", msg); 3595 } 3596 3597 return qdf_status; 3598 } 3599 3600 /** 3601 * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm 3602 * @sap_ctx: SAP context 3603 * @sap_event: SAP event buffer 3604 * @mac_ctx: global MAC context 3605 * @hal: HAL handle 3606 * 3607 * This function is called for state transition from "eSAP_DFS_CAC_WAIT" 3608 * 3609 * Return: QDF_STATUS 3610 */ 3611 static QDF_STATUS sap_fsm_state_dfs_cac_wait(ptSapContext sap_ctx, 3612 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3613 tHalHandle hal) 3614 { 3615 uint32_t msg = sap_event->event; 3616 tCsrRoamInfo *roam_info = (tCsrRoamInfo *) (sap_event->params); 3617 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3618 3619 if (msg == eSAP_DFS_CHANNEL_CAC_START) { 3620 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3621 FL("from state %s => %s"), 3622 "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT"); 3623 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) 3624 sap_start_dfs_cac_timer(sap_ctx); 3625 qdf_status = sap_cac_start_notify(hal); 3626 } else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) { 3627 uint8_t intf; 3628 /* 3629 * Radar found while performing channel availability 3630 * check, need to switch the channel again 3631 */ 3632 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3633 "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n"); 3634 if (mac_ctx->sap.SapDfsInfo.target_channel) { 3635 cds_set_channel_params( 3636 mac_ctx->sap.SapDfsInfo.target_channel, 0, 3637 &sap_ctx->ch_params); 3638 } 3639 3640 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3641 ptSapContext t_sap_ctx; 3642 if (((QDF_SAP_MODE == 3643 mac_ctx->sap.sapCtxList[intf].sapPersona) || 3644 (QDF_P2P_GO_MODE == 3645 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 3646 mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) { 3647 t_sap_ctx = 3648 mac_ctx->sap.sapCtxList[intf].pSapContext; 3649 /* SAP to be moved to DISCONNECTING state */ 3650 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 3651 /* 3652 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND: 3653 * A Radar is found on current DFS Channel 3654 * while in CAC WAIT period So, do a channel 3655 * switch to randomly selected target channel. 3656 * Send the Channel change message to SME/PE. 3657 * sap_radar_found_status is set to 1 3658 */ 3659 sap_signal_hdd_event(t_sap_ctx, NULL, 3660 eSAP_DFS_RADAR_DETECT, 3661 (void *)eSAP_STATUS_SUCCESS); 3662 3663 wlansap_channel_change_request( 3664 (void *)t_sap_ctx, 3665 mac_ctx->sap.SapDfsInfo.target_channel); 3666 } 3667 } 3668 } else if (msg == eSAP_DFS_CHANNEL_CAC_END) { 3669 qdf_status = sap_cac_end_notify(hal, roam_info); 3670 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3671 /* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */ 3672 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3673 FL("from state %s => %s"), 3674 "eSAP_DFS_CAC_WAIT", "eSAP_DISCONNECTING"); 3675 3676 /* 3677 * Stop the CAC timer only in following conditions 3678 * single AP: if there is a single AP then stop the timer 3679 * mulitple APs: incase of multiple APs, make sure that 3680 * all APs are down. 3681 */ 3682 if (NULL == sap_find_valid_concurrent_session(hal)) { 3683 QDF_TRACE(QDF_MODULE_ID_SAP, 3684 QDF_TRACE_LEVEL_INFO_MED, 3685 FL("sapdfs: no sessions are valid, stopping timer")); 3686 sap_stop_dfs_cac_timer(sap_ctx); 3687 } 3688 3689 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 3690 qdf_status = sap_goto_disconnecting(sap_ctx); 3691 } else { 3692 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3693 FL("in state %s, invalid event msg %d"), 3694 "eSAP_DFS_CAC_WAIT", msg); 3695 } 3696 3697 return qdf_status; 3698 } 3699 3700 /** 3701 * sap_fsm_state_starting() - utility function called from sap fsm 3702 * @sap_ctx: SAP context 3703 * @sap_event: SAP event buffer 3704 * @mac_ctx: global MAC context 3705 * @hal: HAL handle 3706 * 3707 * This function is called for state transition from "eSAP_STARTING" 3708 * 3709 * Return: QDF_STATUS 3710 */ 3711 static QDF_STATUS sap_fsm_state_starting(ptSapContext sap_ctx, 3712 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3713 tHalHandle hal) 3714 { 3715 uint32_t msg = sap_event->event; 3716 tCsrRoamInfo *roam_info = (tCsrRoamInfo *) (sap_event->params); 3717 tSapDfsInfo *sap_dfs_info; 3718 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3719 uint8_t is_dfs = false; 3720 3721 if (msg == eSAP_MAC_START_BSS_SUCCESS) { 3722 /* 3723 * Transition from eSAP_STARTING to eSAP_STARTED 3724 * (both without substates) 3725 */ 3726 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3727 FL("from state channel = %d %s => %s ch_width %d"), 3728 sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED", 3729 sap_ctx->ch_params.ch_width); 3730 sap_ctx->sapsMachine = eSAP_STARTED; 3731 3732 /* Action code for transition */ 3733 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 3734 eSAP_START_BSS_EVENT, 3735 (void *) eSAP_STATUS_SUCCESS); 3736 3737 /* 3738 * The upper layers have been informed that AP is up and 3739 * running, however, the AP is still not beaconing, until 3740 * CAC is done if the operating channel is DFS 3741 */ 3742 if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { 3743 is_dfs = true; 3744 } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { 3745 if (cds_get_channel_state(sap_ctx->channel) == 3746 CHANNEL_STATE_DFS || 3747 cds_get_channel_state(sap_ctx-> 3748 ch_params.center_freq_seg1 - 3749 SIR_80MHZ_START_CENTER_CH_DIFF) == 3750 CHANNEL_STATE_DFS) 3751 is_dfs = true; 3752 } else { 3753 if (cds_get_channel_state(sap_ctx->channel) == 3754 CHANNEL_STATE_DFS) 3755 is_dfs = true; 3756 } 3757 3758 if (is_dfs) { 3759 sap_dfs_info = &mac_ctx->sap.SapDfsInfo; 3760 if ((false == sap_dfs_info->ignore_cac) && 3761 (eSAP_DFS_DO_NOT_SKIP_CAC == 3762 sap_dfs_info->cac_state) && 3763 !sap_ctx->pre_cac_complete) { 3764 /* Move the device in CAC_WAIT_STATE */ 3765 sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT; 3766 3767 /* 3768 * Need to stop the OS transmit queues, 3769 * so that no traffic can flow down the stack 3770 */ 3771 3772 /* Start CAC wait timer */ 3773 if (sap_dfs_info->is_dfs_cac_timer_running != 3774 true) 3775 sap_start_dfs_cac_timer(sap_ctx); 3776 qdf_status = sap_cac_start_notify(hal); 3777 3778 } else { 3779 wlansap_start_beacon_req(sap_ctx); 3780 } 3781 } 3782 } else if (msg == eSAP_MAC_START_FAILS) { 3783 /* 3784 * Transition from STARTING to DISCONNECTED 3785 * (both without substates) 3786 */ 3787 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3788 FL("from state %s => %s"), 3789 "eSAP_STARTING", "eSAP_DISCONNECTED"); 3790 3791 /*Action code for transition */ 3792 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3793 eSAP_START_BSS_EVENT, 3794 (void *) eSAP_STATUS_FAILURE); 3795 qdf_status = sap_goto_disconnected(sap_ctx); 3796 /* Advance outer statevar */ 3797 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3798 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3799 /* 3800 * Transition from eSAP_STARTING to eSAP_DISCONNECTED 3801 * (both without substates) 3802 */ 3803 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3804 FL("from state %s => %s"), 3805 "eSAP_STARTING", "eSAP_DISCONNECTED"); 3806 3807 /* Advance outer statevar */ 3808 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3809 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3810 eSAP_START_BSS_EVENT, 3811 (void *) eSAP_STATUS_FAILURE); 3812 qdf_status = sap_goto_disconnected(sap_ctx); 3813 /* Close the SME session */ 3814 3815 if (eSAP_TRUE == sap_ctx->isSapSessionOpen) { 3816 if (QDF_STATUS_SUCCESS == sap_close_session(hal, 3817 sap_ctx, NULL, false)) 3818 sap_ctx->isSapSessionOpen = eSAP_FALSE; 3819 } 3820 } else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) { 3821 /* The operating channel has changed, update hostapd */ 3822 sap_ctx->channel = 3823 (uint8_t) mac_ctx->sap.SapDfsInfo.target_channel; 3824 3825 sap_ctx->sapsMachine = eSAP_STARTED; 3826 3827 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3828 FL("from state %s => %s"), 3829 "eSAP_STARTING", "eSAP_STARTED"); 3830 3831 /* Indicate change in the state to upper layers */ 3832 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 3833 eSAP_START_BSS_EVENT, 3834 (void *)eSAP_STATUS_SUCCESS); 3835 } else { 3836 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3837 FL("in state %s, invalid event msg %d"), 3838 "eSAP_STARTING", msg); 3839 } 3840 3841 return qdf_status; 3842 } 3843 3844 /** 3845 * sap_fsm_state_started() - utility function called from sap fsm 3846 * @sap_ctx: SAP context 3847 * @sap_event: SAP event buffer 3848 * @mac_ctx: global MAC context 3849 * 3850 * This function is called for state transition from "eSAP_STARTED" 3851 * 3852 * Return: QDF_STATUS 3853 */ 3854 static QDF_STATUS sap_fsm_state_started(ptSapContext sap_ctx, 3855 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx) 3856 { 3857 uint32_t msg = sap_event->event; 3858 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3859 3860 if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3861 /* 3862 * Transition from eSAP_STARTED to eSAP_DISCONNECTING 3863 * (both without substates) 3864 */ 3865 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3866 FL("from state %s => %s"), 3867 "eSAP_STARTED", "eSAP_DISCONNECTING"); 3868 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 3869 qdf_status = sap_goto_disconnecting(sap_ctx); 3870 } else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) { 3871 uint8_t intf; 3872 /* 3873 * Radar is seen on the current operating channel 3874 * send CSA IE for all associated stations 3875 * Request for CSA IE transmission 3876 */ 3877 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3878 ptSapContext temp_sap_ctx; 3879 if (((QDF_SAP_MODE == 3880 mac_ctx->sap.sapCtxList[intf].sapPersona) || 3881 (QDF_P2P_GO_MODE == 3882 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 3883 mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) { 3884 temp_sap_ctx = 3885 mac_ctx->sap.sapCtxList[intf].pSapContext; 3886 QDF_TRACE(QDF_MODULE_ID_SAP, 3887 QDF_TRACE_LEVEL_INFO_MED, 3888 FL("sapdfs: Sending CSAIE for sapctx[%p]"), 3889 temp_sap_ctx); 3890 3891 qdf_status = wlansap_dfs_send_csa_ie_request( 3892 (void *) temp_sap_ctx); 3893 } 3894 } 3895 } else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) { 3896 enum tQDF_ADAPTER_MODE persona; 3897 3898 if (!sap_ctx) { 3899 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3900 FL("Invalid sap_ctx")); 3901 return qdf_status; 3902 } 3903 3904 persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId]. 3905 sapPersona; 3906 3907 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3908 FL("app trigger chan switch: mode:%d vdev:%d"), 3909 persona, sap_ctx->sessionId); 3910 3911 if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona)) 3912 qdf_status = wlansap_dfs_send_csa_ie_request( 3913 (void *) sap_ctx); 3914 } else { 3915 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3916 FL("in state %s, invalid event msg %d"), 3917 "eSAP_STARTED", msg); 3918 } 3919 3920 return qdf_status; 3921 } 3922 3923 /** 3924 * sap_fsm_state_disconnecting() - utility function called from sap fsm 3925 * @sap_ctx: SAP context 3926 * @sap_event: SAP event buffer 3927 * @mac_ctx: global MAC context 3928 * 3929 * This function is called for state transition from "eSAP_DISCONNECTING" 3930 * 3931 * Return: QDF_STATUS 3932 */ 3933 static QDF_STATUS sap_fsm_state_disconnecting(ptSapContext sap_ctx, 3934 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3935 tHalHandle hal) 3936 { 3937 uint32_t msg = sap_event->event; 3938 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3939 3940 if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) { 3941 /* 3942 * Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED 3943 * (both without substates) 3944 */ 3945 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3946 FL("from state %s => %s"), 3947 "eSAP_DISCONNECTING", "eSAP_DISCONNECTED"); 3948 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3949 3950 /* Close the SME session */ 3951 if (eSAP_TRUE == sap_ctx->isSapSessionOpen) { 3952 sap_ctx->isSapSessionOpen = eSAP_FALSE; 3953 qdf_status = sap_close_session(hal, sap_ctx, 3954 sap_roam_session_close_callback, true); 3955 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 3956 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3957 eSAP_STOP_BSS_EVENT, 3958 (void *)eSAP_STATUS_SUCCESS); 3959 } 3960 } 3961 } else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) { 3962 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3963 FL("sapdfs: Send channel change request on sapctx[%p]"), 3964 sap_ctx); 3965 /* 3966 * Most likely, radar has been detected and SAP wants to 3967 * change the channel 3968 */ 3969 qdf_status = wlansap_channel_change_request((void *) sap_ctx, 3970 mac_ctx->sap.SapDfsInfo.target_channel); 3971 3972 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3973 FL("Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ")); 3974 } else { 3975 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3976 FL("in state %s, invalid event msg %d"), 3977 "eSAP_DISCONNECTING", msg); 3978 } 3979 3980 return qdf_status; 3981 } 3982 3983 /** 3984 * sap_fsm() - SAP statem machine entry function 3985 * @sap_ctx: SAP context 3986 * @sap_event: SAP event 3987 * 3988 * SAP statem machine entry function 3989 * 3990 * Return: QDF_STATUS 3991 */ 3992 QDF_STATUS sap_fsm(ptSapContext sap_ctx, ptWLAN_SAPEvent sap_event) 3993 { 3994 /* 3995 * Retrieve the phy link state machine structure 3996 * from the sap_ctx value 3997 * state var that keeps track of state machine 3998 */ 3999 eSapFsmStates_t state_var = sap_ctx->sapsMachine; 4000 uint32_t msg = sap_event->event; /* State machine input event message */ 4001 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 4002 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 4003 tpAniSirGlobal mac_ctx; 4004 4005 if (NULL == hal) { 4006 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4007 FL("Invalid hal")); 4008 return QDF_STATUS_E_FAILURE; 4009 } 4010 4011 mac_ctx = PMAC_STRUCT(hal); 4012 if (NULL == mac_ctx) { 4013 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4014 FL("Invalid MAC context")); 4015 return QDF_STATUS_E_FAILURE; 4016 } 4017 4018 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 4019 FL("sap_ctx=%p, state_var=%d, msg=0x%x"), 4020 sap_ctx, state_var, msg); 4021 4022 switch (state_var) { 4023 case eSAP_DISCONNECTED: 4024 qdf_status = sap_fsm_state_disconnected(sap_ctx, sap_event, 4025 mac_ctx, hal); 4026 break; 4027 4028 case eSAP_CH_SELECT: 4029 qdf_status = sap_fsm_state_ch_select(sap_ctx, sap_event, 4030 mac_ctx, hal); 4031 break; 4032 4033 case eSAP_DFS_CAC_WAIT: 4034 qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event, 4035 mac_ctx, hal); 4036 break; 4037 4038 case eSAP_STARTING: 4039 qdf_status = sap_fsm_state_starting(sap_ctx, sap_event, 4040 mac_ctx, hal); 4041 break; 4042 4043 case eSAP_STARTED: 4044 qdf_status = sap_fsm_state_started(sap_ctx, sap_event, 4045 mac_ctx); 4046 break; 4047 4048 case eSAP_DISCONNECTING: 4049 qdf_status = sap_fsm_state_disconnecting(sap_ctx, sap_event, 4050 mac_ctx, hal); 4051 break; 4052 } 4053 return qdf_status; 4054 } 4055 4056 eSapStatus 4057 sapconvert_to_csr_profile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, 4058 tCsrRoamProfile *profile) 4059 { 4060 /* Create Roam profile for SoftAP to connect */ 4061 profile->BSSType = eCSR_BSS_TYPE_INFRA_AP; 4062 profile->SSIDs.numOfSSIDs = 1; 4063 profile->csrPersona = pconfig_params->persona; 4064 profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch; 4065 4066 qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId, 4067 sizeof(profile->SSIDs.SSIDList[0].SSID.ssId)); 4068 4069 /* Flag to not broadcast the SSID information */ 4070 profile->SSIDs.SSIDList[0].ssidHidden = 4071 pconfig_params->SSIDinfo.ssidHidden; 4072 4073 profile->SSIDs.SSIDList[0].SSID.length = 4074 pconfig_params->SSIDinfo.ssid.length; 4075 qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId, 4076 pconfig_params->SSIDinfo.ssid.ssId, 4077 sizeof(pconfig_params->SSIDinfo.ssid.ssId)); 4078 4079 profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; 4080 4081 if (pconfig_params->authType == eSAP_OPEN_SYSTEM) { 4082 profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; 4083 } else if (pconfig_params->authType == eSAP_SHARED_KEY) { 4084 profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY; 4085 } else { 4086 profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH; 4087 } 4088 4089 profile->AuthType.numEntries = 1; 4090 profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; 4091 4092 /* Always set the Encryption Type */ 4093 profile->EncryptionType.numEntries = 1; 4094 profile->EncryptionType.encryptionType[0] = 4095 pconfig_params->RSNEncryptType; 4096 4097 profile->mcEncryptionType.numEntries = 1; 4098 profile->mcEncryptionType.encryptionType[0] = 4099 pconfig_params->mcRSNEncryptType; 4100 4101 if (pconfig_params->privacy & eSAP_SHARED_KEY) { 4102 profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY; 4103 } 4104 4105 profile->privacy = pconfig_params->privacy; 4106 profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq; 4107 4108 if (pconfig_params->authType == eSAP_SHARED_KEY) { 4109 profile->csr80211AuthType = eSIR_SHARED_KEY; 4110 } else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) { 4111 profile->csr80211AuthType = eSIR_OPEN_SYSTEM; 4112 } else { 4113 profile->csr80211AuthType = eSIR_AUTO_SWITCH; 4114 } 4115 4116 /* Initialize we are not going to use it */ 4117 profile->pWPAReqIE = NULL; 4118 profile->nWPAReqIELength = 0; 4119 4120 /* set the RSN/WPA IE */ 4121 profile->pRSNReqIE = NULL; 4122 profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; 4123 if (pconfig_params->RSNWPAReqIELength) { 4124 profile->pRSNReqIE = 4125 qdf_mem_malloc(pconfig_params->RSNWPAReqIELength); 4126 if (NULL == profile->pRSNReqIE) { 4127 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4128 " %s Fail to alloc memory", __func__); 4129 return eSAP_STATUS_FAILURE; 4130 } 4131 qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE, 4132 pconfig_params->RSNWPAReqIELength); 4133 profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; 4134 } 4135 /* Turn off CB mode */ 4136 profile->CBMode = eCSR_CB_OFF; 4137 4138 /* set the phyMode to accept anything */ 4139 /* Best means everything because it covers all the things we support */ 4140 /* eCSR_DOT11_MODE_BEST */ 4141 profile->phyMode = pconfig_params->SapHw_mode; 4142 4143 /* Configure beaconInterval */ 4144 profile->beaconInterval = (uint16_t) pconfig_params->beacon_int; 4145 4146 /* set DTIM period */ 4147 profile->dtimPeriod = pconfig_params->dtim_period; 4148 4149 /* set Uapsd enable bit */ 4150 profile->ApUapsdEnable = pconfig_params->UapsdEnable; 4151 4152 /* Enable protection parameters */ 4153 profile->protEnabled = pconfig_params->protEnabled; 4154 profile->obssProtEnabled = pconfig_params->obssProtEnabled; 4155 profile->cfg_protection = pconfig_params->ht_capab; 4156 4157 /* country code */ 4158 if (pconfig_params->countryCode[0]) 4159 qdf_mem_copy(profile->countryCode, pconfig_params->countryCode, 4160 WNI_CFG_COUNTRY_CODE_LEN); 4161 profile->ieee80211d = pconfig_params->ieee80211d; 4162 /* wps config info */ 4163 profile->wps_state = pconfig_params->wps_state; 4164 4165 #ifdef WLAN_FEATURE_11W 4166 /* MFP capable/required */ 4167 profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0; 4168 profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0; 4169 #endif 4170 4171 if (pconfig_params->probeRespIEsBufferLen > 0 && 4172 pconfig_params->pProbeRespIEsBuffer != NULL) { 4173 profile->addIeParams.probeRespDataLen = 4174 pconfig_params->probeRespIEsBufferLen; 4175 profile->addIeParams.probeRespData_buff = 4176 pconfig_params->pProbeRespIEsBuffer; 4177 } else { 4178 profile->addIeParams.probeRespDataLen = 0; 4179 profile->addIeParams.probeRespData_buff = NULL; 4180 } 4181 /*assoc resp IE */ 4182 if (pconfig_params->assocRespIEsLen > 0 && 4183 pconfig_params->pAssocRespIEsBuffer != NULL) { 4184 profile->addIeParams.assocRespDataLen = 4185 pconfig_params->assocRespIEsLen; 4186 profile->addIeParams.assocRespData_buff = 4187 pconfig_params->pAssocRespIEsBuffer; 4188 } else { 4189 profile->addIeParams.assocRespDataLen = 0; 4190 profile->addIeParams.assocRespData_buff = NULL; 4191 } 4192 4193 if (pconfig_params->probeRespBcnIEsLen > 0 && 4194 pconfig_params->pProbeRespBcnIEsBuffer != NULL) { 4195 profile->addIeParams.probeRespBCNDataLen = 4196 pconfig_params->probeRespBcnIEsLen; 4197 profile->addIeParams.probeRespBCNData_buff = 4198 pconfig_params->pProbeRespBcnIEsBuffer; 4199 } else { 4200 profile->addIeParams.probeRespBCNDataLen = 0; 4201 profile->addIeParams.probeRespBCNData_buff = NULL; 4202 } 4203 profile->sap_dot11mc = pconfig_params->sap_dot11mc; 4204 4205 return eSAP_STATUS_SUCCESS; /* Success. */ 4206 } 4207 4208 void sap_free_roam_profile(tCsrRoamProfile *profile) 4209 { 4210 if (profile->pRSNReqIE) { 4211 qdf_mem_free(profile->pRSNReqIE); 4212 profile->pRSNReqIE = NULL; 4213 } 4214 } 4215 4216 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size) 4217 { 4218 uint8_t outer, inner; 4219 struct qdf_mac_addr temp; 4220 int32_t nRes = -1; 4221 4222 if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) { 4223 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4224 FL("either buffer is NULL or size = %d is more"), size); 4225 return; 4226 } 4227 4228 for (outer = 0; outer < size; outer++) { 4229 for (inner = 0; inner < size - 1; inner++) { 4230 nRes = 4231 qdf_mem_cmp((macList + inner)->bytes, 4232 (macList + inner + 1)->bytes, 4233 QDF_MAC_ADDR_SIZE); 4234 if (nRes > 0) { 4235 qdf_mem_copy(temp.bytes, 4236 (macList + inner + 1)->bytes, 4237 QDF_MAC_ADDR_SIZE); 4238 qdf_mem_copy((macList + inner + 1)->bytes, 4239 (macList + inner)->bytes, 4240 QDF_MAC_ADDR_SIZE); 4241 qdf_mem_copy((macList + inner)->bytes, 4242 temp.bytes, QDF_MAC_ADDR_SIZE); 4243 } 4244 } 4245 } 4246 } 4247 4248 eSapBool 4249 sap_search_mac_list(struct qdf_mac_addr *macList, 4250 uint8_t num_mac, uint8_t *peerMac, 4251 uint8_t *index) 4252 { 4253 int32_t nRes = -1; 4254 int8_t nStart = 0, nEnd, nMiddle; 4255 nEnd = num_mac - 1; 4256 4257 if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) { 4258 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4259 FL("either buffer is NULL or size = %d is more."), num_mac); 4260 return eSAP_FALSE; 4261 } 4262 4263 while (nStart <= nEnd) { 4264 nMiddle = (nStart + nEnd) / 2; 4265 nRes = 4266 qdf_mem_cmp(&macList[nMiddle], peerMac, 4267 QDF_MAC_ADDR_SIZE); 4268 4269 if (0 == nRes) { 4270 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4271 "search SUCC"); 4272 /* "index equals NULL" means the caller does not need the */ 4273 /* index value of the peerMac being searched */ 4274 if (index != NULL) { 4275 *index = (uint8_t) nMiddle; 4276 QDF_TRACE(QDF_MODULE_ID_SAP, 4277 QDF_TRACE_LEVEL_INFO_HIGH, "index %d", 4278 *index); 4279 } 4280 return eSAP_TRUE; 4281 } 4282 if (nRes < 0) 4283 nStart = nMiddle + 1; 4284 else 4285 nEnd = nMiddle - 1; 4286 } 4287 4288 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4289 "search not succ"); 4290 return eSAP_FALSE; 4291 } 4292 4293 void sap_add_mac_to_acl(struct qdf_mac_addr *macList, 4294 uint8_t *size, uint8_t *peerMac) 4295 { 4296 int32_t nRes = -1; 4297 int i; 4298 4299 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4300 "add acl entered"); 4301 4302 if (NULL == macList || *size == 0 || *size > MAX_ACL_MAC_ADDRESS) { 4303 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4304 FL("either buffer is NULL or size = %d is incorrect."), 4305 *size); 4306 return; 4307 } 4308 4309 for (i = ((*size) - 1); i >= 0; i--) { 4310 nRes = 4311 qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE); 4312 if (nRes > 0) { 4313 /* Move alphabetically greater mac addresses one index down to allow for insertion 4314 of new mac in sorted order */ 4315 qdf_mem_copy((macList + i + 1)->bytes, 4316 (macList + i)->bytes, QDF_MAC_ADDR_SIZE); 4317 } else { 4318 break; 4319 } 4320 } 4321 /* This should also take care of if the element is the first to be added in the list */ 4322 qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE); 4323 /* increment the list size */ 4324 (*size)++; 4325 } 4326 4327 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList, 4328 uint8_t *size, uint8_t index) 4329 { 4330 int i; 4331 4332 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4333 "remove acl entered"); 4334 /* 4335 * Return if the list passed is empty. Ideally this should never happen 4336 * since this funcn is always called after sap_search_mac_list to get 4337 * the index of the mac addr to be removed and this will only get 4338 * called if the search is successful. Still no harm in having the check 4339 */ 4340 if ((macList == NULL) || (*size == 0) || 4341 (*size > MAX_ACL_MAC_ADDRESS)) { 4342 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4343 FL("either buffer is NULL or size %d is incorrect."), 4344 *size); 4345 return; 4346 } 4347 for (i = index; i < ((*size) - 1); i++) { 4348 /* Move mac addresses starting from "index" passed one index up to delete the void 4349 created by deletion of a mac address in ACL */ 4350 qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes, 4351 QDF_MAC_ADDR_SIZE); 4352 } 4353 /* The last space should be made empty since all mac addesses moved one step up */ 4354 qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE); 4355 /* reduce the list size by 1 */ 4356 (*size)--; 4357 } 4358 4359 void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size) 4360 { 4361 int i; 4362 uint8_t *macArray; 4363 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4364 "print acl entered"); 4365 4366 if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) { 4367 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4368 "In %s, either buffer is NULL or size %d is incorrect.", 4369 __func__, size); 4370 return; 4371 } 4372 4373 for (i = 0; i < size; i++) { 4374 macArray = (macList + i)->bytes; 4375 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4376 "** ACL entry %i - " MAC_ADDRESS_STR, i, 4377 MAC_ADDR_ARRAY(macArray)); 4378 } 4379 return; 4380 } 4381 4382 QDF_STATUS sap_is_peer_mac_allowed(ptSapContext sapContext, uint8_t *peerMac) 4383 { 4384 if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode) 4385 return QDF_STATUS_SUCCESS; 4386 4387 if (sap_search_mac_list 4388 (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL)) 4389 return QDF_STATUS_SUCCESS; 4390 4391 if (sap_search_mac_list 4392 (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) { 4393 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4394 "In %s, Peer " MAC_ADDRESS_STR " in deny list", 4395 __func__, MAC_ADDR_ARRAY(peerMac)); 4396 return QDF_STATUS_E_FAILURE; 4397 } 4398 /* A new station CAN associate, unless in deny list. Less stringent mode */ 4399 if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode) 4400 return QDF_STATUS_SUCCESS; 4401 4402 /* A new station CANNOT associate, unless in accept list. More stringent mode */ 4403 if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) { 4404 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4405 "In %s, Peer " MAC_ADDRESS_STR 4406 " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED", 4407 __func__, MAC_ADDR_ARRAY(peerMac)); 4408 return QDF_STATUS_E_FAILURE; 4409 } 4410 4411 /* The new STA is neither in accept list nor in deny list. In this case, deny the association 4412 * but send a wifi event notification indicating the mac address being denied 4413 */ 4414 if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) { 4415 sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN, 4416 (void *) peerMac); 4417 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4418 "In %s, Peer " MAC_ADDRESS_STR 4419 " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY", 4420 __func__, MAC_ADDR_ARRAY(peerMac)); 4421 return QDF_STATUS_E_FAILURE; 4422 } 4423 return QDF_STATUS_SUCCESS; 4424 } 4425 4426 #ifdef SOFTAP_CHANNEL_RANGE 4427 /** 4428 * sap_get_channel_list() - get the list of channels 4429 * @sap_ctx: sap context 4430 * @ch_list: pointer to channel list array 4431 * @num_ch: pointer to number of channels. 4432 * 4433 * This function populates the list of channels for scanning. 4434 * 4435 * Return: QDF_STATUS 4436 */ 4437 static QDF_STATUS sap_get_channel_list(ptSapContext sap_ctx, 4438 uint8_t **ch_list, 4439 uint8_t *num_ch) 4440 { 4441 uint8_t loop_count; 4442 uint8_t *list; 4443 uint8_t ch_count; 4444 uint8_t start_ch_num, band_start_ch; 4445 uint8_t end_ch_num, band_end_ch; 4446 uint32_t en_lte_coex; 4447 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 4448 #ifdef FEATURE_WLAN_CH_AVOID 4449 uint8_t i; 4450 #endif 4451 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 4452 4453 if (NULL == hal) { 4454 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4455 FL("Invalid HAL pointer from p_cds_gctx")); 4456 *num_ch = 0; 4457 *ch_list = NULL; 4458 return QDF_STATUS_E_FAULT; 4459 } 4460 4461 start_ch_num = sap_ctx->acs_cfg->start_ch; 4462 end_ch_num = sap_ctx->acs_cfg->end_ch; 4463 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 4464 FL("startChannel %d, EndChannel %d, HW:%d"), 4465 start_ch_num, end_ch_num, 4466 sap_ctx->acs_cfg->hw_mode); 4467 4468 wlansap_extend_to_acs_range(&start_ch_num, &end_ch_num, 4469 &band_start_ch, &band_end_ch); 4470 4471 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 4472 FL("expanded startChannel %d,EndChannel %d"), 4473 start_ch_num, end_ch_num); 4474 4475 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 4476 FL("band_start_ch %d, band_end_ch %d"), 4477 band_start_ch, band_end_ch); 4478 4479 sme_cfg_get_int(hal, WNI_CFG_ENABLE_LTE_COEX, &en_lte_coex); 4480 4481 /* Check if LTE coex is enabled and 2.4GHz is selected */ 4482 if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) && 4483 (band_end_ch == CHAN_ENUM_14)) { 4484 /* Set 2.4GHz upper limit to channel 9 for LTE COEX */ 4485 band_end_ch = CHAN_ENUM_9; 4486 } 4487 4488 /* Allocate the max number of channel supported */ 4489 list = (uint8_t *) qdf_mem_malloc(NUM_5GHZ_CHANNELS + 4490 NUM_24GHZ_CHANNELS); 4491 if (NULL == list) { 4492 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4493 FL("Unable to allocate channel list")); 4494 *num_ch = 0; 4495 *ch_list = NULL; 4496 return QDF_STATUS_E_NOMEM; 4497 } 4498 4499 /* Search for the Active channels in the given range */ 4500 ch_count = 0; 4501 for (loop_count = band_start_ch; loop_count <= band_end_ch; 4502 loop_count++) { 4503 /* go to next channel if rf_channel is out of range */ 4504 if ((start_ch_num > CDS_CHANNEL_NUM(loop_count)) || 4505 (end_ch_num < CDS_CHANNEL_NUM(loop_count))) 4506 continue; 4507 /* 4508 * go to next channel if none of these condition pass 4509 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE 4510 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE 4511 */ 4512 if (!(((eSAP_TRUE == mac_ctx->scan.fEnableDFSChnlScan) && 4513 CDS_CHANNEL_STATE(loop_count)) || 4514 ((eSAP_FALSE == mac_ctx->scan.fEnableDFSChnlScan) && 4515 (CHANNEL_STATE_ENABLE == 4516 CDS_CHANNEL_STATE(loop_count))))) 4517 continue; 4518 4519 #ifdef FEATURE_WLAN_CH_AVOID 4520 for (i = 0; i < NUM_CHANNELS; i++) { 4521 if ((safe_channels[i].channelNumber == 4522 CDS_CHANNEL_NUM(loop_count))) { 4523 /* Check if channel is safe */ 4524 if (true == safe_channels[i].isSafe) { 4525 #endif 4526 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 4527 uint8_t ch; 4528 ch = CDS_CHANNEL_NUM(loop_count); 4529 if ((sap_ctx->acs_cfg->skip_scan_status == 4530 eSAP_DO_PAR_ACS_SCAN)) { 4531 if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch && 4532 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) || 4533 (ch >= sap_ctx->acs_cfg->skip_scan_range2_stch && 4534 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) { 4535 list[ch_count] = 4536 CDS_CHANNEL_NUM(loop_count); 4537 ch_count++; 4538 QDF_TRACE(QDF_MODULE_ID_SAP, 4539 QDF_TRACE_LEVEL_INFO, 4540 FL("%d %d added to ACS ch range"), 4541 ch_count, ch); 4542 } else { 4543 QDF_TRACE(QDF_MODULE_ID_SAP, 4544 QDF_TRACE_LEVEL_INFO_HIGH, 4545 FL("%d %d skipped from ACS ch range"), 4546 ch_count, ch); 4547 } 4548 } else { 4549 list[ch_count] = 4550 CDS_CHANNEL_NUM(loop_count); 4551 ch_count++; 4552 QDF_TRACE(QDF_MODULE_ID_SAP, 4553 QDF_TRACE_LEVEL_INFO, 4554 FL("%d %d added to ACS ch range"), 4555 ch_count, ch); 4556 } 4557 #else 4558 list[ch_count] = CDS_CHANNEL_NUM(loop_count); 4559 ch_count++; 4560 #endif 4561 #ifdef FEATURE_WLAN_CH_AVOID 4562 } 4563 break; 4564 } 4565 } 4566 #endif 4567 } 4568 if (0 == ch_count) { 4569 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4570 FL("No active channels present for the current region")); 4571 /* 4572 * LTE COEX: channel range outside the restricted 2.4GHz 4573 * band limits 4574 */ 4575 if (en_lte_coex && (start_ch_num > band_end_ch)) 4576 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 4577 FL("SAP can't be started as due to LTE COEX")); 4578 } 4579 4580 /* return the channel list and number of channels to scan */ 4581 *num_ch = ch_count; 4582 if (ch_count != 0) { 4583 *ch_list = list; 4584 } else { 4585 *ch_list = NULL; 4586 qdf_mem_free(list); 4587 } 4588 4589 for (loop_count = 0; loop_count < ch_count; loop_count++) { 4590 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 4591 FL("channel number: %d"), list[loop_count]); 4592 } 4593 return QDF_STATUS_SUCCESS; 4594 } 4595 #endif 4596 4597 /* 4598 * Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] 4599 * available channels in the current regulatory domain. 4600 */ 4601 static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext) 4602 { 4603 uint8_t count = 0; 4604 int i; 4605 struct sir_pcl_list pcl; 4606 QDF_STATUS status; 4607 enum channel_state ch_state; 4608 pcl.pcl_len = 0; 4609 if (NULL == sapContext) { 4610 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4611 "Invalid sapContext pointer on sap_get_channel_list"); 4612 return QDF_STATUS_E_FAULT; 4613 } 4614 4615 if (sapContext->SapAllChnlList.channelList) { 4616 qdf_mem_free(sapContext->SapAllChnlList.channelList); 4617 sapContext->SapAllChnlList.channelList = NULL; 4618 } 4619 4620 sapContext->SapAllChnlList.channelList = 4621 (tChannelInfo *) qdf_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN * 4622 sizeof(tChannelInfo)); 4623 if (NULL == sapContext->SapAllChnlList.channelList) { 4624 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4625 " Memory Allocation failed sap_get_channel_list"); 4626 return QDF_STATUS_E_NOMEM; 4627 } 4628 4629 status = cds_get_pcl_for_existing_conn(CDS_SAP_MODE, 4630 pcl.pcl_list, &pcl.pcl_len, 4631 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); 4632 if (status != QDF_STATUS_SUCCESS) { 4633 cds_err("Get PCL failed"); 4634 return status; 4635 } 4636 for (i = 0; i <= pcl.pcl_len; i++) { 4637 if (CDS_IS_CHANNEL_5GHZ(pcl.pcl_list[i])) { 4638 ch_state = cds_get_channel_state(pcl.pcl_list[i]); 4639 if (!(ch_state == CHANNEL_STATE_ENABLE || 4640 ch_state == CHANNEL_STATE_DFS)) 4641 continue; 4642 sapContext->SapAllChnlList.channelList[count].channel = 4643 pcl.pcl_list[i]; 4644 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 4645 "%s[%d] CHANNEL = %d", __func__, __LINE__, 4646 pcl.pcl_list[i]); 4647 sapContext->SapAllChnlList.channelList[count].valid = 4648 true; 4649 count++; 4650 } 4651 } 4652 4653 sapContext->SapAllChnlList.numChannel = count; 4654 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 4655 "%s[%d] NUMBER OF CHANNELS count = %d" 4656 "sapContext->SapAllChnlList.numChannel = %d", 4657 __func__, __LINE__, count, 4658 sapContext->SapAllChnlList.numChannel); 4659 return QDF_STATUS_SUCCESS; 4660 } 4661 4662 /* 4663 * This function randomly selects the channel to switch after the detection 4664 * of radar 4665 * param sapContext - sap context 4666 * dfs_event - Dfs information from DFS 4667 * return - channel to which AP wishes to switch 4668 */ 4669 uint8_t sap_indicate_radar(ptSapContext sapContext, 4670 tSirSmeDfsEventInd *dfs_event) 4671 { 4672 uint8_t target_channel = 0; 4673 tHalHandle hHal; 4674 tpAniSirGlobal pMac; 4675 4676 if (NULL == sapContext || NULL == dfs_event) { 4677 /* Invalid sap context of dfs event passed */ 4678 return 0; 4679 } 4680 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 4681 4682 if (NULL == hHal) { 4683 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4684 "In %s invalid hHal", __func__); 4685 return 0; 4686 } 4687 pMac = PMAC_STRUCT(hHal); 4688 4689 if (!dfs_event->dfs_radar_status) { 4690 /*dfs status does not indicate a radar on the channel-- False Alarm */ 4691 return 0; 4692 } 4693 4694 /* 4695 * SAP needs to generate Channel Switch IE 4696 * if the radar is found in the STARTED state 4697 */ 4698 if (eSAP_STARTED == sapContext->sapsMachine) 4699 pMac->sap.SapDfsInfo.csaIERequired = eSAP_TRUE; 4700 4701 if (sapContext->csr_roamProfile.disableDFSChSwitch) { 4702 return sapContext->channel; 4703 } 4704 4705 /* set the Radar Found flag in SapDfsInfo */ 4706 pMac->sap.SapDfsInfo.sap_radar_found_status = true; 4707 4708 if (dfs_event->chan_list.nchannels > SIR_DFS_MAX_20M_SUB_CH) { 4709 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 4710 FL("nchannels >SIR_DFS_MAX_20M_SUB_CH so resetting")); 4711 dfs_event->chan_list.nchannels = SIR_DFS_MAX_20M_SUB_CH; 4712 } 4713 4714 sap_mark_dfs_channels(sapContext, dfs_event->chan_list.channels, 4715 dfs_event->chan_list.nchannels, 4716 cds_get_monotonic_boottime()); 4717 4718 if (sapContext->chan_before_pre_cac) { 4719 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 4720 FL("sapdfs: set chan before pre cac %d as target chan"), 4721 sapContext->chan_before_pre_cac); 4722 return sapContext->chan_before_pre_cac; 4723 } 4724 4725 /* 4726 * (1) skip static turbo channel as it will require STA to be in 4727 * static turbo to work. 4728 * (2) skip channel which's marked with radar detction 4729 * (3) WAR: we allow user to config not to use any DFS channel 4730 * (4) When we pick a channel, skip excluded 11D channels 4731 * (5) Create the available channel list with the above rules 4732 */ 4733 4734 target_channel = sap_random_channel_sel(sapContext); 4735 if (0 == target_channel) { 4736 sap_signal_hdd_event(sapContext, NULL, 4737 eSAP_DFS_NO_AVAILABLE_CHANNEL, 4738 (void *) eSAP_STATUS_SUCCESS); 4739 } 4740 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 4741 FL("sapdfs: New selected target channel is [%d]"), 4742 target_channel); 4743 return target_channel; 4744 } 4745 4746 /* 4747 * CAC timer callback function. 4748 * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm(). 4749 */ 4750 void sap_dfs_cac_timer_callback(void *data) 4751 { 4752 ptSapContext sapContext; 4753 tWLAN_SAPEvent sapEvent; 4754 tHalHandle hHal = (tHalHandle) data; 4755 tpAniSirGlobal pMac; 4756 4757 if (NULL == hHal) { 4758 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4759 "In %s invalid hHal", __func__); 4760 return; 4761 } 4762 pMac = PMAC_STRUCT(hHal); 4763 sapContext = sap_find_cac_wait_session(hHal); 4764 if (NULL == sapContext) { 4765 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4766 "%s: no SAP contexts in wait state", __func__); 4767 return; 4768 } 4769 4770 /* 4771 * SAP may not be in CAC wait state, when the timer runs out. 4772 * if following flag is set, then timer is in initialized state, 4773 * destroy timer here. 4774 */ 4775 if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) { 4776 qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 4777 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 4778 } 4779 4780 /* 4781 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm 4782 */ 4783 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 4784 "sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%p]", 4785 sapContext->channel, sapContext); 4786 4787 sapEvent.event = eSAP_DFS_CHANNEL_CAC_END; 4788 sapEvent.params = 0; 4789 sapEvent.u1 = 0; 4790 sapEvent.u2 = 0; 4791 4792 sap_fsm(sapContext, &sapEvent); 4793 } 4794 4795 /* 4796 * Function to stop the DFS CAC Timer 4797 */ 4798 static int sap_stop_dfs_cac_timer(ptSapContext sapContext) 4799 { 4800 tHalHandle hHal; 4801 tpAniSirGlobal pMac; 4802 if (sapContext == NULL) 4803 return 0; 4804 4805 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 4806 if (NULL == hHal) { 4807 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4808 "In %s invalid hHal", __func__); 4809 return 0; 4810 } 4811 pMac = PMAC_STRUCT(hHal); 4812 4813 if (QDF_TIMER_STATE_RUNNING != 4814 qdf_mc_timer_get_current_state(&pMac->sap.SapDfsInfo. 4815 sap_dfs_cac_timer)) { 4816 return 0; 4817 } 4818 4819 qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 4820 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 4821 qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 4822 4823 return 0; 4824 } 4825 4826 4827 /** 4828 * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding. 4829 * @sap_context: SAP context 4830 * 4831 * Check if the current SAP operating channel is bonded to weather radar 4832 * channel in ETSI domain. 4833 * 4834 * Return: True if bonded to weather channel in ETSI 4835 */ 4836 static bool 4837 sap_is_channel_bonding_etsi_weather_channel(ptSapContext sap_context) 4838 { 4839 if (IS_CH_BONDING_WITH_WEATHER_CH(sap_context->channel) && 4840 (sap_context->ch_params.ch_width != CH_WIDTH_20MHZ)) 4841 return true; 4842 4843 return false; 4844 } 4845 4846 /* 4847 * Function to start the DFS CAC Timer 4848 * when SAP is started on a DFS channel 4849 */ 4850 int sap_start_dfs_cac_timer(ptSapContext sapContext) 4851 { 4852 QDF_STATUS status; 4853 uint32_t cacTimeOut; 4854 tHalHandle hHal = NULL; 4855 tpAniSirGlobal pMac = NULL; 4856 uint8_t dfs_region; 4857 4858 if (sapContext == NULL) { 4859 return 0; 4860 } 4861 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 4862 4863 if (NULL == hHal) { 4864 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4865 "In %s invalid hHal", __func__); 4866 return 0; 4867 } 4868 pMac = PMAC_STRUCT(hHal); 4869 4870 if (pMac->sap.SapDfsInfo.ignore_cac) { 4871 /* 4872 * If User has set to ignore the CAC 4873 * so, continue without CAC Timer. 4874 */ 4875 return 2; 4876 } 4877 cacTimeOut = DEFAULT_CAC_TIMEOUT; 4878 4879 cds_get_dfs_region(&dfs_region); 4880 4881 if ((dfs_region == DFS_ETSI_REGION) 4882 && ((IS_ETSI_WEATHER_CH(sapContext->channel)) || 4883 (sap_is_channel_bonding_etsi_weather_channel(sapContext)))) { 4884 cacTimeOut = ETSI_WEATHER_CH_CAC_TIMEOUT; 4885 } 4886 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 4887 "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH - %d, CAC TIMEOUT - %d sec", 4888 sapContext->channel, cacTimeOut / 1000); 4889 4890 qdf_mc_timer_init(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer, 4891 QDF_TIMER_TYPE_SW, 4892 sap_dfs_cac_timer_callback, (void *) hHal); 4893 4894 /*Start the CAC timer */ 4895 status = 4896 qdf_mc_timer_start(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer, 4897 cacTimeOut); 4898 if (status == QDF_STATUS_SUCCESS) { 4899 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = true; 4900 return 1; 4901 } else { 4902 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 4903 qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 4904 return 0; 4905 } 4906 } 4907 4908 /* 4909 * This function initializes the NOL list 4910 * parameters required to track the radar 4911 * found DFS channels in the current Reg. Domain . 4912 */ 4913 QDF_STATUS sap_init_dfs_channel_nol_list(ptSapContext sapContext) 4914 { 4915 uint8_t count = 0; 4916 int i; 4917 bool bFound = false; 4918 tHalHandle hHal; 4919 tpAniSirGlobal pMac; 4920 4921 if (NULL == sapContext) { 4922 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4923 "Invalid sapContext pointer on sap_init_dfs_channel_nol_list"); 4924 return QDF_STATUS_E_FAULT; 4925 } 4926 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 4927 4928 if (NULL == hHal) { 4929 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4930 "In %s invalid hHal", __func__); 4931 return QDF_STATUS_E_FAULT; 4932 } 4933 pMac = PMAC_STRUCT(hHal); 4934 4935 /* to indicate hdd to get cnss dfs nol */ 4936 if (QDF_STATUS_SUCCESS == sap_signal_hdd_event(sapContext, NULL, 4937 eSAP_DFS_NOL_GET, 4938 (void *) 4939 eSAP_STATUS_SUCCESS)) { 4940 bFound = true; 4941 } 4942 4943 for (i = CHAN_ENUM_36; i <= CHAN_ENUM_165; i++) { 4944 if (CDS_CHANNEL_STATE(i) == CHANNEL_STATE_DFS) { 4945 /* if dfs nol is not found, initialize it */ 4946 if (!bFound) { 4947 pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] 4948 .dfs_channel_number = 4949 CDS_CHANNEL_NUM(i); 4950 4951 QDF_TRACE(QDF_MODULE_ID_SAP, 4952 QDF_TRACE_LEVEL_INFO_LOW, 4953 "%s: CHANNEL = %d", __func__, 4954 pMac->sap.SapDfsInfo. 4955 sapDfsChannelNolList[count]. 4956 dfs_channel_number); 4957 4958 pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] 4959 .radar_status_flag = 4960 eSAP_DFS_CHANNEL_USABLE; 4961 pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] 4962 .radar_found_timestamp = 0; 4963 } 4964 count++; 4965 } 4966 } 4967 4968 pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels = count; 4969 4970 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 4971 "%s[%d] NUMBER OF DFS CHANNELS = %d", 4972 __func__, __LINE__, 4973 pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels); 4974 4975 return QDF_STATUS_SUCCESS; 4976 } 4977 4978 /* 4979 * This function will calculate how many interfaces 4980 * have sap persona and returns total number of sap persona. 4981 */ 4982 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal) 4983 { 4984 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 4985 uint8_t intf = 0; 4986 uint8_t intf_count = 0; 4987 4988 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 4989 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 4990 || 4991 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 4992 && pMac->sap.sapCtxList[intf].pSapContext != NULL) { 4993 intf_count++; 4994 } 4995 } 4996 return intf_count; 4997 } 4998 4999 /* 5000 * This function will find the concurrent sap context apart from 5001 * passed sap context and return its channel change ready status 5002 */ 5003 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal, 5004 ptSapContext sapContext) 5005 { 5006 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 5007 ptSapContext pSapContext; 5008 uint8_t intf = 0; 5009 5010 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 5011 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 5012 || 5013 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 5014 && pMac->sap.sapCtxList[intf].pSapContext != NULL) { 5015 pSapContext = 5016 (ptSapContext) pMac->sap.sapCtxList[intf]. 5017 pSapContext; 5018 if (pSapContext == sapContext) { 5019 QDF_TRACE(QDF_MODULE_ID_SAP, 5020 QDF_TRACE_LEVEL_ERROR, 5021 FL("sapCtx matched [%p]"), 5022 sapContext); 5023 continue; 5024 } else { 5025 QDF_TRACE(QDF_MODULE_ID_SAP, 5026 QDF_TRACE_LEVEL_ERROR, 5027 FL 5028 ("concurrent sapCtx[%p] didn't matche with [%p]"), 5029 pSapContext, sapContext); 5030 return pSapContext->is_sap_ready_for_chnl_chng; 5031 } 5032 } 5033 } 5034 return false; 5035 } 5036