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, 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 enum dfs_region dfs_region; 1257 1258 if (NULL == hal) { 1259 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1260 FL("hal pointer NULL")); 1261 return 0; 1262 } 1263 1264 mac_ctx = PMAC_STRUCT(hal); 1265 if (NULL == mac_ctx) { 1266 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1267 FL("mac_ctx pointer NULL")); 1268 return 0; 1269 } 1270 1271 preferred_location = 1272 mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location; 1273 cds_get_dfs_region(&dfs_region); 1274 /* loop to check ACS range or NOL channels */ 1275 num_valid_ch = sap_all_ch->numChannel; 1276 for (i = 0; i < sap_all_ch->numChannel; i++) { 1277 ch_id = sap_all_ch->channelList[i].channel; 1278 1279 /* 1280 * IN MKK DFS REGION CHECK IF THE FOLLOWING TWO 1281 * TWO RULES APPLY AND FILTER THE AVAILABLE CHANNELS 1282 * ACCORDINGLY. 1283 * 1284 * 1. If we are operating in Japan regulatory domain 1285 * Check if Japan W53 Channel operation is NOT 1286 * allowed and if its not allowed then mark all the 1287 * W53 channels as Invalid. 1288 * 1289 * 2. If we are operating in Japan regulatory domain 1290 * Check if channel switch between Indoor/Outdoor 1291 * is allowed. If it is not allowed then limit 1292 * the avaiable channels to Indoor or Outdoor 1293 * channels only based up on the SAP Channel location 1294 * indicated by "sap_operating_channel_location" param. 1295 */ 1296 if (DFS_MKK_REGION == dfs_region) { 1297 /* 1298 * Check for JAPAN W53 Channel operation capability 1299 */ 1300 if (true == sap_dfs_is_w53_invalid(hal, ch_id)) { 1301 QDF_TRACE(QDF_MODULE_ID_SAP, 1302 QDF_TRACE_LEVEL_INFO_LOW, 1303 FL("index:%d, Channel=%d Invalid,Japan W53 Disabled"), 1304 i, ch_id); 1305 sap_all_ch->channelList[i].valid = false; 1306 num_valid_ch--; 1307 continue; 1308 } 1309 1310 /* 1311 * If SAP's preferred channel location is Indoor 1312 * then set all the outdoor channels in the domain 1313 * to invalid.If the preferred channel location is 1314 * outdoor then set all the Indoor channels in the 1315 * domain to Invalid. 1316 */ 1317 if (false == 1318 sap_dfs_is_channel_in_preferred_location(hal, 1319 ch_id)) { 1320 QDF_TRACE(QDF_MODULE_ID_SAP, 1321 QDF_TRACE_LEVEL_INFO_LOW, 1322 FL("CHAN=%d is invalid,preferred Channel Location %d Only"), 1323 ch_id, preferred_location); 1324 sap_all_ch->channelList[i].valid = false; 1325 num_valid_ch--; 1326 continue; 1327 } 1328 } 1329 1330 if (cds_get_channel_state(ch_id) == CHANNEL_STATE_DFS) { 1331 is_ch_nol = sap_dfs_is_channel_in_nol_list(sap_ctx, 1332 ch_id, PHY_SINGLE_CHANNEL_CENTERED); 1333 if (true == is_ch_nol) { 1334 /* 1335 * Mark this channel invalid since it is still 1336 * in DFS Non-Occupancy-Period which is 30 mins. 1337 */ 1338 QDF_TRACE(QDF_MODULE_ID_SAP, 1339 QDF_TRACE_LEVEL_INFO_LOW, 1340 FL("index: %d, Channel = %d Present in NOL LIST"), 1341 i, ch_id); 1342 sap_all_ch->channelList[i].valid = false; 1343 num_valid_ch--; 1344 continue; 1345 } 1346 } 1347 1348 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 1349 /* avoid ch on which another MDM AP in MCC mode is detected */ 1350 if (mac_ctx->sap.sap_channel_avoidance 1351 && sap_ctx->sap_detected_avoid_ch_ie.present) { 1352 if (sap_check_in_avoid_ch_list(sap_ctx, ch_id)) { 1353 QDF_TRACE(QDF_MODULE_ID_SAP, 1354 QDF_TRACE_LEVEL_INFO_LOW, 1355 FL("index: %d, Channel = %d, avoided due to presence of another AP+AP MCC device in same channel."), 1356 i, ch_id); 1357 sap_all_ch->channelList[i].valid = false; 1358 } 1359 } 1360 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 1361 1362 /* check if the channel is within ACS channel range */ 1363 is_out_of_range = sap_acs_channel_check(sap_ctx, ch_id); 1364 if (true == is_out_of_range) { 1365 /* 1366 * mark this channel invalid since it is out of ACS 1367 * channel range 1368 */ 1369 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1370 FL("index: %d, Channel = %d out of ACS channel range"), 1371 i, ch_id); 1372 sap_all_ch->channelList[i].valid = false; 1373 num_valid_ch--; 1374 continue; 1375 } 1376 } /* end of check for NOL or ACS channels */ 1377 return num_valid_ch; 1378 } 1379 1380 /** 1381 * select_rand_from_lst() - selects random channel from given list 1382 * @mac_ctx: mac context pointer 1383 * @ch_lst: channel list 1384 * @num_ch: number of channels 1385 * 1386 * Return: new target channel randomly selected 1387 */ 1388 static uint8_t select_rand_from_lst(tpAniSirGlobal mac_ctx, uint8_t *ch_lst, 1389 uint8_t num_ch) 1390 { 1391 uint32_t rand_byte = 0; 1392 uint8_t i, target_channel, non_dfs_num_ch = 0, dfs_num_ch = 0; 1393 uint8_t dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; 1394 uint8_t non_dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; 1395 if (num_ch) { 1396 for (i = 0; i < num_ch; i++) { 1397 if (CDS_IS_DFS_CH(ch_lst[i])) 1398 dfs_ch[dfs_num_ch++] = ch_lst[i]; 1399 else 1400 non_dfs_ch[non_dfs_num_ch++] = ch_lst[i]; 1401 } 1402 } else { 1403 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1404 FL("No target channel found")); 1405 return 0; 1406 } 1407 1408 cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); 1409 1410 /* Give preference to non-DFS channel */ 1411 if (!mac_ctx->f_prefer_non_dfs_on_radar) { 1412 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch; 1413 target_channel = ch_lst[i]; 1414 } else if (non_dfs_num_ch) { 1415 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1416 non_dfs_num_ch; 1417 target_channel = non_dfs_ch[i]; 1418 } else { 1419 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % dfs_num_ch; 1420 target_channel = dfs_ch[i]; 1421 } 1422 1423 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1424 FL("sapdfs: New Channel width = %d"), 1425 mac_ctx->sap.SapDfsInfo.new_chanWidth); 1426 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1427 FL("sapdfs: target_channel = %d"), target_channel); 1428 1429 return target_channel; 1430 } 1431 1432 /** 1433 * sap_find_ch_wh_fallback() - find given channel width from given list of 1434 * channels 1435 * @mac_ctx: mac context pointer 1436 * @ch_wd: channel width to find 1437 * @ch_lst: list of channels 1438 * @num_ch: number of channels 1439 * 1440 * This function tries to find given channel width and returns new target ch. 1441 * If not found updates ch_wd to next lower channel width. 1442 * 1443 * Return: new target channel if successful, 0 otherwise 1444 */ 1445 static uint8_t sap_find_ch_wh_fallback(tpAniSirGlobal mac_ctx, 1446 enum phy_ch_width *ch_wd, 1447 uint8_t *ch_lst, 1448 uint8_t num_ch) 1449 { 1450 bool flag = false; 1451 uint32_t rand_byte = 0; 1452 chan_bonding_bitmap ch_map = { { {0} } }; 1453 uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0; 1454 uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; 1455 uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; 1456 1457 /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ 1458 ch_map.chanBondingSet[0].startChannel = 36; 1459 ch_map.chanBondingSet[1].startChannel = 52; 1460 ch_map.chanBondingSet[2].startChannel = 100; 1461 ch_map.chanBondingSet[3].startChannel = 116; 1462 ch_map.chanBondingSet[4].startChannel = 132; 1463 ch_map.chanBondingSet[5].startChannel = 149; 1464 1465 /* now loop through leakage free list */ 1466 for (i = 0; i < num_ch; i++) { 1467 /* add tmp ch to bitmap */ 1468 if (ch_lst[i] == 0) 1469 continue; 1470 1471 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 1472 FL("sapdfs: Channel=%d added to bitmap"), 1473 ch_lst[i]); 1474 sap_set_bitmap(&ch_map, ch_lst[i]); 1475 } 1476 1477 /* populate available channel list from bitmap */ 1478 final_cnt = sap_populate_available_channels(&ch_map, *ch_wd, final_lst); 1479 /* If no valid ch bonding found, fallback */ 1480 if (final_cnt == 0) { 1481 if ((*ch_wd == CH_WIDTH_160MHZ) || 1482 (*ch_wd == CH_WIDTH_80P80MHZ) || 1483 (*ch_wd == CH_WIDTH_80MHZ)) { 1484 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 1485 FL("sapdfs:Changing chanWidth from [%d] to 40Mhz"), 1486 *ch_wd); 1487 *ch_wd = CH_WIDTH_40MHZ; 1488 } else if (*ch_wd == CH_WIDTH_40MHZ) { 1489 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 1490 FL("sapdfs:No 40MHz cb found, falling to 20MHz")); 1491 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 1492 FL("sapdfs:Changing chanWidth from [%d] to [%d]"), 1493 *ch_wd, CH_WIDTH_20MHZ); 1494 *ch_wd = CH_WIDTH_20MHZ; 1495 } 1496 return 0; 1497 } 1498 1499 /* ch count should be > 8 to switch new channel in 160Mhz band */ 1500 if (((*ch_wd == CH_WIDTH_160MHZ) || (*ch_wd == CH_WIDTH_80P80MHZ)) && 1501 (final_cnt < SIR_DFS_MAX_20M_SUB_CH)) { 1502 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 1503 FL("sapdfs:Changing chanWidth from [%d] to [%d]"), 1504 *ch_wd, CH_WIDTH_80MHZ); 1505 *ch_wd = CH_WIDTH_80MHZ; 1506 return 0; 1507 } 1508 if (*ch_wd == CH_WIDTH_160MHZ) { 1509 /* 1510 * NA supports only 2 blocks for 160Mhz bandwidth i.e 36-64 & 1511 * 100-128 and all the channels in these blocks are continuous 1512 * and seperated by 4Mhz. 1513 */ 1514 for (i = 1; ((i < final_cnt)); i++) { 1515 if ((final_lst[i] - final_lst[i-1]) == 4) 1516 count++; 1517 else 1518 count = 0; 1519 if (count == SIR_DFS_MAX_20M_SUB_CH - 1) { 1520 flag = true; 1521 new_160_start_ch = final_lst[i-7]; 1522 break; 1523 } 1524 } 1525 } else if (*ch_wd == CH_WIDTH_80P80MHZ) { 1526 flag = true; 1527 } 1528 if ((flag == false) && (*ch_wd > CH_WIDTH_80MHZ)) { 1529 *ch_wd = CH_WIDTH_80MHZ; 1530 return 0; 1531 } 1532 1533 if (*ch_wd == CH_WIDTH_160MHZ) { 1534 cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); 1535 rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) 1536 % SIR_DFS_MAX_20M_SUB_CH; 1537 target_channel = new_160_start_ch + (rand_byte * 4); 1538 } else if (*ch_wd == CH_WIDTH_80P80MHZ) { 1539 cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); 1540 index = (rand_byte + qdf_mc_timer_get_system_ticks()) % 1541 final_cnt; 1542 target_channel = final_lst[index]; 1543 index -= (index % 4); 1544 primary_seg_start_ch = final_lst[index]; 1545 1546 /* reset channels associate with primary 80Mhz */ 1547 for (i = 0; i < 4; i++) 1548 final_lst[i + index] = 0; 1549 /* select and calculate center freq for secondary segement */ 1550 for (i = 0; i < final_cnt / 4; i++) { 1551 if (final_lst[i * 4] && 1552 (abs(primary_seg_start_ch - final_lst[i * 4]) > 1553 (SIR_DFS_MAX_20M_SUB_CH * 2))) { 1554 sec_seg_ch = final_lst[i * 4] + 1555 SIR_80MHZ_START_CENTER_CH_DIFF; 1556 break; 1557 } 1558 } 1559 if (!sec_seg_ch && (final_cnt == SIR_DFS_MAX_20M_SUB_CH)) 1560 *ch_wd = CH_WIDTH_160MHZ; 1561 else if (!sec_seg_ch) 1562 *ch_wd = CH_WIDTH_80MHZ; 1563 1564 mac_ctx->sap.SapDfsInfo.new_ch_params.center_freq_seg1 1565 = sec_seg_ch; 1566 1567 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1568 FL("sapdfs: New Center Freq Seg1 = %d"), sec_seg_ch); 1569 } else { 1570 target_channel = select_rand_from_lst(mac_ctx, final_lst, 1571 final_cnt); 1572 } 1573 return target_channel; 1574 } 1575 1576 /** 1577 * sap_random_channel_sel() - This function randomly pick up an available 1578 * channel 1579 * @sap_ctx: sap context. 1580 * 1581 * This function first eliminates invalid channel, then selects random channel 1582 * using following algorithm: 1583 * PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules 1584 * PASS: 2 - now mark channels that will leak into NOL 1585 * PASS: 3 - from leakage_adjusted_lst, either select random channel (for 20MHz) 1586 * or find given channel width possible. if not found fallback to 1587 * lower channel width and try again. once given channel width found 1588 * use random channel from give possibilities. 1589 * Return: channel number picked 1590 */ 1591 static uint8_t sap_random_channel_sel(ptSapContext sap_ctx) 1592 { 1593 uint8_t j = 0, i = 0, final_cnt = 0, target_channel = 0; 1594 /* count and ch list after applying all rules */ 1595 uint8_t rule_adjusted_cnt, *rule_adjusted_lst; 1596 /* ch list after invalidating channels leaking into NOL */ 1597 uint8_t *leakage_adjusted_lst; 1598 /* final list of channel from which random channel will be selected */ 1599 uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; 1600 tAll5GChannelList *all_ch = &sap_ctx->SapAllChnlList; 1601 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 1602 tpAniSirGlobal mac_ctx; 1603 /* channel width for current iteration */ 1604 enum phy_ch_width ch_wd; 1605 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 1606 tSapDfsNolInfo *nol; 1607 #endif 1608 1609 if (NULL == hal) { 1610 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1611 FL("invalid hal")); 1612 return 0; 1613 } 1614 1615 mac_ctx = PMAC_STRUCT(hal); 1616 if (NULL == mac_ctx) { 1617 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1618 FL("invalid mac_ctx")); 1619 return 0; 1620 } 1621 1622 /* 1623 * Retrieve the original one and store it. 1624 * use the stored original value when you call this function next time 1625 * so fall back mechanism always starts with original ini value. 1626 */ 1627 if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) { 1628 ch_wd = sap_ctx->ch_width_orig; 1629 mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd; 1630 } else { 1631 ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth; 1632 } 1633 1634 if (sap_get_5ghz_channel_list(sap_ctx)) { 1635 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1636 FL("Getting 5Ghz channel list failed")); 1637 return 0; 1638 } 1639 1640 /* PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules */ 1641 rule_adjusted_cnt = sap_apply_rules(sap_ctx); 1642 if (0 == rule_adjusted_cnt) { 1643 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1644 FL("No channels left after applying rules.")); 1645 return 0; 1646 } 1647 1648 /* this is list we get after applying all rules */ 1649 rule_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt); 1650 1651 /* list adjusted after leakage has been marked */ 1652 leakage_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt); 1653 if (rule_adjusted_lst == NULL || leakage_adjusted_lst == NULL) { 1654 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1655 FL("sapdfs: memory alloc failed")); 1656 qdf_mem_free(rule_adjusted_lst); 1657 qdf_mem_free(leakage_adjusted_lst); 1658 return 0; 1659 } 1660 1661 /* copy valid ch from sap_ctx->all_ch_lst into rule_adjusted_lst */ 1662 for (i = 0, j = 0; i < all_ch->numChannel; i++) { 1663 if (!all_ch->channelList[i].valid) 1664 continue; 1665 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1666 FL("sapdfs: Adding Channel = %d to temp List"), 1667 all_ch->channelList[i].channel); 1668 rule_adjusted_lst[j++] = all_ch->channelList[i].channel; 1669 } 1670 1671 /* 1672 * do - while loop for fallback mechanism. at each channel width this 1673 * will try to find channel bonding, if not fall back to lower ch width 1674 */ 1675 do { 1676 /* save rules adjusted lst */ 1677 qdf_mem_copy(leakage_adjusted_lst, rule_adjusted_lst, 1678 rule_adjusted_cnt); 1679 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 1680 nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList; 1681 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1682 FL("sapdfs: Processing tmp ch list against NOL.")); 1683 /* PASS: 2 - now mark channels that will leak into NOL */ 1684 if (sap_mark_leaking_ch(sap_ctx, ch_wd, nol, rule_adjusted_cnt, 1685 leakage_adjusted_lst) != QDF_STATUS_SUCCESS) { 1686 qdf_mem_free(rule_adjusted_lst); 1687 qdf_mem_free(leakage_adjusted_lst); 1688 return 0; 1689 } 1690 #endif 1691 if (ch_wd == CH_WIDTH_20MHZ) { 1692 /* 1693 * PASS: 3 - from leakage_adjusted_lst, prepare valid 1694 * ch list and use random number from that 1695 */ 1696 for (i = 0; i < rule_adjusted_cnt; i++) { 1697 if (leakage_adjusted_lst[i] == 0) 1698 continue; 1699 QDF_TRACE(QDF_MODULE_ID_SAP, 1700 QDF_TRACE_LEVEL_DEBUG, 1701 FL("sapdfs: Channel=%d added to available list"), 1702 leakage_adjusted_lst[i]); 1703 final_lst[final_cnt] = leakage_adjusted_lst[i]; 1704 final_cnt++; 1705 } 1706 target_channel = select_rand_from_lst(mac_ctx, 1707 final_lst, final_cnt); 1708 break; 1709 } 1710 1711 /* 1712 * PASS: 3 - following function will check from valid channels 1713 * left if given ch_wd can be supported. if not reduce ch_wd 1714 * (fallback), then continue with reduced ch_wd 1715 */ 1716 target_channel = sap_find_ch_wh_fallback(mac_ctx, &ch_wd, 1717 leakage_adjusted_lst, 1718 rule_adjusted_cnt); 1719 /* 1720 * if target channel is 0, no channel bonding was found 1721 * ch_wd would have been updated for fallback 1722 */ 1723 if (0 == target_channel) 1724 continue; 1725 else 1726 break; 1727 } while (true); 1728 1729 if (target_channel) 1730 mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_wd; 1731 1732 qdf_mem_free(rule_adjusted_lst); 1733 qdf_mem_free(leakage_adjusted_lst); 1734 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1735 FL("sapdfs: New Channel width = %d"), 1736 mac_ctx->sap.SapDfsInfo.new_chanWidth); 1737 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1738 FL("sapdfs: target_channel = %d"), 1739 target_channel); 1740 return target_channel; 1741 } 1742 1743 bool sap_acs_channel_check(ptSapContext sapContext, uint8_t channelNumber) 1744 { 1745 int i = 0; 1746 if (!sapContext->acs_cfg->acs_mode) 1747 return false; 1748 1749 if ((channelNumber >= sapContext->acs_cfg->start_ch) && 1750 (channelNumber <= sapContext->acs_cfg->end_ch)) { 1751 if (!sapContext->acs_cfg->ch_list) { 1752 return false; 1753 } else { 1754 for (i = 0; i < sapContext->acs_cfg->ch_list_count; i++) 1755 if (channelNumber == 1756 sapContext->acs_cfg->ch_list[i]) 1757 return false; 1758 } 1759 } 1760 return true; 1761 } 1762 1763 /** 1764 * sap_mark_dfs_channels() - to mark dfs channel 1765 * @sapContext: pointer sap context 1766 * @channels: list of channels 1767 * @numChannels: number of channels 1768 * @time: time 1769 * 1770 * Mark the channels in NOL with time and eSAP_DFS_CHANNEL_UNAVAILABLE 1771 * 1772 * Return: none 1773 */ 1774 void sap_mark_dfs_channels(ptSapContext sapContext, uint8_t *channels, 1775 uint8_t numChannels, uint64_t time) 1776 { 1777 int i, j; 1778 tSapDfsNolInfo *psapDfsChannelNolList = NULL; 1779 uint8_t nRegDomainDfsChannels; 1780 tHalHandle hHal; 1781 tpAniSirGlobal pMac; 1782 1783 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 1784 if (NULL == channels) 1785 return; 1786 if (NULL == hHal) { 1787 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1788 FL("invalid hHal")); 1789 return; 1790 } 1791 pMac = PMAC_STRUCT(hHal); 1792 if (NULL == pMac) { 1793 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1794 FL("invalid pMac")); 1795 return; 1796 } 1797 1798 /* 1799 * Mark the current channel on which Radar is found 1800 * in the NOL list as eSAP_DFS_CHANNEL_UNAVAILABLE. 1801 */ 1802 psapDfsChannelNolList = pMac->sap.SapDfsInfo.sapDfsChannelNolList; 1803 nRegDomainDfsChannels = 1804 pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; 1805 1806 for (i = 0; i < numChannels; i++) { 1807 for (j = 0; j <= nRegDomainDfsChannels; j++) { 1808 if (!(psapDfsChannelNolList[j].dfs_channel_number == 1809 channels[i])) 1810 continue; 1811 /* 1812 * If channel is already in NOL, don't update it again. 1813 * This is useful when marking bonding channels which 1814 * are already unavailable. 1815 */ 1816 if (psapDfsChannelNolList[j].radar_status_flag == 1817 eSAP_DFS_CHANNEL_UNAVAILABLE) { 1818 QDF_TRACE(QDF_MODULE_ID_SAP, 1819 QDF_TRACE_LEVEL_INFO_HIGH, 1820 FL("Channel=%d already in NOL"), 1821 channels[i]); 1822 continue; 1823 } 1824 /* 1825 * Capture the Radar Found timestamp on the 1826 * Current Channel in ms. 1827 */ 1828 psapDfsChannelNolList[j].radar_found_timestamp = time; 1829 /* Mark the Channel to be unavailble for next 30 mins */ 1830 psapDfsChannelNolList[j].radar_status_flag = 1831 eSAP_DFS_CHANNEL_UNAVAILABLE; 1832 1833 QDF_TRACE(QDF_MODULE_ID_SAP, 1834 QDF_TRACE_LEVEL_INFO_HIGH, 1835 FL("Channel=%d Added to NOL LIST"), 1836 channels[i]); 1837 } 1838 } 1839 } 1840 1841 /* 1842 * This Function is to get bonding channels from primary channel. 1843 * 1844 */ 1845 uint8_t sap_get_bonding_channels(ptSapContext sapContext, uint8_t channel, 1846 uint8_t *channels, uint8_t size, 1847 ePhyChanBondState chanBondState) 1848 { 1849 tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 1850 tpAniSirGlobal pMac; 1851 uint8_t numChannel; 1852 1853 if (channels == NULL) 1854 return 0; 1855 1856 if (size < MAX_BONDED_CHANNELS) 1857 return 0; 1858 1859 if (NULL != hHal) { 1860 pMac = PMAC_STRUCT(hHal); 1861 } else 1862 return 0; 1863 1864 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 1865 FL("cbmode: %d, channel: %d"), chanBondState, channel); 1866 1867 switch (chanBondState) { 1868 case PHY_SINGLE_CHANNEL_CENTERED: 1869 numChannel = 1; 1870 channels[0] = channel; 1871 break; 1872 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 1873 numChannel = 2; 1874 channels[0] = channel - 4; 1875 channels[1] = channel; 1876 break; 1877 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 1878 numChannel = 2; 1879 channels[0] = channel; 1880 channels[1] = channel + 4; 1881 break; 1882 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: 1883 numChannel = 4; 1884 channels[0] = channel; 1885 channels[1] = channel + 4; 1886 channels[2] = channel + 8; 1887 channels[3] = channel + 12; 1888 break; 1889 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: 1890 numChannel = 4; 1891 channels[0] = channel - 4; 1892 channels[1] = channel; 1893 channels[2] = channel + 4; 1894 channels[3] = channel + 8; 1895 break; 1896 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: 1897 numChannel = 4; 1898 channels[0] = channel - 8; 1899 channels[1] = channel - 4; 1900 channels[2] = channel; 1901 channels[3] = channel + 4; 1902 break; 1903 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: 1904 numChannel = 4; 1905 channels[0] = channel - 12; 1906 channels[1] = channel - 8; 1907 channels[2] = channel - 4; 1908 channels[3] = channel; 1909 break; 1910 default: 1911 numChannel = 1; 1912 channels[0] = channel; 1913 break; 1914 } 1915 1916 return numChannel; 1917 } 1918 1919 /** 1920 * sap_dfs_check_if_channel_avaialable() - Check if a channel is out of NOL 1921 * @nol: Pointer to the Non-Occupancy List. 1922 * 1923 * This function Checks if a given channel is available or 1924 * usable or unavailable based on the time lapse since the 1925 * last radar time stamp. 1926 * 1927 * Return: true if channel available or usable, false if unavailable. 1928 */ 1929 static bool sap_dfs_check_if_channel_avaialable(tSapDfsNolInfo *nol) 1930 { 1931 uint64_t time_since_last_radar, time_when_radar_found, current_time = 0; 1932 uint64_t max_jiffies; 1933 1934 if ((nol->radar_status_flag == eSAP_DFS_CHANNEL_USABLE) || 1935 (nol->radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE)) { 1936 /* 1937 * Allow SAP operation on this channel 1938 * either the DFS channel has not been used 1939 * for SAP operation or it is available for 1940 * SAP operation since it is past 1941 * Non-Occupancy-Period so, return false. 1942 */ 1943 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1944 FL("Chan=%d not in NOL,CHAN AVAILABLE"), 1945 nol->dfs_channel_number); 1946 return true; 1947 } else if (nol->radar_status_flag == eSAP_DFS_CHANNEL_UNAVAILABLE) { 1948 /* 1949 * If a DFS Channel is UNAVAILABLE then 1950 * check to see if it is past 1951 * Non-occupancy-period 1952 * of 30 minutes. If it is past 30 mins then 1953 * mark the channel as AVAILABLE and return 1954 * false as the channel is not anymore in 1955 * NON-Occupancy-Period. 1956 */ 1957 time_when_radar_found = nol->radar_found_timestamp; 1958 current_time = cds_get_monotonic_boottime(); 1959 if (current_time < time_when_radar_found) { 1960 /* cds_get_monotonic_boottime() can overflow. 1961 * Jiffies is initialized such that 32 bit jiffies 1962 * value wrap 5 minutes after boot so jiffies wrap bugs 1963 * show up earlier 1964 */ 1965 max_jiffies = (uint64_t)UINT_MAX * 1000; 1966 time_since_last_radar = (max_jiffies - 1967 time_when_radar_found) + (current_time); 1968 } else { 1969 time_since_last_radar = current_time - 1970 time_when_radar_found; 1971 } 1972 if (time_since_last_radar >= SAP_DFS_NON_OCCUPANCY_PERIOD) { 1973 nol->radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE; 1974 nol->radar_found_timestamp = 0; 1975 1976 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1977 FL("Chan=%d not in NOL, Channel AVAILABLE"), 1978 nol->dfs_channel_number); 1979 return true; 1980 } else { 1981 /* 1982 * Channel is not still available for 1983 * SAP operation so return true; As the 1984 * Channel is still in 1985 * Non-occupancy-Period. 1986 */ 1987 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1988 FL("Chan=%d in NOL, Channel UNAVAILBLE"), 1989 nol->dfs_channel_number); 1990 return false; 1991 } 1992 } else { 1993 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1994 FL("Invalid Radar Status Flag")); 1995 } 1996 return true; 1997 } 1998 1999 /** 2000 * sap_dfs_is_channel_in_nol_list() - given bonded channel is available 2001 * @sap_context: Handle to SAP context. 2002 * @channel_number: Channel on which availability should be checked. 2003 * @chan_bondState: The channel bonding mode of the passed channel. 2004 * 2005 * This function Checks if a given bonded channel is available or 2006 * usable for DFS operation. 2007 * 2008 * Return: false if channel is available, true if channel is in NOL. 2009 */ 2010 bool 2011 sap_dfs_is_channel_in_nol_list(ptSapContext sap_context, 2012 uint8_t channel_number, 2013 ePhyChanBondState chan_bondState) 2014 { 2015 int i, j; 2016 tHalHandle h_hal = CDS_GET_HAL_CB(sap_context->p_cds_gctx); 2017 tpAniSirGlobal mac_ctx; 2018 uint8_t channels[MAX_BONDED_CHANNELS]; 2019 uint8_t num_channels; 2020 tSapDfsNolInfo *nol; 2021 tSapDfsInfo *dfs_info; 2022 bool channel_available; 2023 2024 if (NULL == h_hal) { 2025 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2026 FL("invalid h_hal")); 2027 return false; 2028 } else { 2029 mac_ctx = PMAC_STRUCT(h_hal); 2030 } 2031 2032 dfs_info = &mac_ctx->sap.SapDfsInfo; 2033 if ((dfs_info->numCurrentRegDomainDfsChannels == 0) || 2034 (dfs_info->numCurrentRegDomainDfsChannels > 2035 NUM_5GHZ_CHANNELS)) { 2036 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 2037 FL("invalid dfs channel count %d"), 2038 dfs_info->numCurrentRegDomainDfsChannels); 2039 return false; 2040 } 2041 2042 /* get the bonded channels */ 2043 num_channels = sap_get_bonding_channels(sap_context, channel_number, 2044 channels, MAX_BONDED_CHANNELS, chan_bondState); 2045 2046 /* check for NOL, first on will break the loop */ 2047 for (j = 0; j < num_channels; j++) { 2048 for (i = 0; i < dfs_info->numCurrentRegDomainDfsChannels; i++) { 2049 nol = &dfs_info->sapDfsChannelNolList[i]; 2050 if (nol->dfs_channel_number != channels[j]) 2051 continue; 2052 2053 channel_available = 2054 sap_dfs_check_if_channel_avaialable(nol); 2055 2056 if (channel_available == false) 2057 break; 2058 2059 } /* loop for dfs channels */ 2060 2061 if (i < dfs_info->numCurrentRegDomainDfsChannels) 2062 break; 2063 2064 } /* loop for bonded channels */ 2065 2066 /* 2067 * if any of the channel is not available, mark all available channels 2068 * as unavailable with same time stamp. 2069 */ 2070 if (j < num_channels && 2071 i < dfs_info->numCurrentRegDomainDfsChannels) { 2072 if (num_channels > MAX_BONDED_CHANNELS) { 2073 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 2074 FL("num_channel>MAX_BONDED_CHANNEL, reset")); 2075 num_channels = MAX_BONDED_CHANNELS; 2076 } 2077 nol = &dfs_info->sapDfsChannelNolList[i]; 2078 sap_mark_dfs_channels(sap_context, channels, num_channels, 2079 nol->radar_found_timestamp); 2080 2081 /* set DFS-NOL back to keep it update-to-date in CNSS */ 2082 sap_signal_hdd_event(sap_context, NULL, eSAP_DFS_NOL_SET, 2083 (void *) eSAP_STATUS_SUCCESS); 2084 2085 return true; 2086 } 2087 2088 return false; 2089 } 2090 2091 /** 2092 * sap_goto_channel_sel - Function for initiating scan request for SME 2093 * @sap_context: Sap Context value. 2094 * @sap_event: State machine event 2095 * @sap_do_acs_pre_start_bss: true, if ACS scan is issued pre start BSS 2096 * false, if ACS scan is issued post start BSS. 2097 * @check_for_connection_update: true, check and wait for connection update 2098 * false, do not perform connection update 2099 * 2100 * Initiates sme scan for ACS to pick a channel. 2101 * 2102 * Return: The QDF_STATUS code associated with performing the operation. 2103 */ 2104 QDF_STATUS sap_goto_channel_sel(ptSapContext sap_context, 2105 ptWLAN_SAPEvent sap_event, 2106 bool sap_do_acs_pre_start_bss, 2107 bool check_for_connection_update) 2108 { 2109 2110 /* Initiate a SCAN request */ 2111 QDF_STATUS qdf_ret_status; 2112 /* To be initialised if scan is required */ 2113 tCsrScanRequest scan_request; 2114 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 2115 tpAniSirGlobal mac_ctx; 2116 2117 #ifdef SOFTAP_CHANNEL_RANGE 2118 uint8_t *channel_list = NULL; 2119 uint8_t num_of_channels = 0; 2120 #endif 2121 tHalHandle h_hal; 2122 uint8_t con_ch; 2123 2124 h_hal = cds_get_context(QDF_MODULE_ID_SME); 2125 if (NULL == h_hal) { 2126 /* we have a serious problem */ 2127 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 2128 FL("invalid h_hal")); 2129 return QDF_STATUS_E_FAULT; 2130 } 2131 2132 mac_ctx = PMAC_STRUCT(h_hal); 2133 if (NULL == mac_ctx) { 2134 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2135 FL("Invalid MAC context")); 2136 return QDF_STATUS_E_FAILURE; 2137 } 2138 2139 if (cds_concurrent_beaconing_sessions_running()) { 2140 con_ch = 2141 sme_get_concurrent_operation_channel(h_hal); 2142 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 2143 if (con_ch && sap_context->channel == AUTO_CHANNEL_SELECT) { 2144 sap_context->dfs_ch_disable = true; 2145 } else if (con_ch && sap_context->channel != con_ch && 2146 CDS_IS_DFS_CH(sap_context->channel)) { 2147 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 2148 FL("MCC DFS not supported in AP_AP Mode")); 2149 return QDF_STATUS_E_ABORTED; 2150 } 2151 #endif 2152 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 2153 if (sap_context->cc_switch_mode != 2154 QDF_MCC_TO_SCC_SWITCH_DISABLE) { 2155 con_ch = sme_check_concurrent_channel_overlap(h_hal, 2156 sap_context->channel, 2157 sap_context->csr_roamProfile.phyMode, 2158 sap_context->cc_switch_mode); 2159 if (con_ch) { 2160 QDF_TRACE(QDF_MODULE_ID_SAP, 2161 QDF_TRACE_LEVEL_ERROR, 2162 "%s: Override ch %d to %d due to CC Intf", 2163 __func__, sap_context->channel, con_ch); 2164 sap_context->channel = con_ch; 2165 cds_set_channel_params(sap_context->channel, 0, 2166 &sap_context->ch_params); 2167 } 2168 } 2169 #endif 2170 } 2171 2172 if (cds_get_concurrency_mode() == (QDF_STA_MASK | QDF_SAP_MASK)) { 2173 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 2174 if (sap_context->channel == AUTO_CHANNEL_SELECT) 2175 sap_context->dfs_ch_disable = true; 2176 else if (CDS_IS_DFS_CH(sap_context->channel)) { 2177 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 2178 FL("DFS not supported in STA_AP Mode")); 2179 return QDF_STATUS_E_ABORTED; 2180 } 2181 #endif 2182 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 2183 if (sap_context->cc_switch_mode != 2184 QDF_MCC_TO_SCC_SWITCH_DISABLE) { 2185 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2186 FL("check for overlap: chan:%d mode:%d"), 2187 sap_context->channel, 2188 sap_context->csr_roamProfile.phyMode); 2189 con_ch = sme_check_concurrent_channel_overlap(h_hal, 2190 sap_context->channel, 2191 sap_context->csr_roamProfile.phyMode, 2192 sap_context->cc_switch_mode); 2193 if (con_ch && !CDS_IS_DFS_CH(con_ch)) { 2194 QDF_TRACE(QDF_MODULE_ID_SAP, 2195 QDF_TRACE_LEVEL_ERROR, 2196 "%s: Override ch %d to %d due to CC Intf", 2197 __func__, sap_context->channel, con_ch); 2198 sap_context->channel = con_ch; 2199 cds_set_channel_params(sap_context->channel, 0, 2200 &sap_context->ch_params); 2201 } 2202 } 2203 #endif 2204 } 2205 2206 if (sap_context->channel == AUTO_CHANNEL_SELECT) { 2207 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2208 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2209 FL("%s skip_acs_status = %d "), __func__, 2210 sap_context->acs_cfg->skip_scan_status); 2211 if (sap_context->acs_cfg->skip_scan_status != 2212 eSAP_SKIP_ACS_SCAN) { 2213 #endif 2214 qdf_mem_zero(&scan_request, sizeof(scan_request)); 2215 2216 /* 2217 * Set scanType to Active scan. FW takes care of using passive 2218 * scan for DFS and active for non DFS channels. 2219 */ 2220 scan_request.scanType = eSIR_ACTIVE_SCAN; 2221 2222 /* Set min and max channel time to zero */ 2223 scan_request.minChnTime = 0; 2224 scan_request.maxChnTime = 0; 2225 2226 /* Set BSSType to default type */ 2227 scan_request.BSSType = eCSR_BSS_TYPE_ANY; 2228 2229 #ifndef SOFTAP_CHANNEL_RANGE 2230 /*Scan all the channels */ 2231 scan_request.ChannelInfo.num_of_channels = 0; 2232 2233 scan_request.ChannelInfo.ChannelList = NULL; 2234 2235 scan_request.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; 2236 /* eCSR_SCAN_REQUEST_11D_SCAN; */ 2237 2238 #else 2239 2240 sap_get_channel_list(sap_context, &channel_list, 2241 &num_of_channels); 2242 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2243 if (num_of_channels != 0) { 2244 #endif 2245 /*Scan the channels in the list */ 2246 scan_request.ChannelInfo.numOfChannels = 2247 num_of_channels; 2248 2249 scan_request.ChannelInfo.ChannelList = 2250 channel_list; 2251 2252 scan_request.requestType = 2253 eCSR_SCAN_SOFTAP_CHANNEL_RANGE; 2254 2255 sap_context->channelList = channel_list; 2256 2257 #endif 2258 /* Set requestType to Full scan */ 2259 2260 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2261 FL("calling sme_scan_request")); 2262 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2263 if (sap_context->acs_cfg->skip_scan_status == 2264 eSAP_DO_NEW_ACS_SCAN) 2265 #endif 2266 sme_scan_flush_result(h_hal); 2267 if (true == sap_do_acs_pre_start_bss) { 2268 /* 2269 * when ID == 0 11D scan/active scan with callback, 2270 * min-maxChntime set in csrScanRequest()? 2271 * csrScanCompleteCallback callback 2272 * pContext scan_request_id filled up 2273 */ 2274 qdf_ret_status = sme_scan_request(h_hal, 2275 sap_context->sessionId, 2276 &scan_request, 2277 &wlansap_pre_start_bss_acs_scan_callback, 2278 sap_context); 2279 } else { 2280 /* 2281 * when ID == 0 11D scan/active scan with callback, 2282 * min-maxChntime set in csrScanRequest()? 2283 * csrScanCompleteCallback callback, 2284 * pContext scan_request_id filled up 2285 */ 2286 qdf_ret_status = sme_scan_request(h_hal, 2287 sap_context->sessionId, 2288 &scan_request, 2289 &wlansap_scan_callback, 2290 sap_context); 2291 } 2292 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 2293 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2294 FL("sme_scan_request fail %d!!!"), 2295 qdf_ret_status); 2296 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2297 FL("SAP Configuring default channel, Ch=%d"), 2298 sap_context->channel); 2299 /* In case of error, switch to default channel */ 2300 sap_context->channel = SAP_DEFAULT_24GHZ_CHANNEL; 2301 2302 #ifdef SOFTAP_CHANNEL_RANGE 2303 if (sap_context->channelList != NULL) { 2304 sap_context->channel = 2305 sap_context->channelList[0]; 2306 qdf_mem_free(sap_context-> 2307 channelList); 2308 sap_context->channelList = NULL; 2309 } 2310 #endif 2311 if (true == sap_do_acs_pre_start_bss) { 2312 /* 2313 * In case of ACS req before start Bss, 2314 * return failure so that the calling 2315 * fucntion can use the default channel. 2316 */ 2317 return QDF_STATUS_E_FAILURE; 2318 } else { 2319 /* Fill in the event structure */ 2320 sap_event_init(sap_event); 2321 /* Handle event */ 2322 qdf_status = sap_fsm(sap_context, sap_event); 2323 } 2324 } else { 2325 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2326 FL("return sme_ScanReq, scanID=%d, Ch=%d"), 2327 scan_request.scan_id, sap_context->channel); 2328 } 2329 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2330 } 2331 } else { 2332 sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN; 2333 } 2334 2335 if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) { 2336 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2337 FL("## %s SKIPPED ACS SCAN"), __func__); 2338 wlansap_scan_callback(h_hal, sap_context, 2339 sap_context->sessionId, 0, eCSR_SCAN_SUCCESS); 2340 } 2341 #endif 2342 } else { 2343 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2344 FL("for configured channel, Ch= %d"), 2345 sap_context->channel); 2346 2347 if (check_for_connection_update) { 2348 /* This wait happens in the hostapd context. The event 2349 * is set in the MC thread context. 2350 */ 2351 qdf_status = cds_update_and_wait_for_connection_update( 2352 sap_context->sessionId, 2353 sap_context->channel, 2354 SIR_UPDATE_REASON_START_AP); 2355 if (QDF_IS_STATUS_ERROR(qdf_status)) 2356 return qdf_status; 2357 } 2358 2359 if (sap_do_acs_pre_start_bss == true) { 2360 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2361 FL("ACS end due to Ch override. Sel Ch = %d"), 2362 sap_context->channel); 2363 sap_context->acs_cfg->pri_ch = sap_context->channel; 2364 sap_context->acs_cfg->ch_width = 2365 sap_context->ch_width_orig; 2366 sap_config_acs_result(h_hal, sap_context, 0); 2367 return QDF_STATUS_E_CANCELED; 2368 } else { 2369 /* 2370 * Fill in the event structure 2371 * Eventhough scan was not done, 2372 * means a user set channel was chosen 2373 */ 2374 sap_event_init(sap_event); 2375 /* Handle event */ 2376 qdf_status = sap_fsm(sap_context, sap_event); 2377 } 2378 } 2379 2380 /* 2381 * If scan failed, get default channel and advance state 2382 * machine as success with default channel 2383 * 2384 * Have to wait for the call back to be called to get the 2385 * channel cannot advance state machine here as said above 2386 */ 2387 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2388 FL("before exiting sap_goto_channel_sel channel=%d"), 2389 sap_context->channel); 2390 2391 return QDF_STATUS_SUCCESS; 2392 } 2393 2394 /** 2395 * sap_open_session() - Opens a SAP session 2396 * @hHal: Hal handle 2397 * @sapContext: Sap Context value 2398 * @session_id: Pointer to the session id 2399 * 2400 * Function for opening SME and SAP sessions when system is in SoftAP role 2401 * 2402 * Return: QDF_STATUS 2403 */ 2404 2405 #define SAP_OPEN_SESSION_TIMEOUT 2000 2406 QDF_STATUS sap_open_session(tHalHandle hHal, ptSapContext sapContext, 2407 uint32_t *session_id) 2408 { 2409 uint32_t type, subType; 2410 QDF_STATUS qdf_ret_status; 2411 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2412 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 2413 2414 if (sapContext->csr_roamProfile.csrPersona == QDF_P2P_GO_MODE) 2415 status = cds_get_vdev_types(QDF_P2P_GO_MODE, &type, &subType); 2416 else 2417 status = cds_get_vdev_types(QDF_SAP_MODE, &type, &subType); 2418 2419 if (QDF_STATUS_SUCCESS != status) { 2420 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 2421 "failed to get vdev type"); 2422 return QDF_STATUS_E_FAILURE; 2423 } 2424 2425 qdf_event_reset(&sapContext->sap_session_opened_evt); 2426 /* Open SME Session for Softap */ 2427 qdf_ret_status = sme_open_session(hHal, 2428 &wlansap_roam_callback, 2429 sapContext, 2430 sapContext->self_mac_addr, 2431 &sapContext->sessionId, type, subType); 2432 2433 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 2434 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2435 "Error: In %s calling sme_roam_connect status = %d", 2436 __func__, qdf_ret_status); 2437 2438 return QDF_STATUS_E_FAILURE; 2439 } 2440 2441 status = qdf_wait_single_event(&sapContext->sap_session_opened_evt, 2442 SAP_OPEN_SESSION_TIMEOUT); 2443 2444 if (!QDF_IS_STATUS_SUCCESS(status)) { 2445 cds_err("wait for sap open session event timed out"); 2446 return QDF_STATUS_E_FAILURE; 2447 } 2448 2449 pMac->sap.sapCtxList[sapContext->sessionId].sessionID = 2450 sapContext->sessionId; 2451 pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = sapContext; 2452 pMac->sap.sapCtxList[sapContext->sessionId].sapPersona = 2453 sapContext->csr_roamProfile.csrPersona; 2454 *session_id = sapContext->sessionId; 2455 sapContext->isSapSessionOpen = eSAP_TRUE; 2456 sapContext->is_pre_cac_on = false; 2457 sapContext->pre_cac_complete = false; 2458 sapContext->chan_before_pre_cac = 0; 2459 return QDF_STATUS_SUCCESS; 2460 } 2461 2462 /*========================================================================== 2463 FUNCTION sapGotoStarting 2464 2465 DESCRIPTION 2466 Function for initiating start bss request for SME 2467 2468 DEPENDENCIES 2469 NA. 2470 2471 PARAMETERS 2472 2473 IN 2474 sapContext : Sap Context value 2475 sapEvent : State machine event 2476 bssType : Type of bss to start, INRA AP 2477 status : Return the SAP status here 2478 2479 RETURN VALUE 2480 The QDF_STATUS code associated with performing the operation 2481 2482 QDF_STATUS_SUCCESS: Success 2483 2484 SIDE EFFECTS 2485 ============================================================================*/ 2486 QDF_STATUS sap_goto_starting(ptSapContext sapContext, ptWLAN_SAPEvent sapEvent, 2487 eCsrRoamBssType bssType) 2488 { 2489 /* tHalHandle */ 2490 tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 2491 QDF_STATUS qdf_ret_status; 2492 2493 /*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/ 2494 char key_material[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 2495 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, }; 2496 sapContext->key_type = 0x05; 2497 sapContext->key_length = 32; 2498 /* Need a key size define */ 2499 qdf_mem_copy(sapContext->key_material, key_material, 2500 sizeof(key_material)); 2501 2502 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s", 2503 __func__); 2504 2505 if (NULL == hHal) { 2506 /* we have a serious problem */ 2507 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 2508 "In %s, invalid hHal", __func__); 2509 return QDF_STATUS_E_FAULT; 2510 } 2511 2512 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, "%s: session: %d", 2513 __func__, sapContext->sessionId); 2514 2515 qdf_ret_status = sme_roam_connect(hHal, sapContext->sessionId, 2516 &sapContext->csr_roamProfile, 2517 &sapContext->csr_roamId); 2518 if (QDF_STATUS_SUCCESS != qdf_ret_status) 2519 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2520 "%s: Failed to issue sme_roam_connect", __func__); 2521 2522 return qdf_ret_status; 2523 } /* sapGotoStarting */ 2524 2525 /*========================================================================== 2526 FUNCTION sapGotoDisconnecting 2527 2528 DESCRIPTION 2529 Processing of SAP FSM Disconnecting state 2530 2531 DEPENDENCIES 2532 NA. 2533 2534 PARAMETERS 2535 2536 IN 2537 sapContext : Sap Context value 2538 status : Return the SAP status here 2539 2540 RETURN VALUE 2541 The QDF_STATUS code associated with performing the operation 2542 2543 QDF_STATUS_SUCCESS: Success 2544 2545 SIDE EFFECTS 2546 ============================================================================*/ 2547 QDF_STATUS sap_goto_disconnecting(ptSapContext sapContext) 2548 { 2549 QDF_STATUS qdf_ret_status; 2550 tHalHandle hHal; 2551 2552 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 2553 if (NULL == hHal) { 2554 /* we have a serious problem */ 2555 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2556 "In %s, invalid hHal", __func__); 2557 return QDF_STATUS_E_FAULT; 2558 } 2559 2560 sap_free_roam_profile(&sapContext->csr_roamProfile); 2561 qdf_ret_status = sme_roam_stop_bss(hHal, sapContext->sessionId); 2562 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 2563 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2564 "Error: In %s calling sme_roam_stop_bss status = %d", 2565 __func__, qdf_ret_status); 2566 return QDF_STATUS_E_FAILURE; 2567 } 2568 2569 return QDF_STATUS_SUCCESS; 2570 } 2571 2572 static QDF_STATUS sap_roam_session_close_callback(void *pContext) 2573 { 2574 ptSapContext sapContext = (ptSapContext) pContext; 2575 return sap_signal_hdd_event(sapContext, NULL, 2576 eSAP_STOP_BSS_EVENT, 2577 (void *) eSAP_STATUS_SUCCESS); 2578 } 2579 2580 /*========================================================================== 2581 FUNCTION sapGotoDisconnected 2582 2583 DESCRIPTION 2584 Function for setting the SAP FSM to Disconnection state 2585 2586 DEPENDENCIES 2587 NA. 2588 2589 PARAMETERS 2590 2591 IN 2592 sapContext : Sap Context value 2593 sapEvent : State machine event 2594 status : Return the SAP status here 2595 2596 RETURN VALUE 2597 The QDF_STATUS code associated with performing the operation 2598 2599 QDF_STATUS_SUCCESS: Success 2600 2601 SIDE EFFECTS 2602 ============================================================================*/ 2603 QDF_STATUS sap_goto_disconnected(ptSapContext sapContext) 2604 { 2605 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2606 tWLAN_SAPEvent sapEvent; 2607 /* Processing has to be coded */ 2608 /* Clean up stations from TL etc as AP BSS is shut down then set event */ 2609 sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS; /* hardcoded */ 2610 sapEvent.params = 0; 2611 sapEvent.u1 = 0; 2612 sapEvent.u2 = 0; 2613 /* Handle event */ 2614 qdf_status = sap_fsm(sapContext, &sapEvent); 2615 2616 return qdf_status; 2617 } 2618 2619 /** 2620 * sap_signal_hdd_event() - send event notification 2621 * @sap_ctx: Sap Context 2622 * @csr_roaminfo: Pointer to CSR roam information 2623 * @sap_hddevent: SAP HDD event 2624 * @context: to pass the element for future support 2625 * 2626 * Function for HDD to send the event notification using callback 2627 * 2628 * Return: QDF_STATUS 2629 */ 2630 QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx, 2631 tCsrRoamInfo *csr_roaminfo, eSapHddEvent sap_hddevent, 2632 void *context) 2633 { 2634 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 2635 tSap_Event sap_ap_event; /* This now encodes ALL event types */ 2636 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 2637 tpAniSirGlobal mac_ctx; 2638 tSirSmeChanInfo *chaninfo; 2639 tSap_StationAssocIndication *assoc_ind; 2640 tSap_StartBssCompleteEvent *bss_complete; 2641 struct sap_ch_selected_s *acs_selected; 2642 tSap_StationAssocReassocCompleteEvent *reassoc_complete; 2643 tSap_StationDisassocCompleteEvent *disassoc_comp; 2644 tSap_StationSetKeyCompleteEvent *key_complete; 2645 tSap_StationMICFailureEvent *mic_failure; 2646 2647 /* Format the Start BSS Complete event to return... */ 2648 if (NULL == sap_ctx->pfnSapEventCallback) { 2649 QDF_ASSERT(0); 2650 return QDF_STATUS_E_FAILURE; 2651 } 2652 if (NULL == hal) { 2653 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2654 FL("Invalid hal")); 2655 return QDF_STATUS_E_FAILURE; 2656 } 2657 mac_ctx = PMAC_STRUCT(hal); 2658 if (NULL == mac_ctx) { 2659 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2660 FL("Invalid MAC context")); 2661 return QDF_STATUS_E_FAILURE; 2662 } 2663 2664 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2665 FL("SAP event callback event = %s"), 2666 sap_hdd_event_to_string(sap_hddevent)); 2667 2668 switch (sap_hddevent) { 2669 case eSAP_STA_ASSOC_IND: 2670 /* TODO - Indicate the assoc request indication to OS */ 2671 sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_IND; 2672 assoc_ind = &sap_ap_event.sapevt.sapAssocIndication; 2673 2674 qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac); 2675 assoc_ind->staId = csr_roaminfo->staId; 2676 assoc_ind->status = 0; 2677 /* Required for indicating the frames to upper layer */ 2678 assoc_ind->beaconLength = csr_roaminfo->beaconLength; 2679 assoc_ind->beaconPtr = csr_roaminfo->beaconPtr; 2680 assoc_ind->assocReqLength = csr_roaminfo->assocReqLength; 2681 assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr; 2682 assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta; 2683 if (csr_roaminfo->u.pConnectedProfile != NULL) { 2684 assoc_ind->negotiatedAuthType = 2685 csr_roaminfo->u.pConnectedProfile->AuthType; 2686 assoc_ind->negotiatedUCEncryptionType = 2687 csr_roaminfo->u.pConnectedProfile->EncryptionType; 2688 assoc_ind->negotiatedMCEncryptionType = 2689 csr_roaminfo->u.pConnectedProfile->mcEncryptionType; 2690 assoc_ind->fAuthRequired = csr_roaminfo->fAuthRequired; 2691 } 2692 break; 2693 case eSAP_START_BSS_EVENT: 2694 sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT; 2695 bss_complete = &sap_ap_event.sapevt.sapStartBssCompleteEvent; 2696 2697 bss_complete->status = (eSapStatus) context; 2698 if (csr_roaminfo != NULL) 2699 bss_complete->staId = csr_roaminfo->staId; 2700 else 2701 bss_complete->staId = 0; 2702 2703 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2704 FL("(eSAP_START_BSS_EVENT): staId = %d"), 2705 bss_complete->staId); 2706 2707 bss_complete->operatingChannel = (uint8_t) sap_ctx->channel; 2708 bss_complete->sessionId = sap_ctx->sessionId; 2709 break; 2710 case eSAP_DFS_CAC_START: 2711 case eSAP_DFS_CAC_INTERRUPTED: 2712 case eSAP_DFS_CAC_END: 2713 case eSAP_DFS_PRE_CAC_END: 2714 case eSAP_DFS_RADAR_DETECT: 2715 case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC: 2716 case eSAP_DFS_NO_AVAILABLE_CHANNEL: 2717 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 2718 case eSAP_ACS_SCAN_SUCCESS_EVENT: 2719 #endif 2720 sap_ap_event.sapHddEventCode = sap_hddevent; 2721 sap_ap_event.sapevt.sapStopBssCompleteEvent.status = 2722 (eSapStatus) context; 2723 break; 2724 2725 case eSAP_ACS_CHANNEL_SELECTED: 2726 sap_ap_event.sapHddEventCode = sap_hddevent; 2727 acs_selected = &sap_ap_event.sapevt.sap_ch_selected; 2728 if (eSAP_STATUS_SUCCESS == (eSapStatus)context) { 2729 acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; 2730 acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch; 2731 acs_selected->ch_width = sap_ctx->acs_cfg->ch_width; 2732 acs_selected->vht_seg0_center_ch = 2733 sap_ctx->acs_cfg->vht_seg0_center_ch; 2734 acs_selected->vht_seg1_center_ch = 2735 sap_ctx->acs_cfg->vht_seg1_center_ch; 2736 } else if (eSAP_STATUS_FAILURE == (eSapStatus)context) { 2737 acs_selected->pri_ch = 0; 2738 } 2739 break; 2740 2741 case eSAP_STOP_BSS_EVENT: 2742 sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT; 2743 sap_ap_event.sapevt.sapStopBssCompleteEvent.status = 2744 (eSapStatus) context; 2745 break; 2746 2747 case eSAP_STA_ASSOC_EVENT: 2748 case eSAP_STA_REASSOC_EVENT: 2749 reassoc_complete = 2750 &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent; 2751 2752 if (csr_roaminfo->fReassocReq) 2753 sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT; 2754 else 2755 sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT; 2756 2757 qdf_copy_macaddr(&reassoc_complete->staMac, 2758 &csr_roaminfo->peerMac); 2759 reassoc_complete->staId = csr_roaminfo->staId; 2760 reassoc_complete->statusCode = csr_roaminfo->statusCode; 2761 reassoc_complete->iesLen = csr_roaminfo->rsnIELen; 2762 qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE, 2763 csr_roaminfo->rsnIELen); 2764 2765 #ifdef FEATURE_WLAN_WAPI 2766 if (csr_roaminfo->wapiIELen) { 2767 uint8_t len = reassoc_complete->iesLen; 2768 reassoc_complete->iesLen += csr_roaminfo->wapiIELen; 2769 qdf_mem_copy(&reassoc_complete->ies[len], 2770 csr_roaminfo->pwapiIE, 2771 csr_roaminfo->wapiIELen); 2772 } 2773 #endif 2774 if (csr_roaminfo->addIELen) { 2775 uint8_t len = reassoc_complete->iesLen; 2776 reassoc_complete->iesLen += csr_roaminfo->addIELen; 2777 qdf_mem_copy(&reassoc_complete->ies[len], 2778 csr_roaminfo->paddIE, 2779 csr_roaminfo->addIELen); 2780 } 2781 2782 /* also fill up the channel info from the csr_roamInfo */ 2783 chaninfo = &reassoc_complete->chan_info; 2784 2785 chaninfo->chan_id = csr_roaminfo->chan_info.chan_id; 2786 chaninfo->mhz = csr_roaminfo->chan_info.mhz; 2787 chaninfo->info = csr_roaminfo->chan_info.info; 2788 chaninfo->band_center_freq1 = 2789 csr_roaminfo->chan_info.band_center_freq1; 2790 chaninfo->band_center_freq2 = 2791 csr_roaminfo->chan_info.band_center_freq2; 2792 chaninfo->reg_info_1 = 2793 csr_roaminfo->chan_info.reg_info_1; 2794 chaninfo->reg_info_2 = 2795 csr_roaminfo->chan_info.reg_info_2; 2796 chaninfo->nss = csr_roaminfo->chan_info.nss; 2797 chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags; 2798 2799 reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta; 2800 reassoc_complete->status = (eSapStatus) context; 2801 reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap; 2802 break; 2803 2804 case eSAP_STA_DISASSOC_EVENT: 2805 sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; 2806 disassoc_comp = 2807 &sap_ap_event.sapevt.sapStationDisassocCompleteEvent; 2808 2809 qdf_copy_macaddr(&disassoc_comp->staMac, 2810 &csr_roaminfo->peerMac); 2811 disassoc_comp->staId = csr_roaminfo->staId; 2812 if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED) 2813 disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC; 2814 else 2815 disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC; 2816 2817 disassoc_comp->statusCode = csr_roaminfo->statusCode; 2818 disassoc_comp->status = (eSapStatus) context; 2819 break; 2820 2821 case eSAP_STA_SET_KEY_EVENT: 2822 sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT; 2823 key_complete = 2824 &sap_ap_event.sapevt.sapStationSetKeyCompleteEvent; 2825 key_complete->status = (eSapStatus) context; 2826 qdf_copy_macaddr(&key_complete->peerMacAddr, 2827 &csr_roaminfo->peerMac); 2828 break; 2829 2830 case eSAP_STA_MIC_FAILURE_EVENT: 2831 sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT; 2832 mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent; 2833 2834 qdf_mem_copy(&mic_failure->srcMacAddr, 2835 csr_roaminfo->u.pMICFailureInfo->srcMacAddr, 2836 sizeof(tSirMacAddr)); 2837 qdf_mem_copy(&mic_failure->staMac.bytes, 2838 csr_roaminfo->u.pMICFailureInfo->taMacAddr, 2839 sizeof(tSirMacAddr)); 2840 qdf_mem_copy(&mic_failure->dstMacAddr.bytes, 2841 csr_roaminfo->u.pMICFailureInfo->dstMacAddr, 2842 sizeof(tSirMacAddr)); 2843 mic_failure->multicast = 2844 csr_roaminfo->u.pMICFailureInfo->multicast; 2845 mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1; 2846 mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId; 2847 qdf_mem_copy(mic_failure->TSC, 2848 csr_roaminfo->u.pMICFailureInfo->TSC, 2849 SIR_CIPHER_SEQ_CTR_SIZE); 2850 break; 2851 2852 case eSAP_ASSOC_STA_CALLBACK_EVENT: 2853 break; 2854 2855 case eSAP_WPS_PBC_PROBE_REQ_EVENT: 2856 sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT; 2857 2858 qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent. 2859 WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq, 2860 sizeof(tSirWPSPBCProbeReq)); 2861 break; 2862 2863 case eSAP_REMAIN_CHAN_READY: 2864 sap_ap_event.sapHddEventCode = eSAP_REMAIN_CHAN_READY; 2865 sap_ap_event.sapevt.sap_roc_ind.scan_id = 2866 sap_ctx->roc_ind_scan_id; 2867 break; 2868 case eSAP_SEND_ACTION_CNF: 2869 sap_ap_event.sapHddEventCode = eSAP_SEND_ACTION_CNF; 2870 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 2871 (eSapStatus) context; 2872 break; 2873 2874 case eSAP_DISCONNECT_ALL_P2P_CLIENT: 2875 sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT; 2876 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 2877 (eSapStatus) context; 2878 break; 2879 2880 case eSAP_MAC_TRIG_STOP_BSS_EVENT: 2881 sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT; 2882 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 2883 (eSapStatus) context; 2884 break; 2885 2886 case eSAP_UNKNOWN_STA_JOIN: 2887 sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN; 2888 qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin. 2889 macaddr.bytes, (void *) context, 2890 QDF_MAC_ADDR_SIZE); 2891 break; 2892 2893 case eSAP_MAX_ASSOC_EXCEEDED: 2894 sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED; 2895 qdf_copy_macaddr(&sap_ap_event.sapevt. 2896 sapMaxAssocExceeded.macaddr, 2897 &csr_roaminfo->peerMac); 2898 break; 2899 2900 case eSAP_CHANNEL_CHANGE_EVENT: 2901 /* 2902 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS 2903 * follows pri AP 2904 */ 2905 sap_ctx->acs_cfg->pri_ch = sap_ctx->channel; 2906 sap_ctx->acs_cfg->ch_width = 2907 sap_ctx->csr_roamProfile.ch_params.ch_width; 2908 sap_config_acs_result(hal, sap_ctx, 2909 sap_ctx->csr_roamProfile.ch_params.sec_ch_offset); 2910 2911 sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; 2912 2913 acs_selected = &sap_ap_event.sapevt.sap_ch_selected; 2914 acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; 2915 acs_selected->ht_sec_ch = 2916 sap_ctx->csr_roamProfile.ch_params.sec_ch_offset; 2917 acs_selected->ch_width = 2918 sap_ctx->csr_roamProfile.ch_params.ch_width; 2919 acs_selected->vht_seg0_center_ch = 2920 sap_ctx->csr_roamProfile.ch_params.center_freq_seg0; 2921 acs_selected->vht_seg1_center_ch = 2922 sap_ctx->csr_roamProfile.ch_params.center_freq_seg1; 2923 break; 2924 2925 case eSAP_DFS_NOL_GET: 2926 sap_ap_event.sapHddEventCode = eSAP_DFS_NOL_GET; 2927 sap_ap_event.sapevt.sapDfsNolInfo.sDfsList = 2928 NUM_5GHZ_CHANNELS * sizeof(tSapDfsNolInfo); 2929 sap_ap_event.sapevt.sapDfsNolInfo.pDfsList = (void *) 2930 (&mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList[0]); 2931 break; 2932 2933 case eSAP_DFS_NOL_SET: 2934 sap_ap_event.sapHddEventCode = eSAP_DFS_NOL_SET; 2935 sap_ap_event.sapevt.sapDfsNolInfo.sDfsList = 2936 mac_ctx->sap.SapDfsInfo.numCurrentRegDomainDfsChannels * 2937 sizeof(tSapDfsNolInfo); 2938 sap_ap_event.sapevt.sapDfsNolInfo.pDfsList = (void *) 2939 (&mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList[0]); 2940 break; 2941 case eSAP_ECSA_CHANGE_CHAN_IND: 2942 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2943 "In %s, SAP event callback event = %s", 2944 __func__, "eSAP_ECSA_CHANGE_CHAN_IND"); 2945 sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND; 2946 sap_ap_event.sapevt.sap_chan_cng_ind.new_chan = 2947 csr_roaminfo->target_channel; 2948 break; 2949 default: 2950 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2951 FL("SAP Unknown callback event = %d"), 2952 sap_hddevent); 2953 break; 2954 } 2955 qdf_status = (*sap_ctx->pfnSapEventCallback) 2956 (&sap_ap_event, sap_ctx->pUsrContext); 2957 2958 return qdf_status; 2959 2960 } 2961 2962 /*========================================================================== 2963 FUNCTION sap_find_valid_concurrent_session 2964 2965 DESCRIPTION 2966 This function will return sapcontext of any valid sap session. 2967 2968 PARAMETERS 2969 2970 IN 2971 hHal : HAL pointer 2972 2973 RETURN VALUE 2974 ptSapContext : valid sap context 2975 2976 SIDE EFFECTS 2977 NA 2978 ============================================================================*/ 2979 ptSapContext sap_find_valid_concurrent_session(tHalHandle hHal) 2980 { 2981 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 2982 uint8_t intf = 0; 2983 2984 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2985 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 2986 || 2987 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) && 2988 pMac->sap.sapCtxList[intf].pSapContext != NULL) { 2989 return pMac->sap.sapCtxList[intf].pSapContext; 2990 } 2991 } 2992 2993 return NULL; 2994 } 2995 2996 /** 2997 * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state 2998 * @handle: Global MAC handle 2999 * 3000 * Finds and gets the context of a SAP session in CAC wait state. 3001 * 3002 * Return: Valid SAP context on success, else NULL 3003 */ 3004 ptSapContext sap_find_cac_wait_session(tHalHandle handle) 3005 { 3006 tpAniSirGlobal mac = PMAC_STRUCT(handle); 3007 uint8_t i = 0; 3008 ptSapContext sapContext; 3009 3010 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3011 "%s", __func__); 3012 3013 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 3014 sapContext = (ptSapContext) mac->sap.sapCtxList[i].pSapContext; 3015 if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona) 3016 || 3017 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) && 3018 (sapContext) && 3019 (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) { 3020 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3021 "%s: found SAP in cac wait state", __func__); 3022 return sapContext; 3023 } 3024 if (sapContext) { 3025 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3026 "sapdfs: mode:%d intf:%d state:%d", 3027 mac->sap.sapCtxList[i].sapPersona, i, 3028 sapContext->sapsMachine); 3029 } 3030 } 3031 3032 return NULL; 3033 } 3034 3035 /*========================================================================== 3036 FUNCTION sap_close_session 3037 3038 DESCRIPTION 3039 This function will close all the sme sessions as well as zero-out the 3040 sap global structure 3041 3042 PARAMETERS 3043 3044 IN 3045 hHal : HAL pointer 3046 sapContext : Sap Context value 3047 callback : Roam Session close callback 3048 valid : Sap context is valid or no 3049 3050 RETURN VALUE 3051 The QDF_STATUS code associated with performing the operation 3052 QDF_STATUS_SUCCESS: Success 3053 3054 SIDE EFFECTS 3055 NA 3056 ============================================================================*/ 3057 QDF_STATUS sap_close_session(tHalHandle hHal, 3058 ptSapContext sapContext, 3059 csr_roamSessionCloseCallback callback, bool valid) 3060 { 3061 QDF_STATUS qdf_status; 3062 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3063 3064 if (false == valid) { 3065 qdf_status = sme_close_session(hHal, 3066 sapContext->sessionId, 3067 callback, NULL); 3068 } else { 3069 qdf_status = sme_close_session(hHal, 3070 sapContext->sessionId, 3071 callback, sapContext); 3072 } 3073 3074 sapContext->isCacStartNotified = false; 3075 sapContext->isCacEndNotified = false; 3076 pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = NULL; 3077 sapContext->isSapSessionOpen = false; 3078 sapContext->pre_cac_complete = false; 3079 sapContext->is_pre_cac_on = false; 3080 sapContext->chan_before_pre_cac = 0; 3081 3082 if (NULL == sap_find_valid_concurrent_session(hHal)) { 3083 /* If timer is running then stop the timer and destory it */ 3084 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3085 "sapdfs: no session are valid, so clearing dfs global structure"); 3086 /* 3087 * CAC timer will be initiated and started only when SAP starts 3088 * on DFS channel and it will be stopped and destroyed 3089 * immediately once the radar detected or timedout. So 3090 * as per design CAC timer should be destroyed after stop 3091 */ 3092 if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) { 3093 qdf_mc_timer_stop(&pMac->sap.SapDfsInfo. 3094 sap_dfs_cac_timer); 3095 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 3096 qdf_mc_timer_destroy( 3097 &pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 3098 } 3099 pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; 3100 sap_cac_reset_notify(hHal); 3101 qdf_mem_zero(&pMac->sap, sizeof(pMac->sap)); 3102 } 3103 3104 return qdf_status; 3105 } 3106 3107 /*========================================================================== 3108 FUNCTION sap_cac_reset_notify 3109 3110 DESCRIPTION Function will be called up on stop bss indication to clean up 3111 DFS global structure. 3112 3113 DEPENDENCIES PARAMETERS 3114 IN hHAL : HAL pointer 3115 3116 RETURN VALUE : void. 3117 3118 SIDE EFFECTS 3119 ============================================================================*/ 3120 void sap_cac_reset_notify(tHalHandle hHal) 3121 { 3122 uint8_t intf = 0; 3123 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3124 3125 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3126 ptSapContext pSapContext = 3127 (ptSapContext) pMac->sap.sapCtxList[intf].pSapContext; 3128 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3129 || 3130 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3131 && pMac->sap.sapCtxList[intf].pSapContext != NULL) { 3132 pSapContext->isCacStartNotified = false; 3133 pSapContext->isCacEndNotified = false; 3134 } 3135 } 3136 } 3137 3138 /*========================================================================== 3139 FUNCTION sap_cac_start_notify 3140 3141 DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event 3142 to HDD 3143 3144 DEPENDENCIES PARAMETERS 3145 IN hHAL : HAL pointer 3146 3147 RETURN VALUE : QDF_STATUS. 3148 3149 SIDE EFFECTS 3150 ============================================================================*/ 3151 QDF_STATUS sap_cac_start_notify(tHalHandle hHal) 3152 { 3153 uint8_t intf = 0; 3154 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3155 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3156 3157 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3158 ptSapContext pSapContext = 3159 (ptSapContext) pMac->sap.sapCtxList[intf].pSapContext; 3160 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3161 || 3162 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3163 && pMac->sap.sapCtxList[intf].pSapContext != NULL && 3164 (false == pSapContext->isCacStartNotified)) { 3165 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3166 "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%p]", 3167 pSapContext); 3168 3169 qdf_status = sap_signal_hdd_event(pSapContext, NULL, 3170 eSAP_DFS_CAC_START, 3171 (void *) 3172 eSAP_STATUS_SUCCESS); 3173 if (QDF_STATUS_SUCCESS != qdf_status) { 3174 QDF_TRACE(QDF_MODULE_ID_SAP, 3175 QDF_TRACE_LEVEL_ERROR, 3176 "In %s, failed setting isCacStartNotified on interface[%d]", 3177 __func__, intf); 3178 return qdf_status; 3179 } 3180 pSapContext->isCacStartNotified = true; 3181 } 3182 } 3183 return qdf_status; 3184 } 3185 3186 /** 3187 * wlansap_update_pre_cac_end() - Update pre cac end to upper layer 3188 * @sap_context: SAP context 3189 * @mac: Global MAC structure 3190 * @intf: Interface number 3191 * 3192 * Notifies pre cac end to upper layer 3193 * 3194 * Return: QDF_STATUS 3195 */ 3196 static QDF_STATUS wlansap_update_pre_cac_end(ptSapContext sap_context, 3197 tpAniSirGlobal mac, uint8_t intf) 3198 { 3199 QDF_STATUS qdf_status; 3200 3201 sap_context->isCacEndNotified = true; 3202 mac->sap.SapDfsInfo.sap_radar_found_status = false; 3203 sap_context->sapsMachine = eSAP_STARTED; 3204 3205 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3206 "In %s, pre cac end notify on %d: from state %s => %s", 3207 __func__, intf, "eSAP_DFS_CAC_WAIT", 3208 "eSAP_STARTED"); 3209 3210 qdf_status = sap_signal_hdd_event(sap_context, 3211 NULL, eSAP_DFS_PRE_CAC_END, 3212 (void *)eSAP_STATUS_SUCCESS); 3213 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3214 QDF_TRACE(QDF_MODULE_ID_SAP, 3215 QDF_TRACE_LEVEL_ERROR, 3216 "In %s, pre cac notify failed on intf %d", 3217 __func__, intf); 3218 return qdf_status; 3219 } 3220 3221 return QDF_STATUS_SUCCESS; 3222 } 3223 3224 /*========================================================================== 3225 FUNCTION sap_cac_end_notify 3226 3227 DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event 3228 to HDD 3229 3230 DEPENDENCIES PARAMETERS 3231 IN hHAL : HAL pointer 3232 3233 RETURN VALUE : QDF_STATUS. 3234 3235 SIDE EFFECTS 3236 ============================================================================*/ 3237 QDF_STATUS sap_cac_end_notify(tHalHandle hHal, tCsrRoamInfo *roamInfo) 3238 { 3239 uint8_t intf; 3240 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3241 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3242 3243 /* 3244 * eSAP_DFS_CHANNEL_CAC_END: 3245 * CAC Period elapsed and there was no radar 3246 * found so, SAP can continue beaconing. 3247 * sap_radar_found_status is set to 0 3248 */ 3249 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3250 ptSapContext pSapContext = 3251 (ptSapContext) pMac->sap.sapCtxList[intf].pSapContext; 3252 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3253 || 3254 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3255 && pMac->sap.sapCtxList[intf].pSapContext != NULL && 3256 (false == pSapContext->isCacEndNotified) && 3257 (pSapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) { 3258 pSapContext = pMac->sap.sapCtxList[intf].pSapContext; 3259 3260 /* If this is an end notification of a pre cac, the 3261 * SAP must not start beaconing and must delete the 3262 * temporary interface created for pre cac and switch 3263 * the original SAP to the pre CAC channel. 3264 */ 3265 if (pSapContext->is_pre_cac_on) { 3266 qdf_status = wlansap_update_pre_cac_end( 3267 pSapContext, pMac, intf); 3268 if (QDF_IS_STATUS_ERROR(qdf_status)) 3269 return qdf_status; 3270 /* pre CAC is not allowed with any concurrency. 3271 * So, we can break from here. 3272 */ 3273 break; 3274 } 3275 3276 qdf_status = sap_signal_hdd_event(pSapContext, NULL, 3277 eSAP_DFS_CAC_END, 3278 (void *) 3279 eSAP_STATUS_SUCCESS); 3280 if (QDF_STATUS_SUCCESS != qdf_status) { 3281 QDF_TRACE(QDF_MODULE_ID_SAP, 3282 QDF_TRACE_LEVEL_ERROR, 3283 "In %s, failed setting isCacEndNotified on interface[%d]", 3284 __func__, intf); 3285 return qdf_status; 3286 } 3287 pSapContext->isCacEndNotified = true; 3288 pMac->sap.SapDfsInfo.sap_radar_found_status = false; 3289 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3290 "sapdfs: Start beacon request on sapctx[%p]", 3291 pSapContext); 3292 3293 /* Start beaconing on the new channel */ 3294 wlansap_start_beacon_req(pSapContext); 3295 3296 /* Transition from eSAP_STARTING to eSAP_STARTED 3297 * (both without substates) 3298 */ 3299 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3300 "sapdfs: channel[%d] from state %s => %s", 3301 pSapContext->channel, "eSAP_STARTING", 3302 "eSAP_STARTED"); 3303 3304 pSapContext->sapsMachine = eSAP_STARTED; 3305 3306 /*Action code for transition */ 3307 qdf_status = sap_signal_hdd_event(pSapContext, roamInfo, 3308 eSAP_START_BSS_EVENT, 3309 (void *) 3310 eSAP_STATUS_SUCCESS); 3311 if (QDF_STATUS_SUCCESS != qdf_status) { 3312 QDF_TRACE(QDF_MODULE_ID_SAP, 3313 QDF_TRACE_LEVEL_ERROR, 3314 "In %s, failed setting isCacEndNotified on interface[%d]", 3315 __func__, intf); 3316 return qdf_status; 3317 } 3318 3319 /* Transition from eSAP_STARTING to eSAP_STARTED 3320 * (both without substates) 3321 */ 3322 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3323 "In %s, from state %s => %s", 3324 __func__, "eSAP_DFS_CAC_WAIT", 3325 "eSAP_STARTED"); 3326 } 3327 } 3328 /* 3329 * All APs are done with CAC timer, all APs should start beaconing. 3330 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets 3331 * say AP1 goes down and comes back on same DFS channel. In this case 3332 * AP1 shouldn't start CAC timer and start beacon immediately beacause 3333 * AP2 is already beaconing on this channel. This case will be handled 3334 * by checking against eSAP_DFS_SKIP_CAC while starting the timer. 3335 */ 3336 pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC; 3337 return qdf_status; 3338 } 3339 3340 /** 3341 * sap_fsm_state_disconnected() - utility function called from sap fsm 3342 * @sap_ctx: SAP context 3343 * @sap_event: SAP event buffer 3344 * @mac_ctx: global MAC context 3345 * @hal: HAL handle 3346 * 3347 * This function is called for state transition from "eSAP_DISCONNECTED" 3348 * 3349 * Return: QDF_STATUS 3350 */ 3351 static QDF_STATUS sap_fsm_state_disconnected(ptSapContext sap_ctx, 3352 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3353 tHalHandle hal) 3354 { 3355 uint32_t msg = sap_event->event; 3356 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3357 3358 if (msg == eSAP_HDD_START_INFRA_BSS) { 3359 /* 3360 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT 3361 * (both without substates) 3362 */ 3363 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3364 FL("new from state %s => %s: session:%d"), 3365 "eSAP_DISCONNECTED", "eSAP_CH_SELECT", 3366 sap_ctx->sessionId); 3367 3368 if (sap_ctx->isSapSessionOpen == eSAP_FALSE) { 3369 uint32_t type, subtype; 3370 if (sap_ctx->csr_roamProfile.csrPersona == 3371 QDF_P2P_GO_MODE) 3372 qdf_status = cds_get_vdev_types(QDF_P2P_GO_MODE, 3373 &type, &subtype); 3374 else 3375 qdf_status = cds_get_vdev_types(QDF_SAP_MODE, 3376 &type, 3377 &subtype); 3378 3379 if (QDF_STATUS_SUCCESS != qdf_status) { 3380 QDF_TRACE(QDF_MODULE_ID_SAP, 3381 QDF_TRACE_LEVEL_FATAL, 3382 "failed to get vdev type"); 3383 return QDF_STATUS_E_FAILURE; 3384 } 3385 /* Open SME Session for scan */ 3386 qdf_status = sme_open_session(hal, NULL, 3387 sap_ctx, sap_ctx->self_mac_addr, 3388 &sap_ctx->sessionId, type, subtype); 3389 if (QDF_STATUS_SUCCESS != qdf_status) { 3390 QDF_TRACE(QDF_MODULE_ID_SAP, 3391 QDF_TRACE_LEVEL_ERROR, 3392 FL("Error: calling sme_open_session")); 3393 return QDF_STATUS_E_FAILURE; 3394 } 3395 3396 sap_ctx->isSapSessionOpen = eSAP_TRUE; 3397 } 3398 3399 /* init dfs channel nol */ 3400 sap_init_dfs_channel_nol_list(sap_ctx); 3401 3402 /* Set SAP device role */ 3403 sap_ctx->sapsMachine = eSAP_CH_SELECT; 3404 3405 /* 3406 * Perform sme_ScanRequest. This scan request is post start bss 3407 * request so, set the third to false. 3408 */ 3409 qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false, 3410 true); 3411 3412 /* 3413 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT 3414 * (both without substates) 3415 */ 3416 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3417 FL("from state %s => %s"), 3418 "eSAP_DISCONNECTED", "eSAP_CH_SELECT"); 3419 } else if (msg == eSAP_DFS_CHANNEL_CAC_START) { 3420 /* 3421 * No need of state check here, caller is expected to perform 3422 * the checks before sending the event 3423 */ 3424 sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT; 3425 3426 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3427 FL("from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT")); 3428 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) { 3429 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3430 FL("sapdfs: starting dfs cac timer on sapctx[%p]"), 3431 sap_ctx); 3432 sap_start_dfs_cac_timer(sap_ctx); 3433 } 3434 3435 qdf_status = sap_cac_start_notify(hal); 3436 } else if (msg == eSAP_CHANNEL_SELECTION_RETRY) { 3437 /* Set SAP device role */ 3438 sap_ctx->sapsMachine = eSAP_CH_SELECT; 3439 3440 /* 3441 * Perform sme_ScanRequest. This scan request is post start bss 3442 * request so, set the third to false. 3443 */ 3444 qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false, 3445 false); 3446 } else { 3447 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3448 FL("in state %s, event msg %d"), 3449 "eSAP_DISCONNECTED", msg); 3450 } 3451 3452 return qdf_status; 3453 } 3454 3455 /** 3456 * sap_fsm_state_ch_select() - utility function called from sap fsm 3457 * @sap_ctx: SAP context 3458 * @sap_event: SAP event buffer 3459 * @mac_ctx: global MAC context 3460 * @hal: HAL handle 3461 * 3462 * This function is called for state transition from "eSAP_CH_SELECT" 3463 * 3464 * Return: QDF_STATUS 3465 */ 3466 static QDF_STATUS sap_fsm_state_ch_select(ptSapContext sap_ctx, 3467 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3468 tHalHandle hal) 3469 { 3470 uint32_t msg = sap_event->event; 3471 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3472 uint32_t cbmode; 3473 bool b_leak_chan = false; 3474 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 3475 uint8_t temp_chan; 3476 tSapDfsNolInfo *p_nol; 3477 #endif 3478 3479 if (msg == eSAP_MAC_SCAN_COMPLETE) { 3480 /* get the bonding mode */ 3481 if (sap_ctx->channel <= 14) 3482 cbmode = sme_get_cb_phy_state_from_cb_ini_value( 3483 sme_get_channel_bonding_mode24_g(hal)); 3484 else 3485 cbmode = sme_get_cb_phy_state_from_cb_ini_value( 3486 sme_get_channel_bonding_mode5_g(hal)); 3487 3488 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 3489 temp_chan = sap_ctx->channel; 3490 p_nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList; 3491 3492 sap_mark_leaking_ch(sap_ctx, 3493 cbmode, p_nol, 1, &temp_chan); 3494 3495 /* 3496 * if selelcted channel has leakage to channels 3497 * in NOL, the temp_chan will be reset 3498 */ 3499 b_leak_chan = (temp_chan != sap_ctx->channel); 3500 #endif 3501 /* 3502 * check if channel is in DFS_NOL or if the channel 3503 * has leakage to the channels in NOL 3504 */ 3505 if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel, 3506 cbmode) || b_leak_chan) { 3507 uint8_t ch; 3508 3509 /* find a new available channel */ 3510 ch = sap_random_channel_sel(sap_ctx); 3511 if (ch == 0) { 3512 /* No available channel found */ 3513 QDF_TRACE(QDF_MODULE_ID_SAP, 3514 QDF_TRACE_LEVEL_ERROR, 3515 FL("No available channel found!!!")); 3516 sap_signal_hdd_event(sap_ctx, NULL, 3517 eSAP_DFS_NO_AVAILABLE_CHANNEL, 3518 (void *)eSAP_STATUS_SUCCESS); 3519 return QDF_STATUS_E_FAULT; 3520 } 3521 3522 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3523 FL("channel %d is in NOL, StartBss on new channel %d"), 3524 sap_ctx->channel, ch); 3525 3526 sap_ctx->channel = ch; 3527 cds_set_channel_params(sap_ctx->channel, 3528 sap_ctx->secondary_ch, &sap_ctx->ch_params); 3529 } 3530 if (sap_ctx->channel > 14 && 3531 (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g || 3532 sap_ctx->csr_roamProfile.phyMode == 3533 eCSR_DOT11_MODE_11g_ONLY)) 3534 sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a; 3535 3536 /* 3537 * when AP2 is started while AP1 is performing ACS, we may not 3538 * have the AP1 channel yet.So here after the completion of AP2 3539 * ACS check if AP1 ACS resulting channel is DFS and if yes 3540 * override AP2 ACS scan result with AP1 DFS channel 3541 */ 3542 if (cds_concurrent_beaconing_sessions_running()) { 3543 uint16_t con_ch; 3544 3545 con_ch = sme_get_concurrent_operation_channel(hal); 3546 if (con_ch && CDS_IS_DFS_CH(con_ch)) 3547 sap_ctx->channel = con_ch; 3548 } 3549 3550 /* 3551 * Transition from eSAP_CH_SELECT to eSAP_STARTING 3552 * (both without substates) 3553 */ 3554 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3555 FL("from state %s => %s"), 3556 "eSAP_CH_SELECT", "eSAP_STARTING"); 3557 /* Channel selected. Now can sap_goto_starting */ 3558 sap_ctx->sapsMachine = eSAP_STARTING; 3559 /* Specify the channel */ 3560 sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels = 3561 1; 3562 sap_ctx->csr_roamProfile.ChannelInfo.ChannelList = 3563 &sap_ctx->csr_roamProfile.operationChannel; 3564 sap_ctx->csr_roamProfile.operationChannel = 3565 (uint8_t) sap_ctx->channel; 3566 sap_ctx->csr_roamProfile.ch_params.ch_width = 3567 sap_ctx->ch_params.ch_width; 3568 sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 = 3569 sap_ctx->ch_params.center_freq_seg0; 3570 sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 = 3571 sap_ctx->ch_params.center_freq_seg1; 3572 sap_ctx->csr_roamProfile.ch_params.sec_ch_offset = 3573 sap_ctx->ch_params.sec_ch_offset; 3574 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3575 FL("notify hostapd about channel selection: %d"), 3576 sap_ctx->channel); 3577 sap_signal_hdd_event(sap_ctx, NULL, 3578 eSAP_CHANNEL_CHANGE_EVENT, 3579 (void *) eSAP_STATUS_SUCCESS); 3580 qdf_status = sap_goto_starting(sap_ctx, sap_event, 3581 eCSR_BSS_TYPE_INFRA_AP); 3582 } else if (msg == eSAP_CHANNEL_SELECTION_FAILED) { 3583 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3584 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3585 FL("Cannot start BSS, ACS Fail")); 3586 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3587 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3588 sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT, 3589 (void *)eSAP_STATUS_FAILURE); 3590 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3591 "%s: BSS stopped when Ch select in Progress", __func__); 3592 } else { 3593 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3594 FL("in state %s, invalid event msg %d"), 3595 "eSAP_CH_SELECT", msg); 3596 } 3597 3598 return qdf_status; 3599 } 3600 3601 /** 3602 * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm 3603 * @sap_ctx: SAP context 3604 * @sap_event: SAP event buffer 3605 * @mac_ctx: global MAC context 3606 * @hal: HAL handle 3607 * 3608 * This function is called for state transition from "eSAP_DFS_CAC_WAIT" 3609 * 3610 * Return: QDF_STATUS 3611 */ 3612 static QDF_STATUS sap_fsm_state_dfs_cac_wait(ptSapContext sap_ctx, 3613 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3614 tHalHandle hal) 3615 { 3616 uint32_t msg = sap_event->event; 3617 tCsrRoamInfo *roam_info = (tCsrRoamInfo *) (sap_event->params); 3618 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3619 3620 if (msg == eSAP_DFS_CHANNEL_CAC_START) { 3621 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3622 FL("from state %s => %s"), 3623 "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT"); 3624 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) 3625 sap_start_dfs_cac_timer(sap_ctx); 3626 qdf_status = sap_cac_start_notify(hal); 3627 } else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) { 3628 uint8_t intf; 3629 /* 3630 * Radar found while performing channel availability 3631 * check, need to switch the channel again 3632 */ 3633 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3634 "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n"); 3635 if (mac_ctx->sap.SapDfsInfo.target_channel) { 3636 cds_set_channel_params( 3637 mac_ctx->sap.SapDfsInfo.target_channel, 0, 3638 &sap_ctx->ch_params); 3639 } 3640 3641 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3642 ptSapContext t_sap_ctx; 3643 if (((QDF_SAP_MODE == 3644 mac_ctx->sap.sapCtxList[intf].sapPersona) || 3645 (QDF_P2P_GO_MODE == 3646 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 3647 mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) { 3648 t_sap_ctx = 3649 mac_ctx->sap.sapCtxList[intf].pSapContext; 3650 /* SAP to be moved to DISCONNECTING state */ 3651 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 3652 /* 3653 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND: 3654 * A Radar is found on current DFS Channel 3655 * while in CAC WAIT period So, do a channel 3656 * switch to randomly selected target channel. 3657 * Send the Channel change message to SME/PE. 3658 * sap_radar_found_status is set to 1 3659 */ 3660 sap_signal_hdd_event(t_sap_ctx, NULL, 3661 eSAP_DFS_RADAR_DETECT, 3662 (void *)eSAP_STATUS_SUCCESS); 3663 3664 wlansap_channel_change_request( 3665 (void *)t_sap_ctx, 3666 mac_ctx->sap.SapDfsInfo.target_channel); 3667 } 3668 } 3669 } else if (msg == eSAP_DFS_CHANNEL_CAC_END) { 3670 qdf_status = sap_cac_end_notify(hal, roam_info); 3671 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3672 /* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */ 3673 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3674 FL("from state %s => %s"), 3675 "eSAP_DFS_CAC_WAIT", "eSAP_DISCONNECTING"); 3676 3677 /* 3678 * Stop the CAC timer only in following conditions 3679 * single AP: if there is a single AP then stop the timer 3680 * mulitple APs: incase of multiple APs, make sure that 3681 * all APs are down. 3682 */ 3683 if (NULL == sap_find_valid_concurrent_session(hal)) { 3684 QDF_TRACE(QDF_MODULE_ID_SAP, 3685 QDF_TRACE_LEVEL_INFO_MED, 3686 FL("sapdfs: no sessions are valid, stopping timer")); 3687 sap_stop_dfs_cac_timer(sap_ctx); 3688 } 3689 3690 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 3691 qdf_status = sap_goto_disconnecting(sap_ctx); 3692 } else { 3693 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3694 FL("in state %s, invalid event msg %d"), 3695 "eSAP_DFS_CAC_WAIT", msg); 3696 } 3697 3698 return qdf_status; 3699 } 3700 3701 /** 3702 * sap_fsm_state_starting() - utility function called from sap fsm 3703 * @sap_ctx: SAP context 3704 * @sap_event: SAP event buffer 3705 * @mac_ctx: global MAC context 3706 * @hal: HAL handle 3707 * 3708 * This function is called for state transition from "eSAP_STARTING" 3709 * 3710 * Return: QDF_STATUS 3711 */ 3712 static QDF_STATUS sap_fsm_state_starting(ptSapContext sap_ctx, 3713 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3714 tHalHandle hal) 3715 { 3716 uint32_t msg = sap_event->event; 3717 tCsrRoamInfo *roam_info = (tCsrRoamInfo *) (sap_event->params); 3718 tSapDfsInfo *sap_dfs_info; 3719 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3720 uint8_t is_dfs = false; 3721 3722 if (msg == eSAP_MAC_START_BSS_SUCCESS) { 3723 /* 3724 * Transition from eSAP_STARTING to eSAP_STARTED 3725 * (both without substates) 3726 */ 3727 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3728 FL("from state channel = %d %s => %s ch_width %d"), 3729 sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED", 3730 sap_ctx->ch_params.ch_width); 3731 sap_ctx->sapsMachine = eSAP_STARTED; 3732 3733 /* Action code for transition */ 3734 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 3735 eSAP_START_BSS_EVENT, 3736 (void *) eSAP_STATUS_SUCCESS); 3737 3738 /* 3739 * The upper layers have been informed that AP is up and 3740 * running, however, the AP is still not beaconing, until 3741 * CAC is done if the operating channel is DFS 3742 */ 3743 if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { 3744 is_dfs = true; 3745 } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { 3746 if (cds_get_channel_state(sap_ctx->channel) == 3747 CHANNEL_STATE_DFS || 3748 cds_get_channel_state(sap_ctx-> 3749 ch_params.center_freq_seg1 - 3750 SIR_80MHZ_START_CENTER_CH_DIFF) == 3751 CHANNEL_STATE_DFS) 3752 is_dfs = true; 3753 } else { 3754 if (cds_get_channel_state(sap_ctx->channel) == 3755 CHANNEL_STATE_DFS) 3756 is_dfs = true; 3757 } 3758 3759 if (is_dfs) { 3760 sap_dfs_info = &mac_ctx->sap.SapDfsInfo; 3761 if ((false == sap_dfs_info->ignore_cac) && 3762 (eSAP_DFS_DO_NOT_SKIP_CAC == 3763 sap_dfs_info->cac_state) && 3764 !sap_ctx->pre_cac_complete) { 3765 /* Move the device in CAC_WAIT_STATE */ 3766 sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT; 3767 3768 /* 3769 * Need to stop the OS transmit queues, 3770 * so that no traffic can flow down the stack 3771 */ 3772 3773 /* Start CAC wait timer */ 3774 if (sap_dfs_info->is_dfs_cac_timer_running != 3775 true) 3776 sap_start_dfs_cac_timer(sap_ctx); 3777 qdf_status = sap_cac_start_notify(hal); 3778 3779 } else { 3780 wlansap_start_beacon_req(sap_ctx); 3781 } 3782 } 3783 } else if (msg == eSAP_MAC_START_FAILS) { 3784 /* 3785 * Transition from STARTING to DISCONNECTED 3786 * (both without substates) 3787 */ 3788 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3789 FL("from state %s => %s"), 3790 "eSAP_STARTING", "eSAP_DISCONNECTED"); 3791 3792 /*Action code for transition */ 3793 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3794 eSAP_START_BSS_EVENT, 3795 (void *) eSAP_STATUS_FAILURE); 3796 qdf_status = sap_goto_disconnected(sap_ctx); 3797 /* Advance outer statevar */ 3798 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3799 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3800 /* 3801 * Transition from eSAP_STARTING to eSAP_DISCONNECTED 3802 * (both without substates) 3803 */ 3804 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3805 FL("from state %s => %s"), 3806 "eSAP_STARTING", "eSAP_DISCONNECTED"); 3807 3808 /* Advance outer statevar */ 3809 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3810 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3811 eSAP_START_BSS_EVENT, 3812 (void *) eSAP_STATUS_FAILURE); 3813 qdf_status = sap_goto_disconnected(sap_ctx); 3814 /* Close the SME session */ 3815 3816 if (eSAP_TRUE == sap_ctx->isSapSessionOpen) { 3817 if (QDF_STATUS_SUCCESS == sap_close_session(hal, 3818 sap_ctx, NULL, false)) 3819 sap_ctx->isSapSessionOpen = eSAP_FALSE; 3820 } 3821 } else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) { 3822 /* The operating channel has changed, update hostapd */ 3823 sap_ctx->channel = 3824 (uint8_t) mac_ctx->sap.SapDfsInfo.target_channel; 3825 3826 sap_ctx->sapsMachine = eSAP_STARTED; 3827 3828 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3829 FL("from state %s => %s"), 3830 "eSAP_STARTING", "eSAP_STARTED"); 3831 3832 /* Indicate change in the state to upper layers */ 3833 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 3834 eSAP_START_BSS_EVENT, 3835 (void *)eSAP_STATUS_SUCCESS); 3836 } else { 3837 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3838 FL("in state %s, invalid event msg %d"), 3839 "eSAP_STARTING", msg); 3840 } 3841 3842 return qdf_status; 3843 } 3844 3845 /** 3846 * sap_fsm_state_started() - utility function called from sap fsm 3847 * @sap_ctx: SAP context 3848 * @sap_event: SAP event buffer 3849 * @mac_ctx: global MAC context 3850 * 3851 * This function is called for state transition from "eSAP_STARTED" 3852 * 3853 * Return: QDF_STATUS 3854 */ 3855 static QDF_STATUS sap_fsm_state_started(ptSapContext sap_ctx, 3856 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx) 3857 { 3858 uint32_t msg = sap_event->event; 3859 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3860 3861 if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3862 /* 3863 * Transition from eSAP_STARTED to eSAP_DISCONNECTING 3864 * (both without substates) 3865 */ 3866 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3867 FL("from state %s => %s"), 3868 "eSAP_STARTED", "eSAP_DISCONNECTING"); 3869 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 3870 qdf_status = sap_goto_disconnecting(sap_ctx); 3871 } else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) { 3872 uint8_t intf; 3873 /* 3874 * Radar is seen on the current operating channel 3875 * send CSA IE for all associated stations 3876 * Request for CSA IE transmission 3877 */ 3878 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3879 ptSapContext temp_sap_ctx; 3880 if (((QDF_SAP_MODE == 3881 mac_ctx->sap.sapCtxList[intf].sapPersona) || 3882 (QDF_P2P_GO_MODE == 3883 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 3884 mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) { 3885 temp_sap_ctx = 3886 mac_ctx->sap.sapCtxList[intf].pSapContext; 3887 QDF_TRACE(QDF_MODULE_ID_SAP, 3888 QDF_TRACE_LEVEL_INFO_MED, 3889 FL("sapdfs: Sending CSAIE for sapctx[%p]"), 3890 temp_sap_ctx); 3891 3892 qdf_status = wlansap_dfs_send_csa_ie_request( 3893 (void *) temp_sap_ctx); 3894 } 3895 } 3896 } else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) { 3897 enum tQDF_ADAPTER_MODE persona; 3898 3899 if (!sap_ctx) { 3900 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3901 FL("Invalid sap_ctx")); 3902 return qdf_status; 3903 } 3904 3905 persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId]. 3906 sapPersona; 3907 3908 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3909 FL("app trigger chan switch: mode:%d vdev:%d"), 3910 persona, sap_ctx->sessionId); 3911 3912 if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona)) 3913 qdf_status = wlansap_dfs_send_csa_ie_request( 3914 (void *) sap_ctx); 3915 } else { 3916 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3917 FL("in state %s, invalid event msg %d"), 3918 "eSAP_STARTED", msg); 3919 } 3920 3921 return qdf_status; 3922 } 3923 3924 /** 3925 * sap_fsm_state_disconnecting() - utility function called from sap fsm 3926 * @sap_ctx: SAP context 3927 * @sap_event: SAP event buffer 3928 * @mac_ctx: global MAC context 3929 * 3930 * This function is called for state transition from "eSAP_DISCONNECTING" 3931 * 3932 * Return: QDF_STATUS 3933 */ 3934 static QDF_STATUS sap_fsm_state_disconnecting(ptSapContext sap_ctx, 3935 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 3936 tHalHandle hal) 3937 { 3938 uint32_t msg = sap_event->event; 3939 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3940 3941 if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) { 3942 /* 3943 * Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED 3944 * (both without substates) 3945 */ 3946 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3947 FL("from state %s => %s"), 3948 "eSAP_DISCONNECTING", "eSAP_DISCONNECTED"); 3949 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 3950 3951 /* Close the SME session */ 3952 if (eSAP_TRUE == sap_ctx->isSapSessionOpen) { 3953 sap_ctx->isSapSessionOpen = eSAP_FALSE; 3954 qdf_status = sap_close_session(hal, sap_ctx, 3955 sap_roam_session_close_callback, true); 3956 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 3957 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3958 eSAP_STOP_BSS_EVENT, 3959 (void *)eSAP_STATUS_SUCCESS); 3960 } 3961 } 3962 } else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) { 3963 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3964 FL("sapdfs: Send channel change request on sapctx[%p]"), 3965 sap_ctx); 3966 /* 3967 * Most likely, radar has been detected and SAP wants to 3968 * change the channel 3969 */ 3970 qdf_status = wlansap_channel_change_request((void *) sap_ctx, 3971 mac_ctx->sap.SapDfsInfo.target_channel); 3972 3973 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3974 FL("Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ")); 3975 } else { 3976 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3977 FL("in state %s, invalid event msg %d"), 3978 "eSAP_DISCONNECTING", msg); 3979 } 3980 3981 return qdf_status; 3982 } 3983 3984 /** 3985 * sap_fsm() - SAP statem machine entry function 3986 * @sap_ctx: SAP context 3987 * @sap_event: SAP event 3988 * 3989 * SAP statem machine entry function 3990 * 3991 * Return: QDF_STATUS 3992 */ 3993 QDF_STATUS sap_fsm(ptSapContext sap_ctx, ptWLAN_SAPEvent sap_event) 3994 { 3995 /* 3996 * Retrieve the phy link state machine structure 3997 * from the sap_ctx value 3998 * state var that keeps track of state machine 3999 */ 4000 eSapFsmStates_t state_var = sap_ctx->sapsMachine; 4001 uint32_t msg = sap_event->event; /* State machine input event message */ 4002 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 4003 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 4004 tpAniSirGlobal mac_ctx; 4005 4006 if (NULL == hal) { 4007 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4008 FL("Invalid hal")); 4009 return QDF_STATUS_E_FAILURE; 4010 } 4011 4012 mac_ctx = PMAC_STRUCT(hal); 4013 if (NULL == mac_ctx) { 4014 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4015 FL("Invalid MAC context")); 4016 return QDF_STATUS_E_FAILURE; 4017 } 4018 4019 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 4020 FL("sap_ctx=%p, state_var=%d, msg=0x%x"), 4021 sap_ctx, state_var, msg); 4022 4023 switch (state_var) { 4024 case eSAP_DISCONNECTED: 4025 qdf_status = sap_fsm_state_disconnected(sap_ctx, sap_event, 4026 mac_ctx, hal); 4027 break; 4028 4029 case eSAP_CH_SELECT: 4030 qdf_status = sap_fsm_state_ch_select(sap_ctx, sap_event, 4031 mac_ctx, hal); 4032 break; 4033 4034 case eSAP_DFS_CAC_WAIT: 4035 qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event, 4036 mac_ctx, hal); 4037 break; 4038 4039 case eSAP_STARTING: 4040 qdf_status = sap_fsm_state_starting(sap_ctx, sap_event, 4041 mac_ctx, hal); 4042 break; 4043 4044 case eSAP_STARTED: 4045 qdf_status = sap_fsm_state_started(sap_ctx, sap_event, 4046 mac_ctx); 4047 break; 4048 4049 case eSAP_DISCONNECTING: 4050 qdf_status = sap_fsm_state_disconnecting(sap_ctx, sap_event, 4051 mac_ctx, hal); 4052 break; 4053 } 4054 return qdf_status; 4055 } 4056 4057 eSapStatus 4058 sapconvert_to_csr_profile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, 4059 tCsrRoamProfile *profile) 4060 { 4061 /* Create Roam profile for SoftAP to connect */ 4062 profile->BSSType = eCSR_BSS_TYPE_INFRA_AP; 4063 profile->SSIDs.numOfSSIDs = 1; 4064 profile->csrPersona = pconfig_params->persona; 4065 profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch; 4066 4067 qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId, 4068 sizeof(profile->SSIDs.SSIDList[0].SSID.ssId)); 4069 4070 /* Flag to not broadcast the SSID information */ 4071 profile->SSIDs.SSIDList[0].ssidHidden = 4072 pconfig_params->SSIDinfo.ssidHidden; 4073 4074 profile->SSIDs.SSIDList[0].SSID.length = 4075 pconfig_params->SSIDinfo.ssid.length; 4076 qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId, 4077 pconfig_params->SSIDinfo.ssid.ssId, 4078 sizeof(pconfig_params->SSIDinfo.ssid.ssId)); 4079 4080 profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; 4081 4082 if (pconfig_params->authType == eSAP_OPEN_SYSTEM) { 4083 profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; 4084 } else if (pconfig_params->authType == eSAP_SHARED_KEY) { 4085 profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY; 4086 } else { 4087 profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH; 4088 } 4089 4090 profile->AuthType.numEntries = 1; 4091 profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; 4092 4093 /* Always set the Encryption Type */ 4094 profile->EncryptionType.numEntries = 1; 4095 profile->EncryptionType.encryptionType[0] = 4096 pconfig_params->RSNEncryptType; 4097 4098 profile->mcEncryptionType.numEntries = 1; 4099 profile->mcEncryptionType.encryptionType[0] = 4100 pconfig_params->mcRSNEncryptType; 4101 4102 if (pconfig_params->privacy & eSAP_SHARED_KEY) { 4103 profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY; 4104 } 4105 4106 profile->privacy = pconfig_params->privacy; 4107 profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq; 4108 4109 if (pconfig_params->authType == eSAP_SHARED_KEY) { 4110 profile->csr80211AuthType = eSIR_SHARED_KEY; 4111 } else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) { 4112 profile->csr80211AuthType = eSIR_OPEN_SYSTEM; 4113 } else { 4114 profile->csr80211AuthType = eSIR_AUTO_SWITCH; 4115 } 4116 4117 /* Initialize we are not going to use it */ 4118 profile->pWPAReqIE = NULL; 4119 profile->nWPAReqIELength = 0; 4120 4121 /* set the RSN/WPA IE */ 4122 profile->pRSNReqIE = NULL; 4123 profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; 4124 if (pconfig_params->RSNWPAReqIELength) { 4125 profile->pRSNReqIE = 4126 qdf_mem_malloc(pconfig_params->RSNWPAReqIELength); 4127 if (NULL == profile->pRSNReqIE) { 4128 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4129 " %s Fail to alloc memory", __func__); 4130 return eSAP_STATUS_FAILURE; 4131 } 4132 qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE, 4133 pconfig_params->RSNWPAReqIELength); 4134 profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; 4135 } 4136 /* Turn off CB mode */ 4137 profile->CBMode = eCSR_CB_OFF; 4138 4139 /* set the phyMode to accept anything */ 4140 /* Best means everything because it covers all the things we support */ 4141 /* eCSR_DOT11_MODE_BEST */ 4142 profile->phyMode = pconfig_params->SapHw_mode; 4143 4144 /* Configure beaconInterval */ 4145 profile->beaconInterval = (uint16_t) pconfig_params->beacon_int; 4146 4147 /* set DTIM period */ 4148 profile->dtimPeriod = pconfig_params->dtim_period; 4149 4150 /* set Uapsd enable bit */ 4151 profile->ApUapsdEnable = pconfig_params->UapsdEnable; 4152 4153 /* Enable protection parameters */ 4154 profile->protEnabled = pconfig_params->protEnabled; 4155 profile->obssProtEnabled = pconfig_params->obssProtEnabled; 4156 profile->cfg_protection = pconfig_params->ht_capab; 4157 4158 /* country code */ 4159 if (pconfig_params->countryCode[0]) 4160 qdf_mem_copy(profile->countryCode, pconfig_params->countryCode, 4161 WNI_CFG_COUNTRY_CODE_LEN); 4162 profile->ieee80211d = pconfig_params->ieee80211d; 4163 /* wps config info */ 4164 profile->wps_state = pconfig_params->wps_state; 4165 4166 #ifdef WLAN_FEATURE_11W 4167 /* MFP capable/required */ 4168 profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0; 4169 profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0; 4170 #endif 4171 4172 if (pconfig_params->probeRespIEsBufferLen > 0 && 4173 pconfig_params->pProbeRespIEsBuffer != NULL) { 4174 profile->addIeParams.probeRespDataLen = 4175 pconfig_params->probeRespIEsBufferLen; 4176 profile->addIeParams.probeRespData_buff = 4177 pconfig_params->pProbeRespIEsBuffer; 4178 } else { 4179 profile->addIeParams.probeRespDataLen = 0; 4180 profile->addIeParams.probeRespData_buff = NULL; 4181 } 4182 /*assoc resp IE */ 4183 if (pconfig_params->assocRespIEsLen > 0 && 4184 pconfig_params->pAssocRespIEsBuffer != NULL) { 4185 profile->addIeParams.assocRespDataLen = 4186 pconfig_params->assocRespIEsLen; 4187 profile->addIeParams.assocRespData_buff = 4188 pconfig_params->pAssocRespIEsBuffer; 4189 } else { 4190 profile->addIeParams.assocRespDataLen = 0; 4191 profile->addIeParams.assocRespData_buff = NULL; 4192 } 4193 4194 if (pconfig_params->probeRespBcnIEsLen > 0 && 4195 pconfig_params->pProbeRespBcnIEsBuffer != NULL) { 4196 profile->addIeParams.probeRespBCNDataLen = 4197 pconfig_params->probeRespBcnIEsLen; 4198 profile->addIeParams.probeRespBCNData_buff = 4199 pconfig_params->pProbeRespBcnIEsBuffer; 4200 } else { 4201 profile->addIeParams.probeRespBCNDataLen = 0; 4202 profile->addIeParams.probeRespBCNData_buff = NULL; 4203 } 4204 profile->sap_dot11mc = pconfig_params->sap_dot11mc; 4205 4206 return eSAP_STATUS_SUCCESS; /* Success. */ 4207 } 4208 4209 void sap_free_roam_profile(tCsrRoamProfile *profile) 4210 { 4211 if (profile->pRSNReqIE) { 4212 qdf_mem_free(profile->pRSNReqIE); 4213 profile->pRSNReqIE = NULL; 4214 } 4215 } 4216 4217 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size) 4218 { 4219 uint8_t outer, inner; 4220 struct qdf_mac_addr temp; 4221 int32_t nRes = -1; 4222 4223 if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) { 4224 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4225 FL("either buffer is NULL or size = %d is more"), size); 4226 return; 4227 } 4228 4229 for (outer = 0; outer < size; outer++) { 4230 for (inner = 0; inner < size - 1; inner++) { 4231 nRes = 4232 qdf_mem_cmp((macList + inner)->bytes, 4233 (macList + inner + 1)->bytes, 4234 QDF_MAC_ADDR_SIZE); 4235 if (nRes > 0) { 4236 qdf_mem_copy(temp.bytes, 4237 (macList + inner + 1)->bytes, 4238 QDF_MAC_ADDR_SIZE); 4239 qdf_mem_copy((macList + inner + 1)->bytes, 4240 (macList + inner)->bytes, 4241 QDF_MAC_ADDR_SIZE); 4242 qdf_mem_copy((macList + inner)->bytes, 4243 temp.bytes, QDF_MAC_ADDR_SIZE); 4244 } 4245 } 4246 } 4247 } 4248 4249 eSapBool 4250 sap_search_mac_list(struct qdf_mac_addr *macList, 4251 uint8_t num_mac, uint8_t *peerMac, 4252 uint8_t *index) 4253 { 4254 int32_t nRes = -1; 4255 int8_t nStart = 0, nEnd, nMiddle; 4256 nEnd = num_mac - 1; 4257 4258 if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) { 4259 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4260 FL("either buffer is NULL or size = %d is more."), num_mac); 4261 return eSAP_FALSE; 4262 } 4263 4264 while (nStart <= nEnd) { 4265 nMiddle = (nStart + nEnd) / 2; 4266 nRes = 4267 qdf_mem_cmp(&macList[nMiddle], peerMac, 4268 QDF_MAC_ADDR_SIZE); 4269 4270 if (0 == nRes) { 4271 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4272 "search SUCC"); 4273 /* "index equals NULL" means the caller does not need the */ 4274 /* index value of the peerMac being searched */ 4275 if (index != NULL) { 4276 *index = (uint8_t) nMiddle; 4277 QDF_TRACE(QDF_MODULE_ID_SAP, 4278 QDF_TRACE_LEVEL_INFO_HIGH, "index %d", 4279 *index); 4280 } 4281 return eSAP_TRUE; 4282 } 4283 if (nRes < 0) 4284 nStart = nMiddle + 1; 4285 else 4286 nEnd = nMiddle - 1; 4287 } 4288 4289 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4290 "search not succ"); 4291 return eSAP_FALSE; 4292 } 4293 4294 void sap_add_mac_to_acl(struct qdf_mac_addr *macList, 4295 uint8_t *size, uint8_t *peerMac) 4296 { 4297 int32_t nRes = -1; 4298 int i; 4299 4300 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4301 "add acl entered"); 4302 4303 if (NULL == macList || *size == 0 || *size > MAX_ACL_MAC_ADDRESS) { 4304 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4305 FL("either buffer is NULL or size = %d is incorrect."), 4306 *size); 4307 return; 4308 } 4309 4310 for (i = ((*size) - 1); i >= 0; i--) { 4311 nRes = 4312 qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE); 4313 if (nRes > 0) { 4314 /* Move alphabetically greater mac addresses one index down to allow for insertion 4315 of new mac in sorted order */ 4316 qdf_mem_copy((macList + i + 1)->bytes, 4317 (macList + i)->bytes, QDF_MAC_ADDR_SIZE); 4318 } else { 4319 break; 4320 } 4321 } 4322 /* This should also take care of if the element is the first to be added in the list */ 4323 qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE); 4324 /* increment the list size */ 4325 (*size)++; 4326 } 4327 4328 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList, 4329 uint8_t *size, uint8_t index) 4330 { 4331 int i; 4332 4333 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4334 "remove acl entered"); 4335 /* 4336 * Return if the list passed is empty. Ideally this should never happen 4337 * since this funcn is always called after sap_search_mac_list to get 4338 * the index of the mac addr to be removed and this will only get 4339 * called if the search is successful. Still no harm in having the check 4340 */ 4341 if ((macList == NULL) || (*size == 0) || 4342 (*size > MAX_ACL_MAC_ADDRESS)) { 4343 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4344 FL("either buffer is NULL or size %d is incorrect."), 4345 *size); 4346 return; 4347 } 4348 for (i = index; i < ((*size) - 1); i++) { 4349 /* Move mac addresses starting from "index" passed one index up to delete the void 4350 created by deletion of a mac address in ACL */ 4351 qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes, 4352 QDF_MAC_ADDR_SIZE); 4353 } 4354 /* The last space should be made empty since all mac addesses moved one step up */ 4355 qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE); 4356 /* reduce the list size by 1 */ 4357 (*size)--; 4358 } 4359 4360 void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size) 4361 { 4362 int i; 4363 uint8_t *macArray; 4364 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4365 "print acl entered"); 4366 4367 if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) { 4368 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4369 "In %s, either buffer is NULL or size %d is incorrect.", 4370 __func__, size); 4371 return; 4372 } 4373 4374 for (i = 0; i < size; i++) { 4375 macArray = (macList + i)->bytes; 4376 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4377 "** ACL entry %i - " MAC_ADDRESS_STR, i, 4378 MAC_ADDR_ARRAY(macArray)); 4379 } 4380 return; 4381 } 4382 4383 QDF_STATUS sap_is_peer_mac_allowed(ptSapContext sapContext, uint8_t *peerMac) 4384 { 4385 if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode) 4386 return QDF_STATUS_SUCCESS; 4387 4388 if (sap_search_mac_list 4389 (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL)) 4390 return QDF_STATUS_SUCCESS; 4391 4392 if (sap_search_mac_list 4393 (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) { 4394 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4395 "In %s, Peer " MAC_ADDRESS_STR " in deny list", 4396 __func__, MAC_ADDR_ARRAY(peerMac)); 4397 return QDF_STATUS_E_FAILURE; 4398 } 4399 /* A new station CAN associate, unless in deny list. Less stringent mode */ 4400 if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode) 4401 return QDF_STATUS_SUCCESS; 4402 4403 /* A new station CANNOT associate, unless in accept list. More stringent mode */ 4404 if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) { 4405 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4406 "In %s, Peer " MAC_ADDRESS_STR 4407 " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED", 4408 __func__, MAC_ADDR_ARRAY(peerMac)); 4409 return QDF_STATUS_E_FAILURE; 4410 } 4411 4412 /* The new STA is neither in accept list nor in deny list. In this case, deny the association 4413 * but send a wifi event notification indicating the mac address being denied 4414 */ 4415 if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) { 4416 sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN, 4417 (void *) peerMac); 4418 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 4419 "In %s, Peer " MAC_ADDRESS_STR 4420 " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY", 4421 __func__, MAC_ADDR_ARRAY(peerMac)); 4422 return QDF_STATUS_E_FAILURE; 4423 } 4424 return QDF_STATUS_SUCCESS; 4425 } 4426 4427 #ifdef SOFTAP_CHANNEL_RANGE 4428 /** 4429 * sap_get_channel_list() - get the list of channels 4430 * @sap_ctx: sap context 4431 * @ch_list: pointer to channel list array 4432 * @num_ch: pointer to number of channels. 4433 * 4434 * This function populates the list of channels for scanning. 4435 * 4436 * Return: QDF_STATUS 4437 */ 4438 static QDF_STATUS sap_get_channel_list(ptSapContext sap_ctx, 4439 uint8_t **ch_list, 4440 uint8_t *num_ch) 4441 { 4442 uint8_t loop_count; 4443 uint8_t *list; 4444 uint8_t ch_count; 4445 uint8_t start_ch_num, band_start_ch; 4446 uint8_t end_ch_num, band_end_ch; 4447 uint32_t en_lte_coex; 4448 tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); 4449 #ifdef FEATURE_WLAN_CH_AVOID 4450 uint8_t i; 4451 #endif 4452 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 4453 4454 if (NULL == hal) { 4455 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4456 FL("Invalid HAL pointer from p_cds_gctx")); 4457 *num_ch = 0; 4458 *ch_list = NULL; 4459 return QDF_STATUS_E_FAULT; 4460 } 4461 4462 start_ch_num = sap_ctx->acs_cfg->start_ch; 4463 end_ch_num = sap_ctx->acs_cfg->end_ch; 4464 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 4465 FL("startChannel %d, EndChannel %d, HW:%d"), 4466 start_ch_num, end_ch_num, 4467 sap_ctx->acs_cfg->hw_mode); 4468 4469 wlansap_extend_to_acs_range(&start_ch_num, &end_ch_num, 4470 &band_start_ch, &band_end_ch); 4471 4472 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 4473 FL("expanded startChannel %d,EndChannel %d"), 4474 start_ch_num, end_ch_num); 4475 4476 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 4477 FL("band_start_ch %d, band_end_ch %d"), 4478 band_start_ch, band_end_ch); 4479 4480 sme_cfg_get_int(hal, WNI_CFG_ENABLE_LTE_COEX, &en_lte_coex); 4481 4482 /* Check if LTE coex is enabled and 2.4GHz is selected */ 4483 if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) && 4484 (band_end_ch == CHAN_ENUM_14)) { 4485 /* Set 2.4GHz upper limit to channel 9 for LTE COEX */ 4486 band_end_ch = CHAN_ENUM_9; 4487 } 4488 4489 /* Allocate the max number of channel supported */ 4490 list = (uint8_t *) qdf_mem_malloc(NUM_5GHZ_CHANNELS + 4491 NUM_24GHZ_CHANNELS); 4492 if (NULL == list) { 4493 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4494 FL("Unable to allocate channel list")); 4495 *num_ch = 0; 4496 *ch_list = NULL; 4497 return QDF_STATUS_E_NOMEM; 4498 } 4499 4500 /* Search for the Active channels in the given range */ 4501 ch_count = 0; 4502 for (loop_count = band_start_ch; loop_count <= band_end_ch; 4503 loop_count++) { 4504 /* go to next channel if rf_channel is out of range */ 4505 if ((start_ch_num > CDS_CHANNEL_NUM(loop_count)) || 4506 (end_ch_num < CDS_CHANNEL_NUM(loop_count))) 4507 continue; 4508 /* 4509 * go to next channel if none of these condition pass 4510 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE 4511 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE 4512 */ 4513 if (!(((eSAP_TRUE == mac_ctx->scan.fEnableDFSChnlScan) && 4514 CDS_CHANNEL_STATE(loop_count)) || 4515 ((eSAP_FALSE == mac_ctx->scan.fEnableDFSChnlScan) && 4516 (CHANNEL_STATE_ENABLE == 4517 CDS_CHANNEL_STATE(loop_count))))) 4518 continue; 4519 4520 #ifdef FEATURE_WLAN_CH_AVOID 4521 for (i = 0; i < NUM_CHANNELS; i++) { 4522 if ((safe_channels[i].channelNumber == 4523 CDS_CHANNEL_NUM(loop_count))) { 4524 /* Check if channel is safe */ 4525 if (true == safe_channels[i].isSafe) { 4526 #endif 4527 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 4528 uint8_t ch; 4529 ch = CDS_CHANNEL_NUM(loop_count); 4530 if ((sap_ctx->acs_cfg->skip_scan_status == 4531 eSAP_DO_PAR_ACS_SCAN)) { 4532 if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch && 4533 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) || 4534 (ch >= sap_ctx->acs_cfg->skip_scan_range2_stch && 4535 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) { 4536 list[ch_count] = 4537 CDS_CHANNEL_NUM(loop_count); 4538 ch_count++; 4539 QDF_TRACE(QDF_MODULE_ID_SAP, 4540 QDF_TRACE_LEVEL_INFO, 4541 FL("%d %d added to ACS ch range"), 4542 ch_count, ch); 4543 } else { 4544 QDF_TRACE(QDF_MODULE_ID_SAP, 4545 QDF_TRACE_LEVEL_INFO_HIGH, 4546 FL("%d %d skipped from ACS ch range"), 4547 ch_count, ch); 4548 } 4549 } else { 4550 list[ch_count] = 4551 CDS_CHANNEL_NUM(loop_count); 4552 ch_count++; 4553 QDF_TRACE(QDF_MODULE_ID_SAP, 4554 QDF_TRACE_LEVEL_INFO, 4555 FL("%d %d added to ACS ch range"), 4556 ch_count, ch); 4557 } 4558 #else 4559 list[ch_count] = CDS_CHANNEL_NUM(loop_count); 4560 ch_count++; 4561 #endif 4562 #ifdef FEATURE_WLAN_CH_AVOID 4563 } 4564 break; 4565 } 4566 } 4567 #endif 4568 } 4569 if (0 == ch_count) { 4570 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4571 FL("No active channels present for the current region")); 4572 /* 4573 * LTE COEX: channel range outside the restricted 2.4GHz 4574 * band limits 4575 */ 4576 if (en_lte_coex && (start_ch_num > band_end_ch)) 4577 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 4578 FL("SAP can't be started as due to LTE COEX")); 4579 } 4580 4581 /* return the channel list and number of channels to scan */ 4582 *num_ch = ch_count; 4583 if (ch_count != 0) { 4584 *ch_list = list; 4585 } else { 4586 *ch_list = NULL; 4587 qdf_mem_free(list); 4588 } 4589 4590 for (loop_count = 0; loop_count < ch_count; loop_count++) { 4591 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 4592 FL("channel number: %d"), list[loop_count]); 4593 } 4594 return QDF_STATUS_SUCCESS; 4595 } 4596 #endif 4597 4598 /* 4599 * Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] 4600 * available channels in the current regulatory domain. 4601 */ 4602 static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext) 4603 { 4604 uint8_t count = 0; 4605 int i; 4606 struct sir_pcl_list pcl; 4607 QDF_STATUS status; 4608 enum channel_state ch_state; 4609 pcl.pcl_len = 0; 4610 if (NULL == sapContext) { 4611 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4612 "Invalid sapContext pointer on sap_get_channel_list"); 4613 return QDF_STATUS_E_FAULT; 4614 } 4615 4616 if (sapContext->SapAllChnlList.channelList) { 4617 qdf_mem_free(sapContext->SapAllChnlList.channelList); 4618 sapContext->SapAllChnlList.channelList = NULL; 4619 } 4620 4621 sapContext->SapAllChnlList.channelList = 4622 (tChannelInfo *) qdf_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN * 4623 sizeof(tChannelInfo)); 4624 if (NULL == sapContext->SapAllChnlList.channelList) { 4625 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4626 " Memory Allocation failed sap_get_channel_list"); 4627 return QDF_STATUS_E_NOMEM; 4628 } 4629 4630 status = cds_get_pcl_for_existing_conn(CDS_SAP_MODE, 4631 pcl.pcl_list, &pcl.pcl_len, 4632 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); 4633 if (status != QDF_STATUS_SUCCESS) { 4634 cds_err("Get PCL failed"); 4635 return status; 4636 } 4637 for (i = 0; i <= pcl.pcl_len; i++) { 4638 if (CDS_IS_CHANNEL_5GHZ(pcl.pcl_list[i])) { 4639 ch_state = cds_get_channel_state(pcl.pcl_list[i]); 4640 if (!(ch_state == CHANNEL_STATE_ENABLE || 4641 ch_state == CHANNEL_STATE_DFS)) 4642 continue; 4643 sapContext->SapAllChnlList.channelList[count].channel = 4644 pcl.pcl_list[i]; 4645 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 4646 "%s[%d] CHANNEL = %d", __func__, __LINE__, 4647 pcl.pcl_list[i]); 4648 sapContext->SapAllChnlList.channelList[count].valid = 4649 true; 4650 count++; 4651 } 4652 } 4653 4654 sapContext->SapAllChnlList.numChannel = count; 4655 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 4656 "%s[%d] NUMBER OF CHANNELS count = %d" 4657 "sapContext->SapAllChnlList.numChannel = %d", 4658 __func__, __LINE__, count, 4659 sapContext->SapAllChnlList.numChannel); 4660 return QDF_STATUS_SUCCESS; 4661 } 4662 4663 /* 4664 * This function randomly selects the channel to switch after the detection 4665 * of radar 4666 * param sapContext - sap context 4667 * dfs_event - Dfs information from DFS 4668 * return - channel to which AP wishes to switch 4669 */ 4670 uint8_t sap_indicate_radar(ptSapContext sapContext, 4671 tSirSmeDfsEventInd *dfs_event) 4672 { 4673 uint8_t target_channel = 0; 4674 tHalHandle hHal; 4675 tpAniSirGlobal pMac; 4676 4677 if (NULL == sapContext || NULL == dfs_event) { 4678 /* Invalid sap context of dfs event passed */ 4679 return 0; 4680 } 4681 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 4682 4683 if (NULL == hHal) { 4684 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4685 "In %s invalid hHal", __func__); 4686 return 0; 4687 } 4688 pMac = PMAC_STRUCT(hHal); 4689 4690 if (!dfs_event->dfs_radar_status) { 4691 /*dfs status does not indicate a radar on the channel-- False Alarm */ 4692 return 0; 4693 } 4694 4695 /* 4696 * SAP needs to generate Channel Switch IE 4697 * if the radar is found in the STARTED state 4698 */ 4699 if (eSAP_STARTED == sapContext->sapsMachine) 4700 pMac->sap.SapDfsInfo.csaIERequired = eSAP_TRUE; 4701 4702 if (sapContext->csr_roamProfile.disableDFSChSwitch) { 4703 return sapContext->channel; 4704 } 4705 4706 /* set the Radar Found flag in SapDfsInfo */ 4707 pMac->sap.SapDfsInfo.sap_radar_found_status = true; 4708 4709 if (dfs_event->chan_list.nchannels > SIR_DFS_MAX_20M_SUB_CH) { 4710 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 4711 FL("nchannels >SIR_DFS_MAX_20M_SUB_CH so resetting")); 4712 dfs_event->chan_list.nchannels = SIR_DFS_MAX_20M_SUB_CH; 4713 } 4714 4715 sap_mark_dfs_channels(sapContext, dfs_event->chan_list.channels, 4716 dfs_event->chan_list.nchannels, 4717 cds_get_monotonic_boottime()); 4718 4719 if (sapContext->chan_before_pre_cac) { 4720 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 4721 FL("sapdfs: set chan before pre cac %d as target chan"), 4722 sapContext->chan_before_pre_cac); 4723 return sapContext->chan_before_pre_cac; 4724 } 4725 4726 /* 4727 * (1) skip static turbo channel as it will require STA to be in 4728 * static turbo to work. 4729 * (2) skip channel which's marked with radar detction 4730 * (3) WAR: we allow user to config not to use any DFS channel 4731 * (4) When we pick a channel, skip excluded 11D channels 4732 * (5) Create the available channel list with the above rules 4733 */ 4734 4735 target_channel = sap_random_channel_sel(sapContext); 4736 if (0 == target_channel) { 4737 sap_signal_hdd_event(sapContext, NULL, 4738 eSAP_DFS_NO_AVAILABLE_CHANNEL, 4739 (void *) eSAP_STATUS_SUCCESS); 4740 } 4741 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 4742 FL("sapdfs: New selected target channel is [%d]"), 4743 target_channel); 4744 return target_channel; 4745 } 4746 4747 /* 4748 * CAC timer callback function. 4749 * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm(). 4750 */ 4751 void sap_dfs_cac_timer_callback(void *data) 4752 { 4753 ptSapContext sapContext; 4754 tWLAN_SAPEvent sapEvent; 4755 tHalHandle hHal = (tHalHandle) data; 4756 tpAniSirGlobal pMac; 4757 4758 if (NULL == hHal) { 4759 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4760 "In %s invalid hHal", __func__); 4761 return; 4762 } 4763 pMac = PMAC_STRUCT(hHal); 4764 sapContext = sap_find_cac_wait_session(hHal); 4765 if (NULL == sapContext) { 4766 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4767 "%s: no SAP contexts in wait state", __func__); 4768 return; 4769 } 4770 4771 /* 4772 * SAP may not be in CAC wait state, when the timer runs out. 4773 * if following flag is set, then timer is in initialized state, 4774 * destroy timer here. 4775 */ 4776 if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) { 4777 qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 4778 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 4779 } 4780 4781 /* 4782 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm 4783 */ 4784 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 4785 "sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%p]", 4786 sapContext->channel, sapContext); 4787 4788 sapEvent.event = eSAP_DFS_CHANNEL_CAC_END; 4789 sapEvent.params = 0; 4790 sapEvent.u1 = 0; 4791 sapEvent.u2 = 0; 4792 4793 sap_fsm(sapContext, &sapEvent); 4794 } 4795 4796 /* 4797 * Function to stop the DFS CAC Timer 4798 */ 4799 static int sap_stop_dfs_cac_timer(ptSapContext sapContext) 4800 { 4801 tHalHandle hHal; 4802 tpAniSirGlobal pMac; 4803 if (sapContext == NULL) 4804 return 0; 4805 4806 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 4807 if (NULL == hHal) { 4808 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4809 "In %s invalid hHal", __func__); 4810 return 0; 4811 } 4812 pMac = PMAC_STRUCT(hHal); 4813 4814 if (QDF_TIMER_STATE_RUNNING != 4815 qdf_mc_timer_get_current_state(&pMac->sap.SapDfsInfo. 4816 sap_dfs_cac_timer)) { 4817 return 0; 4818 } 4819 4820 qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 4821 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 4822 qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 4823 4824 return 0; 4825 } 4826 4827 4828 /** 4829 * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding. 4830 * @sap_context: SAP context 4831 * 4832 * Check if the current SAP operating channel is bonded to weather radar 4833 * channel in ETSI domain. 4834 * 4835 * Return: True if bonded to weather channel in ETSI 4836 */ 4837 static bool 4838 sap_is_channel_bonding_etsi_weather_channel(ptSapContext sap_context) 4839 { 4840 if (IS_CH_BONDING_WITH_WEATHER_CH(sap_context->channel) && 4841 (sap_context->ch_params.ch_width != CH_WIDTH_20MHZ)) 4842 return true; 4843 4844 return false; 4845 } 4846 4847 /* 4848 * Function to start the DFS CAC Timer 4849 * when SAP is started on a DFS channel 4850 */ 4851 int sap_start_dfs_cac_timer(ptSapContext sapContext) 4852 { 4853 QDF_STATUS status; 4854 uint32_t cacTimeOut; 4855 tHalHandle hHal = NULL; 4856 tpAniSirGlobal pMac = NULL; 4857 enum dfs_region dfs_region; 4858 4859 if (sapContext == NULL) { 4860 return 0; 4861 } 4862 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 4863 4864 if (NULL == hHal) { 4865 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4866 "In %s invalid hHal", __func__); 4867 return 0; 4868 } 4869 pMac = PMAC_STRUCT(hHal); 4870 4871 if (pMac->sap.SapDfsInfo.ignore_cac) { 4872 /* 4873 * If User has set to ignore the CAC 4874 * so, continue without CAC Timer. 4875 */ 4876 return 2; 4877 } 4878 cacTimeOut = DEFAULT_CAC_TIMEOUT; 4879 4880 cds_get_dfs_region(&dfs_region); 4881 4882 if ((dfs_region == DFS_ETSI_REGION) 4883 && ((IS_ETSI_WEATHER_CH(sapContext->channel)) || 4884 (sap_is_channel_bonding_etsi_weather_channel(sapContext)))) { 4885 cacTimeOut = ETSI_WEATHER_CH_CAC_TIMEOUT; 4886 } 4887 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 4888 "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH - %d, CAC TIMEOUT - %d sec", 4889 sapContext->channel, cacTimeOut / 1000); 4890 4891 qdf_mc_timer_init(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer, 4892 QDF_TIMER_TYPE_SW, 4893 sap_dfs_cac_timer_callback, (void *) hHal); 4894 4895 /*Start the CAC timer */ 4896 status = 4897 qdf_mc_timer_start(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer, 4898 cacTimeOut); 4899 if (status == QDF_STATUS_SUCCESS) { 4900 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = true; 4901 return 1; 4902 } else { 4903 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 4904 qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 4905 return 0; 4906 } 4907 } 4908 4909 /* 4910 * This function initializes the NOL list 4911 * parameters required to track the radar 4912 * found DFS channels in the current Reg. Domain . 4913 */ 4914 QDF_STATUS sap_init_dfs_channel_nol_list(ptSapContext sapContext) 4915 { 4916 uint8_t count = 0; 4917 int i; 4918 bool bFound = false; 4919 tHalHandle hHal; 4920 tpAniSirGlobal pMac; 4921 4922 if (NULL == sapContext) { 4923 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4924 "Invalid sapContext pointer on sap_init_dfs_channel_nol_list"); 4925 return QDF_STATUS_E_FAULT; 4926 } 4927 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 4928 4929 if (NULL == hHal) { 4930 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 4931 "In %s invalid hHal", __func__); 4932 return QDF_STATUS_E_FAULT; 4933 } 4934 pMac = PMAC_STRUCT(hHal); 4935 4936 /* to indicate hdd to get cnss dfs nol */ 4937 if (QDF_STATUS_SUCCESS == sap_signal_hdd_event(sapContext, NULL, 4938 eSAP_DFS_NOL_GET, 4939 (void *) 4940 eSAP_STATUS_SUCCESS)) { 4941 bFound = true; 4942 } 4943 4944 for (i = CHAN_ENUM_36; i <= CHAN_ENUM_165; i++) { 4945 if (CDS_CHANNEL_STATE(i) == CHANNEL_STATE_DFS) { 4946 /* if dfs nol is not found, initialize it */ 4947 if (!bFound) { 4948 pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] 4949 .dfs_channel_number = 4950 CDS_CHANNEL_NUM(i); 4951 4952 QDF_TRACE(QDF_MODULE_ID_SAP, 4953 QDF_TRACE_LEVEL_INFO_LOW, 4954 "%s: CHANNEL = %d", __func__, 4955 pMac->sap.SapDfsInfo. 4956 sapDfsChannelNolList[count]. 4957 dfs_channel_number); 4958 4959 pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] 4960 .radar_status_flag = 4961 eSAP_DFS_CHANNEL_USABLE; 4962 pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] 4963 .radar_found_timestamp = 0; 4964 } 4965 count++; 4966 } 4967 } 4968 4969 pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels = count; 4970 4971 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 4972 "%s[%d] NUMBER OF DFS CHANNELS = %d", 4973 __func__, __LINE__, 4974 pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels); 4975 4976 return QDF_STATUS_SUCCESS; 4977 } 4978 4979 /* 4980 * This function will calculate how many interfaces 4981 * have sap persona and returns total number of sap persona. 4982 */ 4983 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal) 4984 { 4985 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 4986 uint8_t intf = 0; 4987 uint8_t intf_count = 0; 4988 4989 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 4990 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 4991 || 4992 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 4993 && pMac->sap.sapCtxList[intf].pSapContext != NULL) { 4994 intf_count++; 4995 } 4996 } 4997 return intf_count; 4998 } 4999 5000 /* 5001 * This function will find the concurrent sap context apart from 5002 * passed sap context and return its channel change ready status 5003 */ 5004 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal, 5005 ptSapContext sapContext) 5006 { 5007 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 5008 ptSapContext pSapContext; 5009 uint8_t intf = 0; 5010 5011 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 5012 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 5013 || 5014 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 5015 && pMac->sap.sapCtxList[intf].pSapContext != NULL) { 5016 pSapContext = 5017 (ptSapContext) pMac->sap.sapCtxList[intf]. 5018 pSapContext; 5019 if (pSapContext == sapContext) { 5020 QDF_TRACE(QDF_MODULE_ID_SAP, 5021 QDF_TRACE_LEVEL_ERROR, 5022 FL("sapCtx matched [%p]"), 5023 sapContext); 5024 continue; 5025 } else { 5026 QDF_TRACE(QDF_MODULE_ID_SAP, 5027 QDF_TRACE_LEVEL_ERROR, 5028 FL 5029 ("concurrent sapCtx[%p] didn't matche with [%p]"), 5030 pSapContext, sapContext); 5031 return pSapContext->is_sap_ready_for_chnl_chng; 5032 } 5033 } 5034 } 5035 return false; 5036 } 5037