blob: 3a258830910d038967bd89bd45007c9e10b2e042 [file] [log] [blame]
/*
* Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*===========================================================================
s a p F s m . C
OVERVIEW:
This software unit holds the implementation of the WLAN SAP Finite
State Machine modules
DEPENDENCIES:
Are listed for each API below.
===========================================================================*/
/*===========================================================================
EDIT HISTORY FOR FILE
This section contains comments describing changes made to the module.
Notice that changes are listed in reverse chronological order.
when who what, where, why
---------- --- --------------------------------------------------------
2010-03-15 Created module
===========================================================================*/
/*----------------------------------------------------------------------------
* Include Files
* -------------------------------------------------------------------------*/
#include "sapInternal.h"
// Pick up the SME API definitions
#include "sme_Api.h"
#include "smeInside.h"
// Pick up the PMC API definitions
#include "pmcApi.h"
#include "wlan_nv.h"
#include "vos_utils.h"
#include "_ieee80211_common.h"
/*----------------------------------------------------------------------------
* Preprocessor Definitions and Constants
* -------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* Type Declarations
* -------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* Global Data Definitions
* -------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* External declarations for global context
* -------------------------------------------------------------------------*/
#ifdef FEATURE_WLAN_CH_AVOID
extern sapSafeChannelType safeChannels[];
#endif /* FEATURE_WLAN_CH_AVOID */
/*----------------------------------------------------------------------------
* Static Variable Definitions
* -------------------------------------------------------------------------*/
#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
/*
* TODO: At present SAP Channel leakage matrix for ch 144
* is not available from system's team. So to play it safe
* and avoid crash if channel 144 is request, in following
* matix channel 144 is added such that it will cause code
* to avoid selecting channel 144.
*
* THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS
* PROVIDED BY SYSTEM'S TEAM.
*/
/* channel tx leakage table - ht80 */
tSapChanMatrixInfo ht80_chan[] =
{
{52,
{{36, 148}, {40, 199},
{44, 193}, {48, 197},
{52, SAP_TX_LEAKAGE_MIN}, {56, 153},
{60, 137}, {64, 134},
{100, 358}, {104, 350},
{108, 404}, {112, 344},
{116, 424}, {120, 429},
{124, 437}, {128, 435},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{56,
{{36, 171}, {40, 178},
{44, 171}, {48, 178},
{52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
{60, SAP_TX_LEAKAGE_MIN}, {64, 280},
{100, 351}, {104, 376},
{108, 362}, {112, 362},
{116, 403}, {120, 397},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{60,
{{36, 156}, {40, 146},
{44, SAP_TX_LEAKAGE_MIN}, {48, SAP_TX_LEAKAGE_MIN},
{52, 180}, {56, SAP_TX_LEAKAGE_MIN},
{60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
{100, 376}, {104, 360},
{108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX},
{116, 395}, {120, 399},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{64,
{{36, 217}, {40, 221},
{44, SAP_TX_LEAKAGE_MIN}, {48, SAP_TX_LEAKAGE_MIN},
{52, 176}, {56, 176},
{60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
{100, 384}, {104, 390},
{108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX},
{116, 375}, {120, 374},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{100,
{{36, 357}, {40, 326},
{44, 321}, {48, 326},
{52, 378}, {56, 396},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN},
{108, 196}, {112, 116},
{116, 166}, {120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{104,
{{36, 325}, {40, 325},
{44, 305}, {48, 352},
{52, 411}, {56, 411},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN},
{108, SAP_TX_LEAKAGE_MIN},{112, 460},
{116, 198}, {120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{108,
{{36, 304}, {40, 332},
{44, 310}, {48, 335},
{52, 431}, {56, 391},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 280}, {104, SAP_TX_LEAKAGE_MIN},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, 185}, {120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{112,
{{36, 327}, {40, 335},
{44, 331}, {48, 345},
{52, 367}, {56, 401},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 131}, {104, 132},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, 189}, {120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{116,
{{36, 384}, {40, 372},
{44, 389}, {48, 396},
{52, 348}, {56, 336},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 172}, {104, 169},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{120,
{{36, 395}, {40, 419},
{44, 439}, {48, 407},
{52, 321}, {56, 334},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 134}, {104, 186},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, 159},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{124,
{{36, 469}, {40, 433},
{44, 434}, {48, 435},
{52, 332}, {56, 345},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 146}, {104, 177},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, 350}, {120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, 138},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{128,
{{36, 408}, {40, 434},
{44, 449}, {48, 444},
{52, 341}, {56, 374},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 205}, {104, 208},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, 142}, {120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{132,
{{36, SAP_TX_LEAKAGE_MAX }, {40, SAP_TX_LEAKAGE_MAX },
{44, SAP_TX_LEAKAGE_MAX }, {48, SAP_TX_LEAKAGE_MAX },
{52, SAP_TX_LEAKAGE_MAX }, {56, SAP_TX_LEAKAGE_MAX },
{60, SAP_TX_LEAKAGE_MIN }, {64, SAP_TX_LEAKAGE_MIN },
{100, SAP_TX_LEAKAGE_MIN },{104, SAP_TX_LEAKAGE_MIN },
{108, SAP_TX_LEAKAGE_MIN }, {112, SAP_TX_LEAKAGE_MIN },
{116, SAP_TX_LEAKAGE_MIN },{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN }
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{136,
{{36, SAP_TX_LEAKAGE_MAX }, {40, SAP_TX_LEAKAGE_MAX },
{44, SAP_TX_LEAKAGE_MAX }, {48, SAP_TX_LEAKAGE_MAX },
{52, SAP_TX_LEAKAGE_MAX }, {56, SAP_TX_LEAKAGE_MAX },
{60, SAP_TX_LEAKAGE_MIN }, {64, SAP_TX_LEAKAGE_MIN },
{100, SAP_TX_LEAKAGE_MIN },{104, SAP_TX_LEAKAGE_MIN },
{108, SAP_TX_LEAKAGE_MIN },{112, SAP_TX_LEAKAGE_MIN },
{116, SAP_TX_LEAKAGE_MIN }, {120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN }
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{140,
{{36, SAP_TX_LEAKAGE_MAX }, {40, SAP_TX_LEAKAGE_MAX },
{44, SAP_TX_LEAKAGE_MAX }, {48, SAP_TX_LEAKAGE_MAX },
{52, SAP_TX_LEAKAGE_MAX }, {56, SAP_TX_LEAKAGE_MAX },
{60, SAP_TX_LEAKAGE_MIN }, {64, SAP_TX_LEAKAGE_MIN },
{100, SAP_TX_LEAKAGE_MIN },{104, SAP_TX_LEAKAGE_MIN },
{108, SAP_TX_LEAKAGE_MIN },{112, SAP_TX_LEAKAGE_MIN },
{116, SAP_TX_LEAKAGE_MIN }, {120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
#ifdef FEATURE_WLAN_CH144
{144,
{{36, 695}, {40, 695 },
{44, 684}, {48, 684 },
{52, 664}, {56, 664 },
{60, 658}, {64, 658 },
{100, 601},{104, 601 },
{108, 545},{112, 545 },
{116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
{124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
{132, 262},{136, 262},
{140, SAP_TX_LEAKAGE_MIN},
{144, SAP_TX_LEAKAGE_MIN}
}},
#endif
};
/* channel tx leakage table - ht40 */
tSapChanMatrixInfo ht40_chan[] =
{
{52,
{{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
{44, 230}, {48, 230 },
{52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
{60, SAP_TX_LEAKAGE_AUTO_MIN}, {64, SAP_TX_LEAKAGE_AUTO_MIN},
{100, 625}, {104, 323 },
{108, 646},{112, 646 },
{116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{56,
{{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
{44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN},
{52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
{60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
{100, 611},{104, 611 },
{108, 617},{112, 617 },
{116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{60,
{{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40,SAP_TX_LEAKAGE_AUTO_MIN},
{44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN},
{52, 190}, {56, 190},
{60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
{100, 608},{104, 608 },
{108, 623},{112, 623 },
{116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{64,
{{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
{44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN},
{52, 295}, {56, 295 },
{60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
{100, 594}, {104, 594 },
{108, 625},{112, 625 },
{116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{100,
{{36, 618}, {40, 618 },
{44, 604}, {48, 604 },
{52, 596}, {56, 596 },
{60, 584}, {64, 584 },
{100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN },
{108, 299}, {112, 299 },
{116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
{124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
{132, 538}, {136, 538 },
{140, 598}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{104,
{{36, 636}, {40, 636 },
{44, 601}, {48, 601 },
{52, 616}, {56, 616 },
{60, 584}, {64, 584 },
{100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, SAP_TX_LEAKAGE_AUTO_MIN},{120, SAP_TX_LEAKAGE_AUTO_MIN},
{124, SAP_TX_LEAKAGE_AUTO_MIN},{128, SAP_TX_LEAKAGE_AUTO_MIN},
{132, 553}, {136, 553 },
{140, 568}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{108,
{{36, 600}, {40, 600 },
{44, 627}, {48, 627 },
{52, 611}, {56, 611 },
{60, 611}, {64, 611 },
{100, 214},{104, 214},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, SAP_TX_LEAKAGE_AUTO_MIN},{120, SAP_TX_LEAKAGE_AUTO_MIN},
{124, SAP_TX_LEAKAGE_AUTO_MIN},{128, SAP_TX_LEAKAGE_AUTO_MIN},
{132, SAP_TX_LEAKAGE_AUTO_MIN},{136, SAP_TX_LEAKAGE_AUTO_MIN},
{140, 534}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{112,
{{36, 645}, {40, 645 },
{44, 641}, {48, 641 },
{52, 618}, {56, 618 },
{60, 612}, {64, 612 },
{100, 293},{104, 293},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_AUTO_MIN},{128, SAP_TX_LEAKAGE_AUTO_MIN},
{132, SAP_TX_LEAKAGE_AUTO_MIN},{136, SAP_TX_LEAKAGE_AUTO_MIN},
{140, 521}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{116,
{{36, 661}, {40, 661 },
{44, 624}, {48, 624 },
{52, 634}, {56, 634 },
{60, 611}, {64, 611 },
{100, SAP_TX_LEAKAGE_AUTO_MIN},{104, SAP_TX_LEAKAGE_AUTO_MIN},
{108, 217},{112, 217 },
{116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_AUTO_MIN},{128, SAP_TX_LEAKAGE_AUTO_MIN},
{132, SAP_TX_LEAKAGE_AUTO_MIN},{136, SAP_TX_LEAKAGE_AUTO_MIN},
{140, SAP_TX_LEAKAGE_AUTO_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{120,
{{36, 667}, {40, 667 },
{44, 645}, {48, 645 },
{52, 633}, {56, 633 },
{60, 619}, {64, 619 },
{100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN},
{108, 291},{112, 291},
{116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_AUTO_MIN},{136, SAP_TX_LEAKAGE_AUTO_MIN},
{140, SAP_TX_LEAKAGE_AUTO_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{124,
{{36, 676}, {40, 676 },
{44, 668}, {48, 668 },
{52, 595}, {56, 595 },
{60, 622}, {64, 622 },
{100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN},
{108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
{116, 225},{120, 225},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_AUTO_MIN},{136, SAP_TX_LEAKAGE_AUTO_MIN},
{140, SAP_TX_LEAKAGE_AUTO_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{128,
{{36, 678}, {40, 678 },
{44, 664}, {48, 664 },
{52, 651}, {56, 651 },
{60, 643}, {64, 643 },
{100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN},
{108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
{116, 293},{120, 293},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_AUTO_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{132,
{{36, 689}, {40, 689 },
{44, 669}, {48, 669 },
{52, 662}, {56, 662 },
{60, 609}, {64, 609 },
{100, 538},{104, 538 },
{108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
{116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
{124, 247},{128, 247},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN }
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{136,
{{36, 703}, {40, 703 },
{44, 688}, {48, SAP_TX_LEAKAGE_MIN },
{52, 671}, {56, 671 },
{60, 658}, {64, 658 },
{100, 504},{104, 504 },
{108, SAP_TX_LEAKAGE_AUTO_MIN},{112, SAP_TX_LEAKAGE_AUTO_MIN},
{116, SAP_TX_LEAKAGE_AUTO_MIN},{120, SAP_TX_LEAKAGE_AUTO_MIN},
{124, 289},{128, 289},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN }
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{140,
{{36, 695}, {40, 695 },
{44, 684}, {48, 684 },
{52, 664}, {56, 664 },
{60, 658}, {64, 658 },
{100, 601},{104, 601 },
{108, 545},{112, 545 },
{116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
{124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
{132, 262},{136, 262},
{140, SAP_TX_LEAKAGE_MIN }
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
#ifdef FEATURE_WLAN_CH144
{144,
{{36, 695}, {40, 695 },
{44, 684}, {48, 684 },
{52, 664}, {56, 664 },
{60, 658}, {64, 658 },
{100, 601},{104, 601 },
{108, 545},{112, 545 },
{116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
{124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
{132, 262},{136, 262},
{140, SAP_TX_LEAKAGE_MIN},
{144, SAP_TX_LEAKAGE_MIN}
}},
#endif
};
/* channel tx leakage table - ht20 */
tSapChanMatrixInfo ht20_chan[] =
{
{52,
{{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, 286},
{44, 225}, {48, 121},
{52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
{60, 300}, {64, SAP_TX_LEAKAGE_AUTO_MIN},
{100, 637}, {104, SAP_TX_LEAKAGE_MAX},
{108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX},
{116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{56,
{{36, 468}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
{44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, 206},
{52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
{60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
{100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX},
{108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX},
{116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{60,
{{36, 507}, {40, 440},
{44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, 313},
{52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
{60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
{100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX},
{108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX},
{116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{64,
{{36, 516}, {40, 520},
{44, 506}, {48, SAP_TX_LEAKAGE_AUTO_MIN},
{52, 301}, {56, 258},
{60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
{100, 620}, {104, 617},
{108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX},
{116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX},
{124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX},
{132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX},
{140, SAP_TX_LEAKAGE_MAX}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{100,
{{36, 616}, {40, 601},
{44, 604}, {48, 589},
{52, 612}, {56, 592},
{60, 590}, {64, 582},
{100, SAP_TX_LEAKAGE_MIN},{104, 131},
{108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
{116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, 522},
{124, 571}, {128, 589},
{132, 593}, {136, 598},
{140, 594}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{104,
{{36, 622}, {40, 624},
{44, 618}, {48, 610},
{52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN},
{108, SAP_TX_LEAKAGE_MIN},{112, 463},
{116, 483},{120, 503},
{124, 523}, {128, 565},
{132, 570}, {136, 588},
{140, 585}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{108,
{{36, 620}, {40, 638},
{44, 611}, {48, 614},
{52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 477},{104, SAP_TX_LEAKAGE_MIN},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, 477},{120, 497},
{124, 517},{128, 537},
{132, 557},{136, 577},
{140, 603}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{112,
{{36, 636}, {40, 623},
{44, 638}, {48, 628},
{52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
{60, SAP_TX_LEAKAGE_MAX}, {64, 606},
{100, 501},{104, 481},
{108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN},
{116, SAP_TX_LEAKAGE_MIN},{120, 481},
{124, 501},{128, 421},
{132, 541},{136, 561},
{140, 583}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{116,
{{36, 646}, {40, 648},
{44, 633}, {48, 634},
{52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
{60, 615}, {64, 594},
{100, 575},{104, 554},
{108, 534},{112, SAP_TX_LEAKAGE_MIN},
{116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, 534},{136, 554},
{140, 574}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{120,
{{36, 643}, {40, 649},
{44, 654}, {48, 629},
{52, SAP_TX_LEAKAGE_MAX}, {56, 621},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 565}, {104, 545},
{108, 525},{112, 505},
{116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, 505},
{132, 525},{136, 545},
{140, 565}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{124,
{{36, 638}, {40, 657},
{44, 663}, {48, 649},
{52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 581}, {104, 561},
{108, 541},{112, 521},
{116, 499},{120, SAP_TX_LEAKAGE_MIN},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, 499},{136, 519},
{140, 539}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{128,
{{36, 651}, {40, 651},
{44, 674}, {48, 640},
{52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, 603}, {104, 560},
{108, 540},{112, 520},
{116, 499},{120, 479},
{124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, 479},
{140, 499}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{132,
{{36, 643}, {40, 668},
{44, 651}, {48, 657},
{52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, SAP_TX_LEAKAGE_MAX},{104, 602},
{108, 578}, {112, 570},
{116, 550},{120, 530},
{124, 510},{128, SAP_TX_LEAKAGE_MIN},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, 490}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{136,
{{36, 654}, {40, 667},
{44, 666}, {48, 642},
{52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
{60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
{100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX},
{108, SAP_TX_LEAKAGE_MAX},{112, 596},
{116, 555}, {120, 535},
{124, 515},{128, 495},
{132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
{140,
{{36, 679}, {40, 673},
{44, 667}, {48, 656},
{52, 634}, {56, 663},
{60, 662}, {64, 660},
{100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX},
{108, SAP_TX_LEAKAGE_MAX},{112, 590},
{116, 573}, {120, 553},
{124, 533},{128, 513},
{132, 490},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN}
#ifdef FEATURE_WLAN_CH144
,{144, SAP_TX_LEAKAGE_MIN}
#endif
}},
#ifdef FEATURE_WLAN_CH144
{144,
{{36, 679}, {40, 673},
{44, 667}, {48, 656},
{52, 634}, {56, 663},
{60, 662}, {64, 660},
{100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX},
{108, SAP_TX_LEAKAGE_MAX},{112, 590},
{116, 573}, {120, 553},
{124, 533},{128, 513},
{132, 490},{136, SAP_TX_LEAKAGE_MIN},
{140, SAP_TX_LEAKAGE_MIN},
{144, SAP_TX_LEAKAGE_MIN}
}},
#endif
};
#endif //end of WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
/*----------------------------------------------------------------------------
* Static Function Declarations and Definitions
* -------------------------------------------------------------------------*/
#ifdef SOFTAP_CHANNEL_RANGE
static VOS_STATUS sapGetChannelList(ptSapContext sapContext, v_U8_t **channelList,
v_U8_t *numberOfChannels);
#endif
/*==========================================================================
FUNCTION sapGet5GHzChannelList
DESCRIPTION
Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] available
channels in the current regulatory domain.
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext: SAP Context
RETURN VALUE
NA
SIDE EFFECTS
============================================================================*/
static VOS_STATUS sapGet5GHzChannelList(ptSapContext sapContext);
/*==========================================================================
FUNCTION sapStopDfsCacTimer
DESCRIPTION
Function to sttop the DFS CAC timer when SAP is stopped
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext: SAP Context
RETURN VALUE
DFS Timer start status
SIDE EFFECTS
============================================================================*/
static int sapStopDfsCacTimer(ptSapContext sapContext);
/*==========================================================================
FUNCTION sapStartDfsCacTimer
DESCRIPTION
Function to start the DFS CAC timer when SAP is started on DFS Channel
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext: SAP Context
RETURN VALUE
DFS Timer start status
SIDE EFFECTS
============================================================================*/
int sapStartDfsCacTimer(ptSapContext sapContext);
/*----------------------------------------------------------------------------
* Externalized Function Definitions
* -------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* Function Declarations and Documentation
* -------------------------------------------------------------------------*/
/*==========================================================================
FUNCTION sapEventInit
DESCRIPTION
Function for initializing sWLAN_SAPEvent structure
DEPENDENCIES
NA.
PARAMETERS
IN
sapEvent : State machine event
RETURN VALUE
None
SIDE EFFECTS
============================================================================*/
static inline void sapEventInit(ptWLAN_SAPEvent sapEvent)
{
sapEvent->event = eSAP_MAC_SCAN_COMPLETE;
sapEvent->params = 0;
sapEvent->u1 = 0;
sapEvent->u2 = 0;
}
#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
/*
* This function gives the leakage matrix for given NOL channel and cbMode
*
* PARAMETERS
* IN
* sapContext : Pointer to vos global context structure
* cbMode : target channel bonding mode
* NOL_channel : the NOL channel whose leakage matrix is required
* pTarget_chnl_mtrx : pointer to target channel matrix returned.
*
* RETURN VALUE
* BOOLEAN
* TRUE: leakage matrix was found
* FALSE: leakage matrix was not found
*/
v_BOOL_t
sapFindTargetChannelInChannelMatrix(ptSapContext sapContext,
ePhyChanBondState cbMode,
v_U8_t NOL_channel,
tSapTxLeakInfo **pTarget_chnl_mtrx)
{
tSapTxLeakInfo *target_chan_matrix = NULL;
tSapChanMatrixInfo *pchan_matrix = NULL;
v_U32_t nchan_matrix;
int i = 0;
switch (cbMode) {
case PHY_SINGLE_CHANNEL_CENTERED:
/* HT20 */
pchan_matrix = ht20_chan;
nchan_matrix = sizeof(ht20_chan)/sizeof(tSapChanMatrixInfo);
break;
case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
/* HT40 */
pchan_matrix = ht40_chan;
nchan_matrix = sizeof(ht40_chan)/sizeof(tSapChanMatrixInfo);
break;
#ifdef WLAN_FEATURE_11AC
case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
/* HT80 */
pchan_matrix = ht80_chan;
nchan_matrix = sizeof(ht80_chan)/sizeof(tSapChanMatrixInfo);
break;
#endif
default:
/* handle exception and fall back to HT20 table */
pchan_matrix = ht20_chan;
nchan_matrix = sizeof(ht20_chan)/sizeof(tSapChanMatrixInfo);
break;
}
for (i = 0; i < nchan_matrix; i++)
{
/* find the SAP channel to map the leakage matrix */
if (NOL_channel == pchan_matrix[i].channel)
{
target_chan_matrix = pchan_matrix[i].chan_matrix;
break;
}
}
if (NULL == target_chan_matrix)
{
return VOS_FALSE;
} else {
*pTarget_chnl_mtrx = target_chan_matrix;
return VOS_TRUE;
}
}
/*
* This function removes the channels from temp channel list that
* (if selected as target channel) will cause leakage in one of
* the NOL channels
*
* PARAMETERS
* IN
* sapContext : Pointer to vos global context structure
* cbMode : target channel bonding mode
* pNol : DFS NOL
* pTempChannelList : the target channel list
*
* RETURN VALUE
* VOS_STATUS code associated with performing the operation
*/
VOS_STATUS
sapMarkChannelsLeakingIntoNOL(ptSapContext sapContext,
ePhyChanBondState cbMode,
tSapDfsNolInfo *pNol,
v_U8_t tempChannelListSize,
v_U8_t *pTempChannelList)
{
tSapTxLeakInfo *target_chan_matrix = NULL;
#ifdef FEATURE_WLAN_CH144
v_U32_t num_channel = (RF_CHAN_144 - RF_CHAN_36) + 1;
#else
v_U32_t num_channel = (RF_CHAN_140 - RF_CHAN_36) + 1;
#endif
v_U32_t i = 0;
v_U32_t j = 0;
v_U32_t k = 0;
v_U8_t dfs_nol_channel;
tHalHandle hal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
tpAniSirGlobal mac;
if (NULL == hal) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s: Invalid hal pointer", __func__);
return VOS_STATUS_E_FAULT;
}
mac = PMAC_STRUCT(hal);
/* traverse target_chan_matrix and */
for (i = 0; i < NUM_5GHZ_CHANNELS ; i++) {
dfs_nol_channel = pNol[i].dfs_channel_number;
if ( pNol[i].radar_status_flag == eSAP_DFS_CHANNEL_USABLE ||
pNol[i].radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE ) {
/* not present in NOL */
continue;
}
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG,
FL("sapdfs: processing NOL channel: %d"),
dfs_nol_channel );
if (VOS_FALSE == sapFindTargetChannelInChannelMatrix(sapContext,
cbMode,
dfs_nol_channel,
&target_chan_matrix))
{
/*
* should never happen, we should always find a table here,
* if we don't, need a fix here!
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("Couldn't find target channel matrix!"));
VOS_ASSERT(0);
return VOS_STATUS_E_FAILURE;
}
/*
* following is based on assumption that both pTempChannelList
* and target channel matrix are in increasing order of channelID
*/
for (j = 0, k = 0; j < tempChannelListSize &&
k < num_channel; ) {
if (pTempChannelList[j] == 0) {
j++;
} else {
if (target_chan_matrix[k].leak_chan != pTempChannelList[j]) {
k++;
} else {
/* check leakage from candidate channel to NOL channel */
if (target_chan_matrix[k].leak_lvl <=
mac->sap.SapDfsInfo.tx_leakage_threshold)
{
/*
* this means that candidate channel will have bad
* leakage in NOL channel, remove the candidate channel
* from temp list
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("sapdfs: channel: %d will have bad leakage"
" due to channel: %d\n"),
dfs_nol_channel,
pTempChannelList[j]);
pTempChannelList[j] = 0;
}
j++;
k++;
}
}
} /* end of for loop checking temp channel list leakage into NOL */
} /* end of loop that selects each NOL */
return VOS_STATUS_SUCCESS;
}
#endif // end of WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
/*
* This function adds availabe channel to bitmap
*
* PARAMETERS
* IN
* pBitmap: bitmap to populate
* channel: channel to set in bitmap
*/
static void sapSetBitmap(chan_bonding_bitmap *pBitmap, v_U8_t channel)
{
int i = 0;
int start_channel = 0;
for ( i = 0; i < MAX_80MHZ_BANDS; i++ ) {
start_channel = pBitmap->chanBondingSet[i].startChannel;
if (channel >= start_channel && channel <= start_channel + 12) {
pBitmap->chanBondingSet[i].channelMap |=
1 << ((channel - start_channel)/4);
return;
}
}
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("Channel=%d is not in the bitmap"), channel);
}
/*
* This function reads the bitmap and populates available channel
* list according to channel bonding mode. This will be called for
* 80 MHz and 40 Mhz only. For 20 MHz no need for bitmap hence list
* is directly created while parsing the main list
*
* PARAMETERS
* IN
* pBitmap: bitmap to populate
* cbModeCurrent: cb mode to check for channel availability
* availableChannels: available channel list to populate
*
* RETURN VALUE
* number of channels found
*/
static v_U8_t sapPopulateAvailableChannels(chan_bonding_bitmap *pBitmap,
ePhyChanBondState cbModeCurrent,
v_U8_t *availableChannels)
{
v_U8_t i = 0;
v_U8_t channelCount = 0;
v_U8_t start_channel = 0;
switch (cbModeCurrent) {
#ifdef WLAN_FEATURE_11AC
/* HT80 */
case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
for ( i = 0; i < MAX_80MHZ_BANDS; i++ ) {
start_channel = pBitmap->chanBondingSet[i].startChannel;
if (pBitmap->chanBondingSet[i].channelMap == SAP_80MHZ_MASK) {
availableChannels[channelCount++] = start_channel;
availableChannels[channelCount++] = start_channel + 4;
availableChannels[channelCount++] = start_channel + 8;
availableChannels[channelCount++] = start_channel + 12;
}
}
break;
#endif
/* HT40 */
case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
for ( i = 0; i < MAX_80MHZ_BANDS; i++ ) {
start_channel = pBitmap->chanBondingSet[i].startChannel;
if ((pBitmap->chanBondingSet[i].channelMap & SAP_40MHZ_MASK_L)
== SAP_40MHZ_MASK_L) {
availableChannels[channelCount++] = start_channel;
availableChannels[channelCount++] = start_channel + 4;
} else {
if ((pBitmap->chanBondingSet[i].channelMap &
SAP_40MHZ_MASK_H) == SAP_40MHZ_MASK_H) {
availableChannels[channelCount++] = start_channel + 8;
availableChannels[channelCount++] = start_channel + 12;
}
}
}
break;
default:
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("Invalid case."));
break;
}
return channelCount;
}
/*
* FUNCTION sapDfsIsW53Invalid
*
* DESCRIPTION Checks if the passed channel is W53 and returns if
* SAP W53 opearation is allowed.
*
* DEPENDENCIES PARAMETERS
* IN hHAL : HAL pointer
* channelID: Channel Number to be verified
*
* RETURN VALUE : v_BOOL_t
* VOS_TRUE: If W53 operation is disabled
* VOS_FALSE: If W53 operation is enabled
*
* SIDE EFFECTS
*/
v_BOOL_t sapDfsIsW53Invalid(tHalHandle hHal, v_U8_t channelID)
{
tpAniSirGlobal pMac;
pMac = PMAC_STRUCT(hHal);
if (NULL == pMac)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("invalid pMac"));
return VOS_FALSE;
}
/*
* Check for JAPAN W53 Channel operation capability
*/
if (VOS_TRUE == pMac->sap.SapDfsInfo.is_dfs_w53_disabled &&
VOS_TRUE == IS_CHAN_JAPAN_W53(channelID))
{
return VOS_TRUE;
}
return VOS_FALSE;
}
/*
* FUNCTION sapDfsIsChannelInPreferredLocation
*
* DESCRIPTION Checks if the passed channel is in accordance with preferred
* Channel location settings.
*
* DEPENDENCIES PARAMETERS
* IN hHAL : HAL pointer
* channelID: Channel Number to be verified
*
* RETURN VALUE :v_BOOL_t
* VOS_TRUE:If Channel location is same as the preferred location
* VOS_FALSE:If Channel location is not same as the preferred location
*
* SIDE EFFECTS
*/
v_BOOL_t sapDfsIsChannelInPreferredLocation(tHalHandle hHal, v_U8_t channelID)
{
tpAniSirGlobal pMac;
pMac = PMAC_STRUCT(hHal);
if (NULL == pMac) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("invalid pMac"));
return VOS_TRUE;
}
if ( (SAP_CHAN_PREFERRED_INDOOR ==
pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) &&
(VOS_TRUE == IS_CHAN_JAPAN_OUTDOOR(channelID)) )
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("CHAN=%d is Outdoor so invalid,preferred Indoor only"),
channelID);
return VOS_FALSE;
}
else if ( (SAP_CHAN_PREFERRED_OUTDOOR ==
pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) &&
(VOS_TRUE == IS_CHAN_JAPAN_INDOOR(channelID)) )
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("CHAN=%d is Indoor so invalid,preferred Outdoor only"),
channelID);
return VOS_FALSE;
}
return VOS_TRUE;
}
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
/**
* sap_check_in_avoid_ch_list() - checks if given channel present is channel
* avoidance list
* avoid_channels_info struct
* @sap_ctx: sap context.
* @channel: channel to be checked in sap_ctx's avoid ch list
*
* sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
* which MDM device's AP with MCC was detected. This function checks if given
* channel is present in that list.
*
* Return: true, if channel was present, false othersie.
*/
bool
sap_check_in_avoid_ch_list(ptSapContext sap_ctx, uint8_t channel)
{
uint8_t i = 0;
struct sap_avoid_channels_info *ie_info =
&sap_ctx->sap_detected_avoid_ch_ie;
for (i = 0; i < sizeof(ie_info->channels); i++) {
if (ie_info->channels[i] == channel)
return true;
}
return false;
}
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
/**
* sap_is_valid_acs_channel() - checks if given channel is in acs channel range
* @sap_ctx: sap context.
* @channel: channel to be checked in acs range
*
* Return: true, if channel is valid, false otherwise.
*/
static bool sap_is_valid_acs_channel(ptSapContext sap_ctx, uint8_t channel)
{
int i = 0;
/* Check whether acs is enabled */
if (!sap_ctx->acs_cfg->acs_mode)
return true;
if ((channel < sap_ctx->acs_cfg->start_ch) ||
(channel > sap_ctx->acs_cfg->end_ch)) {
return false;
}
if (!sap_ctx->acs_cfg->ch_list) {
/* List not present, return */
return true;
} else {
for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++)
if (channel == sap_ctx->acs_cfg->ch_list[i])
return true;
}
return false;
}
/*
* This function randomly pick up an AVAILABLE channel
*/
static v_U8_t sapRandomChannelSel(ptSapContext sapContext)
{
v_U32_t random_byte = 0;
v_U8_t available_chnl_count = 0;
uint8_t avail_dfs_chan_count = 0;
uint8_t avail_non_dfs_chan_count = 0;
v_U8_t valid_chnl_count = 0;
v_U8_t availableChannels[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0,};
uint8_t avail_dfs_chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0,};
uint8_t avail_non_dfs_chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0,};
v_U8_t target_channel = 0;
v_BOOL_t isChannelNol = VOS_FALSE;
v_BOOL_t is_valid_acs_chan = VOS_FALSE;
chan_bonding_bitmap channelBitmap;
v_U8_t i = 0;
v_U8_t channelID;
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
tpAniSirGlobal pMac;
tANI_U32 chanWidth;
ePhyChanBondState cbModeCurrent;
v_U8_t *tempChannels = NULL;
uint8_t dfs_region;
if (NULL == hHal) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("invalid hHal"));
return target_channel;
}
pMac = PMAC_STRUCT(hHal);
if (NULL == pMac) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("invalid pMac"));
return target_channel;
}
/*
* Retrieve the original one and store it.
* use the stored original value when you call this function next time
* so fall back mechanism always starts with original ini value.
*/
if (pMac->sap.SapDfsInfo.orig_cbMode == 0)
{
pMac->sap.SapDfsInfo.orig_cbMode = sme_SelectCBMode(hHal,
sapContext->csrRoamProfile.phyMode,
sapContext->channel,
sapContext->secondary_ch,
&sapContext->vht_channel_width,
sapContext->ch_width_orig);
pMac->sap.SapDfsInfo.orig_cbMode = csrConvertCBIniValueToPhyCBState(
pMac->sap.SapDfsInfo.orig_cbMode);
cbModeCurrent = pMac->sap.SapDfsInfo.orig_cbMode;
}
else
{
cbModeCurrent = pMac->sap.SapDfsInfo.orig_cbMode;
}
/*
* Retrieve the original one and store it.
* use the stored original value when you call this function next time
* so fall back mechanism always starts with original ini value.
*/
if (pMac->sap.SapDfsInfo.orig_chanWidth == 0)
{
pMac->sap.SapDfsInfo.orig_chanWidth =
sapContext->ch_width_orig;
chanWidth = pMac->sap.SapDfsInfo.orig_chanWidth;
}
else
{
chanWidth = pMac->sap.SapDfsInfo.orig_chanWidth;
}
if (sapGet5GHzChannelList(sapContext))
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("Getting 5Ghz channel list failed"));
return target_channel;
}
vos_nv_get_dfs_region(&dfs_region);
/*
* valid_chnl_count will be used to find number of valid channels
* after following for loop ends
*/
valid_chnl_count = sapContext->SapAllChnlList.numChannel;
/* loop to check ACS range or NOL channels */
for (i = 0; i < sapContext->SapAllChnlList.numChannel; i++)
{
channelID = sapContext->SapAllChnlList.channelList[i].channel;
/*
* IN JAPAN REGULATORY DOMAIN CHECK IF THE FOLLOWING TWO
* TWO RULES APPLY AND FILTER THE AVAILABLE CHANNELS
* ACCORDINGLY.
*
* 1. If we are operating in Japan regulatory domain
* Check if Japan W53 Channel operation is NOT
* allowed and if its not allowed then mark all the
* W53 channels as Invalid.
*
* 2. If we are operating in Japan regulatory domain
* Check if channel switch between Indoor/Outdoor
* is allowed. If it is not allowed then limit
* the avaiable channels to Indoor or Outdoor
* channels only based up on the SAP Channel location
* indicated by "sap_operating_channel_location" param.
*/
if (DFS_MKK4_DOMAIN == dfs_region)
{
/*
* Check for JAPAN W53 Channel operation capability
*/
if (VOS_TRUE == sapDfsIsW53Invalid(hHal, channelID))
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("index:%d, Channel=%d Invalid,Japan W53 Disabled"),
i, channelID);
sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE;
valid_chnl_count--;
continue;
}
/*
* If SAP's preferred channel location is Indoor
* then set all the outdoor channels in the domain
* to invalid.If the preferred channel location is
* outdoor then set all the Indoor channels in the
* domain to Invalid.
*/
if (VOS_FALSE ==
sapDfsIsChannelInPreferredLocation(hHal, channelID))
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("CHAN=%d is invalid,preferred Channel Location %d Only"),
channelID,
pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location);
sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE;
valid_chnl_count--;
continue;
}
}
if (vos_nv_getChannelEnabledState(channelID) == NV_CHANNEL_DFS)
{
isChannelNol = sapDfsIsChannelInNolList(sapContext,
channelID,
PHY_SINGLE_CHANNEL_CENTERED);
if (VOS_TRUE == isChannelNol)
{
/*
* Mark this channel invalid since it is still in
* DFS Non-Occupancy-Period which is 30 mins.
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("index: %d, Channel = %d Present in NOL"),
i, channelID);
sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE;
valid_chnl_count--;
continue;
}
}
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
/* avoid channels on which another MDM AP in MCC mode is detected. */
if (pMac->sap.sap_channel_avoidance
&& sapContext->sap_detected_avoid_ch_ie.present) {
if (sap_check_in_avoid_ch_list(sapContext, channelID)) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("index: %d, Channel = %d, avoided due to "
"presence of another AP+AP MCC device in same "
"channel."),
i, channelID);
sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE;
}
}
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
/* check if the channel is within ACS channel range */
is_valid_acs_chan = sap_is_valid_acs_channel(sapContext,
channelID);
if (is_valid_acs_chan == false)
{
/*
* mark this channel invalid since it is out of ACS channel range
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("index: %d, Channel=%d out of ACS channel range %d-%d"),
i, channelID, sapContext->acs_cfg->start_ch,
sapContext->acs_cfg->end_ch);
sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE;
valid_chnl_count--;
continue;
}
} /* end of check for NOL or ACS channels */
/* valid_chnl_count now have number of valid channels */
tempChannels = vos_mem_malloc(valid_chnl_count);
if (tempChannels == NULL) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("sapdfs: memory alloc failed"));
return target_channel;
}
do
{
v_U8_t j = 0;
#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
tSapDfsNolInfo *pNol = pMac->sap.SapDfsInfo.sapDfsChannelNolList;
#endif
/* prepare temp list of just the valid channels */
for (i = 0; i < sapContext->SapAllChnlList.numChannel; i++) {
if (sapContext->SapAllChnlList.channelList[i].valid) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("sapdfs: Adding Channel = %d to temp List"),
sapContext->SapAllChnlList.channelList[i].channel);
tempChannels[j++] =
sapContext->SapAllChnlList.channelList[i].channel;
}
}
#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("sapdfs: Processing temp channel list against NOL."));
if (VOS_STATUS_SUCCESS != sapMarkChannelsLeakingIntoNOL(sapContext,
cbModeCurrent,
pNol,
valid_chnl_count,
tempChannels)) {
vos_mem_free(tempChannels);
return target_channel;
}
#endif
vos_mem_zero(availableChannels, sizeof(availableChannels));
vos_mem_zero(&channelBitmap, sizeof(channelBitmap));
channelBitmap.chanBondingSet[0].startChannel = 36;
channelBitmap.chanBondingSet[1].startChannel = 52;
channelBitmap.chanBondingSet[2].startChannel = 100;
channelBitmap.chanBondingSet[3].startChannel = 116;
channelBitmap.chanBondingSet[4].startChannel = 132;
channelBitmap.chanBondingSet[5].startChannel = 149;
/* now loop through whatever is left of channel list */
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("sapdfs: Moving temp channel list to final."));
for (i = 0; i < valid_chnl_count; i++ ){
/*
* add channel from temp channel list to bitmap or fianl
* channel list (in case of 20MHz width)
*/
if (tempChannels[i] != 0) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG,
FL("sapdfs: processing channel: %d "),
tempChannels[i]);
/* for 20MHz, directly create available channel list */
if (cbModeCurrent == PHY_SINGLE_CHANNEL_CENTERED) {
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_DEBUG,
FL("sapdfs: Channel=%d added to available list"),
tempChannels[i]);
availableChannels[available_chnl_count++] =
tempChannels[i];
} else {
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_DEBUG,
FL("sapdfs: Channel=%d added to bitmap"),
tempChannels[i]);
sapSetBitmap(&channelBitmap, tempChannels[i]);
}
}
}
/* if 40 MHz or 80 MHz, populate available channel list from bitmap */
if (cbModeCurrent != PHY_SINGLE_CHANNEL_CENTERED) {
available_chnl_count = sapPopulateAvailableChannels(&channelBitmap,
cbModeCurrent,
availableChannels);
/* if no valid channel bonding found, fallback to lower bandwidth */
if (available_chnl_count == 0) {
if (cbModeCurrent >=
PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED) {
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_WARN,
FL("sapdfs:No 80MHz cb found, falling to 40MHz"));
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_WARN,
FL("sapdfs:Changing chanWidth from [%d] to [%d]"),
chanWidth, eHT_CHANNEL_WIDTH_40MHZ);
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_WARN,
FL("sapdfs:Changing CB mode from [%d] to [%d]"),
cbModeCurrent, PHY_DOUBLE_CHANNEL_LOW_PRIMARY);
cbModeCurrent = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
chanWidth = eHT_CHANNEL_WIDTH_40MHZ;
/* continue to start of do loop */
continue;
} else if (cbModeCurrent >=
PHY_DOUBLE_CHANNEL_LOW_PRIMARY ) {
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_WARN,
FL("sapdfs:No 40MHz cb found, falling to 20MHz"));
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_WARN,
FL("sapdfs:Changing chanWidth from [%d] to [%d]"),
chanWidth, eHT_CHANNEL_WIDTH_20MHZ);
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_WARN,
FL("sapdfs:Changing CB mode from [%d] to [%d]"),
cbModeCurrent, PHY_SINGLE_CHANNEL_CENTERED);
cbModeCurrent = PHY_SINGLE_CHANNEL_CENTERED;
chanWidth = eHT_CHANNEL_WIDTH_20MHZ;
/* continue to start of do loop */
continue;
}
}
}
/*
* by now, available channels list will be populated or
* no channels are avaialbe
*/
if (available_chnl_count) {
for (i=0;i<available_chnl_count;i++) {
if (VOS_IS_DFS_CH(availableChannels[i])) {
avail_dfs_chan_list[avail_dfs_chan_count++] =
availableChannels[i];
} else {
avail_non_dfs_chan_list[avail_non_dfs_chan_count++] =
availableChannels[i];
}
}
} else {
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_INFO_LOW,
FL("No target channel found"));
break;
}
vos_rand_get_bytes(0, (v_U8_t*)&random_byte, 1);
/* Give preference to non-DFS channel */
if (!pMac->f_prefer_non_dfs_on_radar) {
i = (random_byte + vos_timer_get_system_ticks()) %
available_chnl_count;
target_channel = availableChannels[i];
} else if (avail_non_dfs_chan_count) {
i = (random_byte + vos_timer_get_system_ticks()) %
avail_non_dfs_chan_count;
target_channel = avail_non_dfs_chan_list[i];
} else {
i = (random_byte + vos_timer_get_system_ticks()) %
avail_dfs_chan_count;
target_channel = avail_dfs_chan_list[i];
}
pMac->sap.SapDfsInfo.new_chanWidth = chanWidth;
pMac->sap.SapDfsInfo.new_cbMode = cbModeCurrent;
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_INFO_LOW,
FL("sapdfs: New CB mode = %d"),
pMac->sap.SapDfsInfo.new_cbMode);
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_INFO_LOW,
FL("sapdfs: New Channel width = %d"),
pMac->sap.SapDfsInfo.new_chanWidth);
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_INFO_LOW,
FL("sapdfs: target_channel = %d"), target_channel);
break;
} while(1); /* this loop will iterate at max 3 times */
vos_mem_free(tempChannels);
return target_channel;
}
/*
* Mark the channels in NOL with time and eSAP_DFS_CHANNEL_UNAVAILABLE
*/
void sapMarkDfsChannels(ptSapContext sapContext, v_U8_t* channels,
v_U8_t numChannels, v_U64_t time)
{
int i, j;
tSapDfsNolInfo *psapDfsChannelNolList = NULL;
v_U8_t nRegDomainDfsChannels;
tHalHandle hHal;
tpAniSirGlobal pMac;
v_U64_t time_elapsed_since_last_radar;
v_U64_t time_when_radar_found;
hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == channels)
return;
if (NULL == hHal) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("invalid hHal"));
return;
}
pMac = PMAC_STRUCT(hHal);
if (NULL == pMac) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("invalid pMac"));
return;
}
/*
* Mark the current channel on which Radar is found
* in the NOL list as eSAP_DFS_CHANNEL_UNAVAILABLE.
*/
psapDfsChannelNolList = pMac->sap.SapDfsInfo.sapDfsChannelNolList;
nRegDomainDfsChannels = pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
for (i = 0; i < numChannels; i++) {
for (j = 0; j <= nRegDomainDfsChannels; j++)
{
if (psapDfsChannelNolList[j].dfs_channel_number ==
channels[i])
{
time_when_radar_found =
psapDfsChannelNolList[j].radar_found_timestamp;
time_elapsed_since_last_radar = time -
time_when_radar_found;
/* If channel is already in NOL, don't update it again.
* This is useful when marking bonding channels which are
* already unavailable.
*/
if ((psapDfsChannelNolList[j].radar_status_flag ==
eSAP_DFS_CHANNEL_UNAVAILABLE)&&
(time_elapsed_since_last_radar <
SAP_DFS_NON_OCCUPANCY_PERIOD))
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("Channel=%d already in NOL"),
channels[i]);
}
else
{
/*
* Capture the Radar Found timestamp on the Current
* Channel in ms.
*/
psapDfsChannelNolList[j].radar_found_timestamp = time;
/* Mark the Channel to be UNAVAILABLE for next 30 mins */
psapDfsChannelNolList[j].radar_status_flag =
eSAP_DFS_CHANNEL_UNAVAILABLE;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("Channel=%d Added to NOL LIST"),
channels[i]);
}
}
}
}
}
/*
* This Function is to get bonding channels from primary channel.
*
*/
v_U8_t sapGetBondingChannels(ptSapContext sapContext, v_U8_t channel,
v_U8_t* channels, v_U8_t size, ePhyChanBondState chanBondState)
{
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
tpAniSirGlobal pMac;
v_U8_t numChannel;
if(channels == NULL)
return 0;
if(size < MAX_BONDED_CHANNELS) return 0;
if (NULL != hHal)
{
pMac = PMAC_STRUCT( hHal );
}
else
return 0;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
FL("cbmode: %d, channel: %d"),
chanBondState, channel);
switch (chanBondState) {
case PHY_SINGLE_CHANNEL_CENTERED:
numChannel = 1;
channels[0] = channel;
break;
case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
numChannel = 2;
channels[0] = channel - 4;
channels[1] = channel;
break;
case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
numChannel = 2;
channels[0] = channel;
channels[1] = channel + 4;
break;
#ifdef WLAN_FEATURE_11AC
case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
numChannel = 4;
channels[0] = channel;
channels[1] = channel + 4;
channels[2] = channel + 8;
channels[3] = channel + 12;
break;
case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
numChannel = 4;
channels[0] = channel - 4;
channels[1] = channel;
channels[2] = channel + 4;
channels[3] = channel + 8;
break;
case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
numChannel = 4;
channels[0] = channel - 8;
channels[1] = channel - 4;
channels[2] = channel;
channels[3] = channel + 4;
break;
case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
numChannel = 4;
channels[0] = channel - 12;
channels[1] = channel - 8;
channels[2] = channel - 4;
channels[3] = channel;
break;
#endif
default:
numChannel = 1;
channels[0] = channel;
break;
}
return numChannel;
}
/*
* This Function Checks if a given bonded channel is AVAILABLE or USABLE
* for DFS operation.
*/
v_BOOL_t
sapDfsIsChannelInNolList(ptSapContext sapContext, v_U8_t channelNumber,
ePhyChanBondState chanBondState)
{
int i = 0, j;
v_U64_t timeElapsedSinceLastRadar,timeWhenRadarFound,currentTime = 0;
v_U64_t max_jiffies;
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
tpAniSirGlobal pMac;
v_U8_t channels[MAX_BONDED_CHANNELS];
v_U8_t numChannels;
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s invalid hHal", __func__);
return VOS_FALSE;
}
else
{
pMac = PMAC_STRUCT( hHal );
}
if ((pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels == 0) ||
(pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels >
NUM_5GHZ_CHANNELS))
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
"%s: invalid dfs channel count %d",
__func__,
pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels);
return VOS_FALSE;
}
/* get the bonded channels */
numChannels = sapGetBondingChannels(sapContext, channelNumber, channels,
MAX_BONDED_CHANNELS, chanBondState );
/* check for NOL, first on will break the loop */
for (j=0; j < numChannels; j++)
{
for (i =0 ; i< pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; i++)
{
if(pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.dfs_channel_number == channels[j])
{
if ( (pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.radar_status_flag == eSAP_DFS_CHANNEL_USABLE)
||
(pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE) )
{
/*
* Allow SAP operation on this channel
* either the DFS channel has not been used
* for SAP operation or it is available for
* SAP operation since it is past Non-Occupancy-Period
* so, return FALSE.
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("Channel = %d not in NOL, CHANNEL AVAILABLE"),
pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.dfs_channel_number);
}
else if (pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.radar_status_flag == eSAP_DFS_CHANNEL_UNAVAILABLE)
{
/*
* If a DFS Channel is UNAVAILABLE then
* check to see if it is past Non-occupancy-period
* of 30 minutes. If it is past 30 mins then
* mark the channel as AVAILABLE and return FALSE
* as the channel is not anymore in NON-Occupancy-Period.
*/
timeWhenRadarFound = pMac->sap.SapDfsInfo
.sapDfsChannelNolList[i]
.radar_found_timestamp;
currentTime = vos_get_monotonic_boottime();
if (currentTime < timeWhenRadarFound) {
/* vos_get_monotonic_boottime() can overflow. Jiffies is
* initialized such that 32 bit jiffies value wrap 5 minutes
* after boot so jiffies wrap bugs show up earlier.
*/
max_jiffies = (v_U64_t)UINT_MAX * 1000;
timeElapsedSinceLastRadar = (max_jiffies -
timeWhenRadarFound) + (currentTime);
} else {
timeElapsedSinceLastRadar = currentTime -
timeWhenRadarFound;
}
if (timeElapsedSinceLastRadar >= SAP_DFS_NON_OCCUPANCY_PERIOD)
{
pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE;
pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.radar_found_timestamp = 0;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("Channel=%d not in NOL, CHANNEL AVAILABLE"),
pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.dfs_channel_number);
}
else
{
/*
* Channel is not still available for SAP operation
* so return TRUE; As the Channel is still
* in Non-occupancy-Period.
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
FL("Channel=%d still in NOL, CHANNEL UNAVAILABLE"),
pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.dfs_channel_number);
break;
}
}
} /* if */
} /* loop for dfs channels */
if (i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels)
break;
} /* loop for bonded channels */
/* if any of the channel is not available, mark all available channels as
* unavailable with same time stamp.
*/
if (j < numChannels &&
i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels)
{
if (numChannels > MAX_BONDED_CHANNELS) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
FL( "numChannels > MAX_BONDED_CHANNELS so resetting"));
numChannels = MAX_BONDED_CHANNELS;
}
sapMarkDfsChannels(sapContext,
channels,
numChannels,
pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
.radar_found_timestamp);
/* set DFS-NOL back to keep it update-to-date in CNSS */
sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NOL_SET,
(v_PVOID_t) eSAP_STATUS_SUCCESS);
return VOS_TRUE;
}
return VOS_FALSE;
}
/**
* sap_select_default_oper_chan_ini() - Selects operating channel based on ini
* @hal: pointer to HAL
* @acs_11a: 11a acs cfg
*
* Return: selected operating channel
*/
uint8_t sap_select_default_oper_chan_ini(tHalHandle hal, uint32_t acs_11a)
{
uint32_t operating_band = 0;
uint8_t channel;
ccmCfgGetInt(hal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND,
&operating_band);
if (acs_11a || operating_band == RF_SUBBAND_5_LOW_GHZ ||
operating_band == RF_SUBBAND_5_MID_GHZ ||
operating_band == RF_SUBBAND_5_HIGH_GHZ) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
FL("Default channel selection from band %d"),
operating_band);
if (operating_band)
(operating_band == RF_SUBBAND_5_LOW_GHZ) ?
(channel = SAP_DEFAULT_LOW_5GHZ_CHANNEL) :
(operating_band == RF_SUBBAND_5_MID_GHZ) ?
(channel = SAP_DEFAULT_MID_5GHZ_CHANNEL) :
(operating_band == RF_SUBBAND_5_HIGH_GHZ) ?
(channel = SAP_DEFAULT_HIGH_5GHZ_CHANNEL) : 0;
else
channel = SAP_DEFAULT_LOW_5GHZ_CHANNEL;
} else {
channel = SAP_DEFAULT_24GHZ_CHANNEL;
}
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
FL("channel selected to start bss %d"), channel);
return channel;
}
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
/**
* sap_create_session_info() - create session info based on
* the input chan and phymode
* @sap_context: ptSapContext ptr
* @session_info: information returned.
* @sap_ch: requesting channel number
*
* Return: TRUE if session info returned
*/
static v_BOOL_t sap_create_session_info(
ptSapContext sap_context,
session_info_t *session_info,
v_U16_t sap_ch)
{
tHalHandle hHal;
eCsrPhyMode sap_phymode;
hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME,
sap_context->pvosGCtx);
if (NULL == hHal) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
"In %s, invalid hHal", __func__);
return FALSE;
}
sap_phymode = sap_context->csrRoamProfile.phyMode;
return sme_create_sap_session_info(
hHal, sap_phymode, sap_ch, session_info);
}
/**
* sap_find_station_session_info() - get active station session info
* @sap_context: ptSapContext ptr
* @session_info: information returned.
*
* Return: TRUE if session info returned
*/
static v_BOOL_t sap_find_station_session_info(
ptSapContext sap_context,
session_info_t * session_info)
{
tHalHandle hHal;
hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME,
sap_context->pvosGCtx);
if (NULL == hHal) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
"In %s, invalid hHal", __func__);
return FALSE;
}
return sme_find_sta_session_info(hHal, session_info);
}
/**
* sap_find_all_session_info() - get all active session info
* @sap_context: ptSapContext ptr
* @session_info: information returned.
* @count: number of session returned.
*
* Return: TRUE if any session info returned
*/
static v_BOOL_t sap_find_all_session_info(
ptSapContext sap_context,
session_info_t *session_info,
v_U8_t *count)
{
tHalHandle hHal;
hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME,
sap_context->pvosGCtx);
if (NULL == hHal) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
"In %s, invalid hHal", __func__);
return FALSE;
}
return sme_find_all_session_info(hHal, session_info, count);
}
/**
* sap_overlap_check() - check channel overlap or not
* @sap_context: ptSapContext ptr
* @info_1: session info 1.
* @info_2: session info 2.
*
* Return: TRUE if two session channels are overlap
*/
static v_BOOL_t sap_overlap_check(
session_info_t *info_1,
session_info_t *info_2)
{
v_BOOL_t intf = TRUE;
if (!(((info_1->lfreq >= info_2->lfreq
&& info_1->lfreq < info_2->hfreq) ||
(info_1->hfreq > info_2->lfreq
&& info_1->hfreq <= info_2->hfreq))
|| ((info_2->lfreq >= info_1->lfreq
&& info_2->lfreq < info_1->hfreq) ||
(info_2->hfreq > info_1->lfreq
&& info_2->hfreq <= info_1->hfreq))
)) {
intf = FALSE;
}
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s:info_1 mode %d band %d och %d lf %d"
"hf %d cf %d hbw %d",
__func__, info_1->con_mode, info_1->band,
info_1->och, info_1->lfreq, info_1->hfreq,
info_1->cfreq, info_1->hbw);
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s:info_2 mode %d band %d och %d lf %d"
"hf %d cf %d hbw %d",
__func__, info_2->con_mode, info_2->band,
info_2->och, info_2->lfreq, info_2->hfreq,
info_2->cfreq, info_2->hbw);
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s:info_1 %s with info_2",
__func__, intf ? "overlap" : "not overlap");
return intf;
}
/**
* sap_check_mcc_valid() - check mcc violation or not
* @sap_context: ptSapContext ptr
* @chan: chan to check
* @band: band of the channel
* @session_info: session info array of all active sessions
* @session_count: session counts
*
* Return: VOS_STATUS_SUCCESS if the new sap chan is valid.
*/
static VOS_STATUS sap_check_mcc_valid(
ptSapContext sap_context,
v_SINT_t chan,
eCsrBand band,
session_info_t *session_info,
v_U8_t session_count)
{
session_info_t *info;
session_info_t sessions[VOS_MAX_CONCURRENCY_PERSONA + 1];
v_U8_t i, j;
v_U8_t session_cnt[VOS_MAX_CONCURRENCY_PERSONA + 1];
v_U32_t channels[VOS_MAX_CONCURRENCY_PERSONA + 1];
v_U8_t chan_cnt = 0;
if (session_count <= 0)
return VOS_STATUS_SUCCESS;
else if (session_count > VOS_MAX_CONCURRENCY_PERSONA) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s: invalid session count %d", __func__,
session_count);
return VOS_STATUS_E_INVAL;
}
/*
* create channel & session matrix
*/
vos_mem_copy(sessions, session_info,
sizeof(session_info_t) * session_count);
info = &sessions[session_count];
info->con_mode = VOS_STA_SAP_MODE;
info->och = chan;
session_count++;
for (i = 0; i < session_count &&
chan_cnt < VOS_MAX_CONCURRENCY_PERSONA; i++) {
info = &sessions[i];
for (j = 0; j < chan_cnt; j++) {
if (info->och == channels[j]) {
session_cnt[j]++;
break;
}
}
if ((j >= chan_cnt) &&
(chan_cnt < (VOS_MAX_CONCURRENCY_PERSONA + 1))) {
channels[chan_cnt] = info->och;
session_cnt[chan_cnt] = 1;
chan_cnt++;
}
}
/*
* 1 .FW doesn't support > 2 home channel MCC.
*/
if (chan_cnt > MAX_CONCURRENCY_CHAN_COUNT) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s: exceed 2 home chan in MCC (chan %d band %d)",
__func__, chan, band);
return VOS_STATUS_E_FAILURE;
}
/*
* 2. FW doesn't support the MCC case in which >= 3 SAP sessions
* on one channel, e.g. AP1 AP2 AP3 on channel A and AP4 on
* channel B is not supported.
*/
if (chan_cnt > 1) {
for (j = 0; j < chan_cnt; j++) {
if (session_cnt[j] >
MAX_SESSSION_PER_CHAN_MCC) {
VOS_TRACE( VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_ERROR,
"%s: exceed 2 session in MCC "
"(chan %d band %d)",
__func__, chan, band);
return VOS_STATUS_E_FAILURE;
}
}
}
/*
* 3. Don't support MCC on DFS channel.
*/
if (chan_cnt > 1) {
for (j = 0; j < chan_cnt; j++) {
if (channels[j] != 0
&& vos_nv_getChannelEnabledState(channels[j])
== NV_CHANNEL_DFS) {
VOS_TRACE( VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_ERROR,
"%s: dfs not support in MCC dfs chan %d"
"(chan %d band %d)",
__func__, channels[j], chan, band);
return VOS_STATUS_E_FAILURE;
}
}
}
return VOS_STATUS_SUCCESS;
}
/**
* sap_concurrence_chan_override() - override SAP channel if necessary
* @sap_context: ptSapContext ptr
* @cc_switch_mode: override policy
* @con_ch: the override result channel
*
* This function will check and override sap channel based on configurated
* MCC to SCC policy :
* gWlanMccToSccSwitchMode = 0: disabled.
* gWlanMccToSccSwitchMode = 1: override to SCC if channel overlap in
* same band.
* gWlanMccToSccSwitchMode = 2: force to SCC in same band.
*
* gWlanBandSwitchEnable = false: disabled.
* gWlanBandSwitchEnable = true: enable band switch for MCC to SCC
*
* Return: VOS_STATUS_SUCCESS: Success
* other value will fail the sap start request
*/
static VOS_STATUS
sap_concurrency_chan_override(
ptSapContext sap_context,
v_U8_t cc_switch_mode,
tANI_U8 *con_ch)
{
v_U8_t i;
v_SINT_t target_chan;
eCsrBand target_band;
session_info_t target_info;
v_SINT_t candidate_chan = 0;
v_SINT_t candidate[2 * VOS_MAX_CONCURRENCY_PERSONA + 1];
v_U8_t candidate_count = 0;
session_info_t session_info[VOS_MAX_CONCURRENCY_PERSONA];
v_U8_t session_count = 0;
VOS_STATUS status = VOS_STATUS_SUCCESS;
if (sap_context->channel == AUTO_CHANNEL_SELECT) {
target_band = sap_context->target_band;
target_chan = 0;
candidate_chan = 0;
} else {
if (sap_context->channel > MAX_2_4GHZ_CHANNEL) {
target_band = eCSR_BAND_5G;
sap_context->target_band = eCSR_BAND_5G;
} else {
target_band = eCSR_BAND_24;
sap_context->target_band = eCSR_BAND_24;
}
target_chan = sap_context->channel;
candidate_chan = sap_context->channel;
if (!sap_create_session_info(sap_context, &target_info,
target_chan)) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"Failed to create channel(%d) info", target_chan);
return VOS_STATUS_E_FAILURE;
}
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s:curr sap mode %d band %d och %d lf %d hf"
"%d cf %d hbw %d",
__func__, target_info.con_mode, target_info.band,
target_info.och, target_info.lfreq, target_info.hfreq,
target_info.cfreq, target_info.hbw);
}
/*
* 1. find all active session info
*/
sap_find_all_session_info(sap_context, session_info, &session_count);
/*
* 2. get candidate chan list from more preference to less preference
*/
for (i = 0; i < session_count; i++) {
session_info_t *info = &session_info[i];
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s: mode %d band %d och %d lf %d hf %d cf %d hbw %d",
__func__, info->con_mode, info->band, info->och,
info->lfreq, info->hfreq, info->cfreq, info->hbw);
if (info->band != target_band) {
if (sap_context->band_switch_enable) {
if (info->band == eCSR_BAND_5G) {
sap_context->ch_width_orig =
sap_context->ch_width_5g_orig;
} else {
sap_context->ch_width_orig =
sap_context->ch_width_24g_orig;
}
} else {
continue;
}
}
if (cc_switch_mode == VOS_MCC_TO_SCC_SWITCH_ENABLE
&& target_chan != 0
&& sap_overlap_check(&target_info, info))
candidate[candidate_count++] = info->och;
else if (cc_switch_mode == VOS_MCC_TO_SCC_SWITCH_FORCE)
candidate[candidate_count++] = info->och;
}
candidate[candidate_count++] = target_chan;
if (cc_switch_mode == VOS_MCC_TO_SCC_SWITCH_ENABLE
&& target_chan == 0) {
for (i = 0; i < session_count; i++) {
session_info_t *info = &session_info[i];
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s: mode %d band %d och %d lf %d"
"hf %d cf %d hbw %d",
__func__, info->con_mode, info->band,
info->och, info->lfreq, info->hfreq,
info->cfreq, info->hbw);
if (info->band != target_band) {
if (sap_context->band_switch_enable) {
if (info->band == eCSR_BAND_5G) {
sap_context->ch_width_orig =
sap_context->ch_width_5g_orig;
} else {
sap_context->ch_width_orig =
sap_context->ch_width_24g_orig;
}
} else {
continue;
}
}
candidate[candidate_count++] = info->och;
}
}
/*
* 3. check MCC violation and find the first good channel.
*/
for (i = 0; i < candidate_count; i++) {
status = sap_check_mcc_valid(sap_context, candidate[i],
target_band,
session_info,
session_count);
if (status == VOS_STATUS_SUCCESS) {
candidate_chan = candidate[i];
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s: found chan %d band %d",
__func__, candidate_chan, target_band);
break;
}
}
if (status == VOS_STATUS_SUCCESS) {
sap_context->channel = candidate_chan;
*con_ch = sap_context->channel;
if (target_chan != candidate_chan)
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"In %s, override to chan %d band %d from %d",
__func__, candidate_chan, target_band,
target_chan);
else
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"In %s, no override chan %d band %d",
__func__, target_chan, target_band);
} else {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, mcc violation chan %d band %d",
__func__, target_chan, target_band);
}
return status;
}
/**
* sap_same_band_channel_switch_validate() -
* check target chan valid or not during chan switch
* @sap_context: ptSapContext ptr
* @target_chan: target chan to switch
*
* This function checks whether target chan violates the same band
* SCC policy.
*
* Return: TRUE: target chan doesn't violate the policy
*/
static bool
sap_same_band_channel_switch_validate(
ptSapContext sap_context,
v_U16_t target_chan)
{
session_info_t station_info;
v_SINT_t candidate_chan = 0;
eCsrBand target_band;
if (target_chan == 0)
return false;
if (target_chan > MAX_2_4GHZ_CHANNEL)
target_band = eCSR_BAND_5G;
else
target_band = eCSR_BAND_24;
/*
* find and check active station session on same band
*/
if (sap_find_station_session_info(sap_context, &station_info)) {
if (station_info.band == target_band)
candidate_chan = station_info.och;
}
return candidate_chan == 0 || candidate_chan == target_chan;
}
/**
* sap_overlap_channel_switch_validate() -
* check target chan valid or not during chan switch
* @sap_context: ptSapContext ptr
* @target_chan: target chan to switch
*
* This function checks whether target chan violates the same band
* overlap policy.
*
* Return: TRUE: target chan doesn't violate the policy
*/
static bool
sap_overlap_channel_switch_validate(
ptSapContext sap_context,
v_U16_t target_chan)
{
session_info_t station_info, target_info;
v_SINT_t candidate_chan = 0;
if (target_chan == 0)
return false;
if (!sap_create_session_info(sap_context, &target_info,
target_chan))
return false;
/*
* find and check active station session on same band
*/
if (sap_find_station_session_info(sap_context, &station_info)) {
if (station_info.band == target_info.band)
if (sap_overlap_check(&target_info, &station_info))
candidate_chan = station_info.och;
}
return candidate_chan == 0 || candidate_chan == target_chan;
}
/**
* sap_channel_switch_validate() -
* check target chan valid or not during chan switch
* @sap_context: ptSapContext ptr
* @target_chan: target chan to switch
*
* This function checks whether target chan violates the configurated MCC to
* SCC policy.
*
* Return: TRUE: target chan doesn't violate the policy
*/
bool
sap_channel_switch_validate(
ptSapContext sap_context,
tHalHandle hal,
uint16_t target_channel,
eCsrPhyMode sap_phy_mode,
uint8_t cc_switch_mode,
uint32_t session_id)
{
if (sap_context->cc_switch_mode == VOS_MCC_TO_SCC_SWITCH_FORCE)
return sap_same_band_channel_switch_validate(sap_context,
target_channel);
else if (sap_context->cc_switch_mode
== VOS_MCC_TO_SCC_SWITCH_ENABLE)
return sap_overlap_channel_switch_validate(sap_context,
target_channel);
else
return true;
}
#endif
/*==========================================================================
FUNCTION sapGotoChannelSel
DESCRIPTION
Function for initiating scan request for SME
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext : Sap Context value
sapEvent : State machine event
sapDoAcsPreStartBss: VOS_TRUE, if ACS scan is issued pre start BSS.
VOS_FALSE, if ACS scan is issued post start BSS.
RETURN VALUE
The VOS_STATUS code associated with performing the operation
VOS_STATUS_SUCCESS: Success
SIDE EFFECTS
============================================================================*/
VOS_STATUS
sapGotoChannelSel
(
ptSapContext sapContext,
ptWLAN_SAPEvent sapEvent,
v_BOOL_t sapDoAcsPreStartBss
)
{
/* Initiate a SCAN request */
eHalStatus halStatus;
tCsrScanRequest scanRequest;/* To be initialised if scan is required */
v_U32_t scanRequestID = 0;
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
#ifdef SOFTAP_CHANNEL_RANGE
v_U8_t *channelList = NULL;
v_U8_t numOfChannels = 0 ;
#endif
tHalHandle hHal;
tANI_U8 con_ch;
hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, sapContext->pvosGCtx);
if (NULL == hHal)
{
/* we have a serious problem */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
"In %s, invalid hHal", __func__);
return VOS_STATUS_E_FAULT;
}
if (vos_concurrent_beaconing_sessions_running()) {
con_ch = sme_GetConcurrentOperationChannel(hHal);
#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
if (con_ch && sapContext->channel == AUTO_CHANNEL_SELECT) {
sapContext->dfs_ch_disable = VOS_TRUE;
} else if (con_ch && sapContext->channel != con_ch &&
VOS_IS_DFS_CH(sapContext->channel)) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
"In %s, MCC DFS not supported in AP_AP Mode", __func__);
return VOS_STATUS_E_ABORTED;
}
#endif
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
vosStatus = sap_concurrency_chan_override(
sapContext,
sapContext->cc_switch_mode,
&con_ch);
if (vosStatus != VOS_STATUS_SUCCESS) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s: invalid SAP channel(%d) configuration",
__func__,sapContext->channel);
return VOS_STATUS_E_ABORTED;
}
#endif
}
if (vos_get_concurrency_mode() == VOS_STA_SAP)
{
#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
if (sapContext->channel == AUTO_CHANNEL_SELECT)
sapContext->dfs_ch_disable = VOS_TRUE;
else if (VOS_IS_DFS_CH(sapContext->channel)) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
"In %s, DFS not supported in STA_AP Mode, chan=%d",
__func__, sapContext->channel);
return VOS_STATUS_E_ABORTED;
}
#endif
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
vosStatus = sap_concurrency_chan_override(
sapContext,
sapContext->cc_switch_mode,
&con_ch);
if (vosStatus != VOS_STATUS_SUCCESS) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s: invalid SAP channel(%d) configuration",
__func__,sapContext->channel);
return VOS_STATUS_E_ABORTED;
}
#else
/* If STA-AP concurrency is enabled take the concurrent connected
* channel first. In other cases wpa_supplicant should take care */
con_ch = sme_GetConcurrentOperationChannel(hHal);
if (con_ch)
{ /*if a valid channel is returned then use concurrent channel.
Else take whatever comes from configuartion*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
FL("Channel overridden due to MCC->SCC switch: %d -> %d"),
sapContext->channel, con_ch);
sapContext->channel = con_ch;
sme_SelectCBMode(hHal, sapContext->csrRoamProfile.phyMode,
con_ch, 0, &sapContext->vht_channel_width,
sapContext->ch_width_orig);
}
#endif
}
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
else if (sapContext->ap_p2pclient_concur_enable &&
vos_get_concurrency_mode() == (VOS_SAP|VOS_P2P_CLIENT)) {
#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
if (sapContext->channel == AUTO_CHANNEL_SELECT)
sapContext->dfs_ch_disable = VOS_TRUE;
else if (VOS_IS_DFS_CH(sapContext->channel)) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
"In %s, DFS not supported in STA_AP Mode, chan=%d",
__func__, sapContext->channel);
return VOS_STATUS_E_ABORTED;
}
#endif
vosStatus = sap_concurrency_chan_override(
sapContext,
sapContext->cc_switch_mode,
&con_ch);
if (vosStatus != VOS_STATUS_SUCCESS) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s: invalid SAP channel(%d) configuration",
__func__,sapContext->channel);
return VOS_STATUS_E_ABORTED;
}
}
#endif
if (sapContext->channel == AUTO_CHANNEL_SELECT)
{
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"%s acs_cfg->skip_status = %d ", __func__,
sapContext->acs_cfg->skip_scan_status);
if (sapContext->acs_cfg->skip_scan_status != eSAP_SKIP_ACS_SCAN) {
#endif
vos_mem_zero(&scanRequest, sizeof(scanRequest));
/* Set scanType to Active scan. FW takes care of using passive
* scan for DFS and active for non DFS channels.
*/
scanRequest.scanType = eSIR_ACTIVE_SCAN;
/* Set min and max channel time to zero */
scanRequest.minChnTime = 0;
scanRequest.maxChnTime = 0;
/* Set BSSType to default type */
scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
if (ACS_FW_REPORT_PARAM_CONFIGURED)
scanRequest.BSSType = eCSR_BSS_TYPE_INFRA_AP;
#ifndef SOFTAP_CHANNEL_RANGE
/*Scan all the channels */
scanRequest.ChannelInfo.numOfChannels = 0;
scanRequest.ChannelInfo.ChannelList = NULL;
scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
//eCSR_SCAN_REQUEST_11D_SCAN;
#else
sapGetChannelList(sapContext, &channelList, &numOfChannels);
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
if (numOfChannels != 0) {
#endif
/*Scan the channels in the list*/
scanRequest.ChannelInfo.numOfChannels = numOfChannels;
scanRequest.ChannelInfo.ChannelList = channelList;
scanRequest.requestType = eCSR_SCAN_SOFTAP_CHANNEL_RANGE;
sapContext->channelList = channelList;
sapContext->num_of_channel = numOfChannels;
#endif
/* Set requestType to Full scan */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, calling sme_ScanRequest", __func__);
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
if (sapContext->acs_cfg->skip_scan_status == eSAP_DO_NEW_ACS_SCAN) {
#endif
sme_ScanFlushResult(hHal, sapContext->sessionId);
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
}
#endif
if (VOS_TRUE == sapDoAcsPreStartBss)
{
halStatus = sme_ScanRequest(hHal,
sapContext->sessionId,
&scanRequest,
/* when ID == 0 11D scan/active
* scan with callback,
* min-maxChntime set in csrScanRequest()?
*/
&scanRequestID,
/*csrScanCompleteCallback callback,*/
&WLANSAP_PreStartBssAcsScanCallback,
/* pContext scanRequestID filled up*/
sapContext);
}
else
{
halStatus = sme_ScanRequest(hHal,
sapContext->sessionId,
&scanRequest,
/* when ID == 0 11D scan/active
* scan with callback,
* min-maxChntime set in csrScanRequest()?
*/
&scanRequestID,
/*csrScanCompleteCallback callback,*/
&WLANSAP_ScanCallback,
/* pContext scanRequestID filled up*/
sapContext);
}
if (eHAL_STATUS_SUCCESS != halStatus)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s:sme_ScanRequest fail %d!!!", __func__, halStatus);
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"SoftAP Configuring for default channel, Ch= %d",
sapContext->channel);
sapContext->channel =
sap_select_default_oper_chan_ini(hHal, 0);
#ifdef SOFTAP_CHANNEL_RANGE
if(sapContext->channelList != NULL)
{
sapContext->channel = sapContext->channelList[0];
vos_mem_free(sapContext->channelList);
sapContext->channelList = NULL;
sapContext->num_of_channel = 0;
}
#endif
if (VOS_TRUE == sapDoAcsPreStartBss)
{
/*
* In case of ACS req before start Bss,
* return failure so that the calling
* fucntion can use the default channel.
*/
return VOS_STATUS_E_FAILURE;
}
else
{
/* Fill in the event structure */
sapEventInit(sapEvent);
/* Handle event */
vosStatus = sapFsm(sapContext, sapEvent);
}
}
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, return from sme_ScanReq, scanID=%d, Ch= %d",
__func__, scanRequestID, sapContext->channel);
}
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
} else
sapContext->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN;
}
if (sapContext->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"## %s SKIPPED ACS SCAN", __func__);
if (VOS_TRUE == sapDoAcsPreStartBss)
{
WLANSAP_PreStartBssAcsScanCallback(hHal, sapContext,
sapContext->sessionId,
0,
eCSR_SCAN_SUCCESS);
}
else
{
WLANSAP_ScanCallback(hHal, sapContext,
sapContext->sessionId,
0,
eCSR_SCAN_SUCCESS);
}
}
#endif
}
else
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, for configured channel, Ch= %d",
__func__, sapContext->channel);
if (VOS_TRUE == sapDoAcsPreStartBss)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"In %s, ACS end due to channel override, Selected Ch= %d",
__func__, sapContext->channel);
sapContext->acs_cfg->pri_ch = sapContext->channel;
sap_config_acs_result(hHal, sapContext, 0);
return VOS_STATUS_E_CANCELED;
}
else
{
/* Fill in the event structure */
// Eventhough scan was not done, means a user set channel was chosen
sapEventInit(sapEvent);
/* Handle event */
vosStatus = sapFsm(sapContext, sapEvent);
}
}
/* If scan failed, get default channel and advance state machine as success with default channel */
/* Have to wait for the call back to be called to get the channel cannot advance state machine here as said above */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before exiting sapGotoChannelSel channel=%d", __func__, sapContext->channel);
return VOS_STATUS_SUCCESS;
}// sapGotoChannelSel
#define SAP_OPEN_SESSION_TIMEOUT 500
/**
* sap_OpenSession() - Opens a SAP session
* @hHal: Hal handle
* @sapContext: Sap Context value
* @session_id: Pointer to the session id
*
* Function for opening SME and SAP sessions when system is in SoftAP role
*
* Return: eHalStatus
*/
eHalStatus
sap_OpenSession (tHalHandle hHal, ptSapContext sapContext,
uint32_t *session_id)
{
tANI_U32 type, subType;
eHalStatus halStatus;
VOS_STATUS status = VOS_STATUS_E_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
if (sapContext->csrRoamProfile.csrPersona == VOS_P2P_GO_MODE)
status = vos_get_vdev_types(VOS_P2P_GO_MODE, &type, &subType);
else
status = vos_get_vdev_types(VOS_STA_SAP_MODE, &type, &subType);
if (VOS_STATUS_SUCCESS != status)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, "failed to get vdev type");
return VOS_STATUS_E_FAILURE;
}
vos_event_reset(&sapContext->sap_session_opened_evt);
/* Open SME Session for Softap */
halStatus = sme_OpenSession(hHal,
&WLANSAP_RoamCallback,
sapContext,
sapContext->self_mac_addr,
&sapContext->sessionId,
type, subType);
if(eHAL_STATUS_SUCCESS != halStatus )
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"Error: In %s calling sme_RoamConnect status = %d",
__func__, halStatus);
return VOS_STATUS_E_FAILURE;
}
sme_set_allowed_action_frames(hHal,
ALLOWED_ACTION_FRAMES_BITMAP0_SAP, false);
status = vos_wait_single_event(
&sapContext->sap_session_opened_evt,
SAP_OPEN_SESSION_TIMEOUT);
if (!VOS_IS_STATUS_SUCCESS(status)) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"wait for sap open session event timed out");
sme_CloseSession(hHal, sapContext->sessionId, NULL, FALSE);
return VOS_STATUS_E_FAILURE;
}
pMac->sap.sapCtxList [ sapContext->sessionId ].sessionID =
sapContext->sessionId;
pMac->sap.sapCtxList [ sapContext->sessionId ].pSapContext = sapContext;
pMac->sap.sapCtxList [ sapContext->sessionId ].sapPersona=
sapContext->csrRoamProfile.csrPersona;
*session_id = sapContext->sessionId;
sapContext->isSapSessionOpen = eSAP_TRUE;
return VOS_STATUS_SUCCESS;
}
/*==========================================================================
FUNCTION sapGotoStarting
DESCRIPTION
Function for initiating start bss request for SME
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext : Sap Context value
sapEvent : State machine event
bssType : Type of bss to start, INRA AP
status : Return the SAP status here
RETURN VALUE
The VOS_STATUS code associated with performing the operation
VOS_STATUS_SUCCESS: Success
SIDE EFFECTS
============================================================================*/
VOS_STATUS
sapGotoStarting
(
ptSapContext sapContext,
ptWLAN_SAPEvent sapEvent,
eCsrRoamBssType bssType
)
{
/* tHalHandle */
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
eHalStatus halStatus;
/*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/
char key_material[32]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,};
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
sapContext->key_type = 0x05;
sapContext->key_length = 32;
vos_mem_copy(sapContext->key_material, key_material, sizeof(key_material)); /* Need a key size define */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s", __func__);
if (NULL == hHal)
{
/* we have a serious problem */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
"In %s, invalid hHal", __func__);
return VOS_STATUS_E_FAULT;
}
/* No Need to Req for Power with power offload enabled */
if(!pMac->psOffloadEnabled)
{
//TODO: What shall we do if failure????
halStatus = pmcRequestFullPower( hHal,
WLANSAP_pmcFullPwrReqCB,
sapContext,
eSME_REASON_OTHER);
}
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s: session: %d", __func__, sapContext->sessionId);
halStatus = sme_RoamConnect(hHal, sapContext->sessionId,
&sapContext->csrRoamProfile,
&sapContext->csrRoamId);
if (eHAL_STATUS_SUCCESS != halStatus)
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s: Failed to issue sme_RoamConnect", __func__);
return halStatus;
}// sapGotoStarting
/*==========================================================================
FUNCTION sapGotoDisconnecting
DESCRIPTION
Processing of SAP FSM Disconnecting state
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext : Sap Context value
status : Return the SAP status here
RETURN VALUE
The VOS_STATUS code associated with performing the operation
VOS_STATUS_SUCCESS: Success
SIDE EFFECTS
============================================================================*/
VOS_STATUS
sapGotoDisconnecting
(
ptSapContext sapContext
)
{
eHalStatus halStatus;
tHalHandle hHal;
hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
/* we have a serious problem */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, invalid hHal", __func__);
return VOS_STATUS_E_FAULT;
}
sapFreeRoamProfile(&sapContext->csrRoamProfile);
halStatus = sme_RoamStopBss(hHal, sapContext->sessionId);
if(eHAL_STATUS_SUCCESS != halStatus )
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "Error: In %s calling sme_RoamStopBss status = %d", __func__, halStatus);
return VOS_STATUS_E_FAILURE;
}
return VOS_STATUS_SUCCESS;
}
eHalStatus sapRoamSessionCloseCallback(void *pContext)
{
ptSapContext sapContext = (ptSapContext)pContext;
return sapSignalHDDevent(sapContext, NULL,
eSAP_STOP_BSS_EVENT, (v_PVOID_t) eSAP_STATUS_SUCCESS);
}
/*==========================================================================
FUNCTION sapGotoDisconnected
DESCRIPTION
Function for setting the SAP FSM to Disconnection state
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext : Sap Context value
sapEvent : State machine event
status : Return the SAP status here
RETURN VALUE
The VOS_STATUS code associated with performing the operation
VOS_STATUS_SUCCESS: Success
SIDE EFFECTS
============================================================================*/
VOS_STATUS
sapGotoDisconnected
(
ptSapContext sapContext
)
{
VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
tWLAN_SAPEvent sapEvent;
// Processing has to be coded
// Clean up stations from TL etc as AP BSS is shut down then set event
sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS;// hardcoded
sapEvent.params = 0;
sapEvent.u1 = 0;
sapEvent.u2 = 0;
/* Handle event */
vosStatus = sapFsm(sapContext, &sapEvent);
return vosStatus;
}
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
/**
* sap_handle_acs_scan_event() - handle acs scan event for SAP
* @sap_context: ptSapContext
* @sap_event: tSap_Event
* @status: status of acs scan
*
* The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
*
* Return: void
*/
static void sap_handle_acs_scan_event(ptSapContext sap_context,
tSap_Event *sap_event, eSapStatus status)
{
sap_event->sapHddEventCode = eSAP_ACS_SCAN_SUCCESS_EVENT;
sap_event->sapevt.sap_acs_scan_comp.status = status;
sap_event->sapevt.sap_acs_scan_comp.num_of_channels =
sap_context->num_of_channel;
sap_event->sapevt.sap_acs_scan_comp.channellist =
sap_context->channelList;
}
#else
static void sap_handle_acs_scan_event(ptSapContext sap_context,
tSap_Event *sap_event, eSapStatus status)
{
}
#endif
/*==========================================================================
FUNCTION sapSignalHDDevent
DESCRIPTION
Function for HDD to send the event notification using callback
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext : Sap Context value
pCsrRoamInfo : Pointer to CSR roam information
sapHddevent : SAP HDD event
context : to pass the element for future support
RETURN VALUE
The VOS_STATUS code associated with performing the operation
VOS_STATUS_SUCCESS: Success
SIDE EFFECTS
============================================================================*/
VOS_STATUS
sapSignalHDDevent
(
ptSapContext sapContext, /* sapContext value */
tCsrRoamInfo *pCsrRoamInfo,
eSapHddEvent sapHddevent,
void *context
)
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
tSap_Event sapApAppEvent; /* This now encodes ALL event types */
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
tpAniSirGlobal pMac;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* Format the Start BSS Complete event to return... */
if (NULL == sapContext->pfnSapEventCallback)
{
return VOS_STATUS_E_FAILURE;
}
if (NULL == hHal)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s invalid hHal", __func__);
return VOS_STATUS_E_FAILURE;
}
pMac = PMAC_STRUCT( hHal );
switch (sapHddevent)
{
case eSAP_STA_ASSOC_IND:
// TODO - Indicate the assoc request indication to OS
sapApAppEvent.sapHddEventCode = eSAP_STA_ASSOC_IND;
vos_mem_copy( &sapApAppEvent.sapevt.sapAssocIndication.staMac, pCsrRoamInfo->peerMac,sizeof(tSirMacAddr));
sapApAppEvent.sapevt.sapAssocIndication.staId = pCsrRoamInfo->staId;
sapApAppEvent.sapevt.sapAssocIndication.status = 0;
// Required for indicating the frames to upper layer
sapApAppEvent.sapevt.sapAssocIndication.beaconLength = pCsrRoamInfo->beaconLength;
sapApAppEvent.sapevt.sapAssocIndication.beaconPtr = pCsrRoamInfo->beaconPtr;
sapApAppEvent.sapevt.sapAssocIndication.assocReqLength = pCsrRoamInfo->assocReqLength;
sapApAppEvent.sapevt.sapAssocIndication.assocReqPtr = pCsrRoamInfo->assocReqPtr;
sapApAppEvent.sapevt.sapAssocIndication.fWmmEnabled = pCsrRoamInfo->wmmEnabledSta;
sapApAppEvent.sapevt.sapAssocIndication.ecsa_capable =
pCsrRoamInfo->ecsa_capable;
if ( pCsrRoamInfo->u.pConnectedProfile != NULL )
{
sapApAppEvent.sapevt.sapAssocIndication.negotiatedAuthType = pCsrRoamInfo->u.pConnectedProfile->AuthType;
sapApAppEvent.sapevt.sapAssocIndication.negotiatedUCEncryptionType = pCsrRoamInfo->u.pConnectedProfile->EncryptionType;
sapApAppEvent.sapevt.sapAssocIndication.negotiatedMCEncryptionType = pCsrRoamInfo->u.pConnectedProfile->mcEncryptionType;
sapApAppEvent.sapevt.sapAssocIndication.fAuthRequired = pCsrRoamInfo->fAuthRequired;
}
break;
case eSAP_START_BSS_EVENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_START_BSS_EVENT");
sapApAppEvent.sapHddEventCode = eSAP_START_BSS_EVENT;
sapApAppEvent.sapevt.sapStartBssCompleteEvent.status = (eSapStatus )context;
if(pCsrRoamInfo != NULL ){
sapApAppEvent.sapevt.sapStartBssCompleteEvent.staId = pCsrRoamInfo->staId;
}
else
{
sapApAppEvent.sapevt.sapStartBssCompleteEvent.staId =
tl_shim_get_sta_id_by_addr(sapContext->pvosGCtx,
sapContext->self_mac_addr);
}
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s(eSAP_START_BSS_EVENT): staId = %d",
__func__, sapApAppEvent.sapevt.sapStartBssCompleteEvent.staId);
sapApAppEvent.sapevt.sapStartBssCompleteEvent.operatingChannel = (v_U8_t)sapContext->channel;
sapApAppEvent.sapevt.sapStartBssCompleteEvent.sessionId =
sapContext->sessionId;
break;
case eSAP_DFS_CAC_START:
case eSAP_DFS_CAC_INTERRUPTED:
case eSAP_DFS_CAC_END:
case eSAP_DFS_RADAR_DETECT:
case eSAP_DFS_NO_AVAILABLE_CHANNEL:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, SAP event callback event = %s : %d", __func__,
"eSAP_DFS event", sapHddevent);
sapApAppEvent.sapHddEventCode = sapHddevent;
sapApAppEvent.sapevt.sapStopBssCompleteEvent.status =
(eSapStatus )context;
break;
case eSAP_ACS_SCAN_SUCCESS_EVENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, SAP event callback event = %s : %d", __func__,
"ACS Scan event", sapHddevent);
sap_handle_acs_scan_event(sapContext, &sapApAppEvent,
(eSapStatus)context);
break;
case eSAP_ACS_CHANNEL_SELECTED:
sapApAppEvent.sapHddEventCode = sapHddevent;
if ( eSAP_STATUS_SUCCESS == (eSapStatus )context)
{
sapApAppEvent.sapevt.sapChSelected.pri_ch =
sapContext->acs_cfg->pri_ch;
sapApAppEvent.sapevt.sapChSelected.ht_sec_ch =
sapContext->acs_cfg->ht_sec_ch;
sapApAppEvent.sapevt.sapChSelected.ch_width =
sapContext->acs_cfg->ch_width;
sapApAppEvent.sapevt.sapChSelected.vht_seg0_center_ch =
sapContext->acs_cfg->vht_seg0_center_ch;
sapApAppEvent.sapevt.sapChSelected.vht_seg1_center_ch =
sapContext->acs_cfg->vht_seg1_center_ch;
}
else if (eSAP_STATUS_FAILURE == (eSapStatus )context)
{
sapApAppEvent.sapevt.sapChSelected.pri_ch = 0;
}
break;
case eSAP_STOP_BSS_EVENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_STOP_BSS_EVENT");
sapApAppEvent.sapHddEventCode = eSAP_STOP_BSS_EVENT;
sapApAppEvent.sapevt.sapStopBssCompleteEvent.status = (eSapStatus )context;
break;
case eSAP_STA_ASSOC_EVENT:
case eSAP_STA_REASSOC_EVENT:
{
tSirSmeChanInfo *pChanInfo;
tSap_StationAssocReassocCompleteEvent *sta_event_ptr;
sta_event_ptr =
&sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent;
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_STA_ASSOC_EVENT");
if (pCsrRoamInfo->fReassocReq)
sapApAppEvent.sapHddEventCode = eSAP_STA_REASSOC_EVENT;
else
sapApAppEvent.sapHddEventCode = eSAP_STA_ASSOC_EVENT;
//TODO: Need to fill the SET KEY information and pass to HDD
vos_mem_copy(&sta_event_ptr->staMac,
pCsrRoamInfo->peerMac,sizeof(tSirMacAddr));
sta_event_ptr->staId = pCsrRoamInfo->staId;
sta_event_ptr->statusCode = pCsrRoamInfo->statusCode;
sta_event_ptr->iesLen = pCsrRoamInfo->rsnIELen;
vos_mem_copy(sta_event_ptr->ies, pCsrRoamInfo->prsnIE,
pCsrRoamInfo->rsnIELen);
sta_event_ptr->ampdu = pCsrRoamInfo->ampdu;
sta_event_ptr->sgi_enable = pCsrRoamInfo->sgi_enable;
sta_event_ptr->tx_stbc = pCsrRoamInfo->tx_stbc;
sta_event_ptr->rx_stbc = pCsrRoamInfo->rx_stbc;
sta_event_ptr->ch_width = pCsrRoamInfo->ch_width;
sta_event_ptr->mode = pCsrRoamInfo->mode;
sta_event_ptr->max_supp_idx = pCsrRoamInfo->max_supp_idx;
sta_event_ptr->max_ext_idx = pCsrRoamInfo->max_ext_idx;
sta_event_ptr->max_mcs_idx = pCsrRoamInfo->max_mcs_idx;
sta_event_ptr->rx_mcs_map = pCsrRoamInfo->rx_mcs_map;
sta_event_ptr->tx_mcs_map = pCsrRoamInfo->tx_mcs_map;
#ifdef FEATURE_WLAN_WAPI
if(pCsrRoamInfo->wapiIELen)
{
v_U8_t len = sta_event_ptr->iesLen;
sta_event_ptr->iesLen
+= pCsrRoamInfo->wapiIELen;
vos_mem_copy(&sta_event_ptr->ies[len],
pCsrRoamInfo->pwapiIE,
pCsrRoamInfo->wapiIELen);
}
#endif
if(pCsrRoamInfo->addIELen)
{
v_U8_t len = sta_event_ptr->iesLen;
sta_event_ptr->iesLen
+= pCsrRoamInfo->addIELen;
vos_mem_copy(&sta_event_ptr->ies[len], pCsrRoamInfo->paddIE,
pCsrRoamInfo->addIELen);
}
/* also fill up the channel info from the csrRoamInfo */
pChanInfo =
&sta_event_ptr->chan_info;
pChanInfo->chan_id = pCsrRoamInfo->chan_info.chan_id;
pChanInfo->mhz = pCsrRoamInfo->chan_info.mhz;
pChanInfo->info = pCsrRoamInfo->chan_info.info;
pChanInfo->band_center_freq1 = pCsrRoamInfo->chan_info.band_center_freq1;
pChanInfo->band_center_freq2 = pCsrRoamInfo->chan_info.band_center_freq2;
pChanInfo->reg_info_1 = pCsrRoamInfo->chan_info.reg_info_1;
pChanInfo->reg_info_2 = pCsrRoamInfo->chan_info.reg_info_2;
pChanInfo->nss = pCsrRoamInfo->chan_info.nss;
pChanInfo->rate_flags = pCsrRoamInfo->chan_info.rate_flags;
pChanInfo->sub20_channelwidth =
pCsrRoamInfo->chan_info.sub20_channelwidth;
sta_event_ptr->wmmEnabled = pCsrRoamInfo->wmmEnabledSta;
sta_event_ptr->status = (eSapStatus )context;
sta_event_ptr->timingMeasCap = pCsrRoamInfo->timingMeasCap;
sta_event_ptr->ecsa_capable = pCsrRoamInfo->ecsa_capable;
//TODO: Need to fill sapAuthType
//sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.SapAuthType = pCsrRoamInfo->pProfile->negotiatedAuthType;
break;
}
case eSAP_STA_DISASSOC_EVENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_STA_DISASSOC_EVENT");
sapApAppEvent.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
vos_mem_copy( &sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.staMac,
pCsrRoamInfo->peerMac, sizeof(tSirMacAddr));
sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.staId = pCsrRoamInfo->staId;
if (pCsrRoamInfo->reasonCode == eCSR_ROAM_RESULT_FORCED)
sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.reason = eSAP_USR_INITATED_DISASSOC;
else
sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.reason = eSAP_MAC_INITATED_DISASSOC;
sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.statusCode = pCsrRoamInfo->statusCode;
sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.status = (eSapStatus )context;
break;
case eSAP_STA_SET_KEY_EVENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_STA_SET_KEY_EVENT");
sapApAppEvent.sapHddEventCode = eSAP_STA_SET_KEY_EVENT;
sapApAppEvent.sapevt.sapStationSetKeyCompleteEvent.status = (eSapStatus )context;
vos_mem_copy(&sapApAppEvent.sapevt.sapStationSetKeyCompleteEvent.peerMacAddr,
pCsrRoamInfo->peerMac,sizeof(tSirMacAddr));
break;
case eSAP_STA_DEL_KEY_EVENT :
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_STA_DEL_KEY_EVENT");
sapApAppEvent.sapHddEventCode = eSAP_STA_DEL_KEY_EVENT;
sapApAppEvent.sapevt.sapStationDeleteKeyCompleteEvent.status = (eSapStatus )context;
//TODO: Should we need to send the key information
//sapApAppEvent.sapevt.sapStationDeleteKeyCompleteEvent.keyId = ;
break;
case eSAP_STA_MIC_FAILURE_EVENT :
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_STA_MIC_FAILURE_EVENT");
sapApAppEvent.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT;
vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.srcMacAddr,
pCsrRoamInfo->u.pMICFailureInfo->srcMacAddr,
sizeof(tSirMacAddr));
vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.staMac,
pCsrRoamInfo->u.pMICFailureInfo->taMacAddr,
sizeof(tSirMacAddr));
vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.dstMacAddr,
pCsrRoamInfo->u.pMICFailureInfo->dstMacAddr,
sizeof(tSirMacAddr));
sapApAppEvent.sapevt.sapStationMICFailureEvent.multicast = pCsrRoamInfo->u.pMICFailureInfo->multicast;
sapApAppEvent.sapevt.sapStationMICFailureEvent.IV1 = pCsrRoamInfo->u.pMICFailureInfo->IV1;
sapApAppEvent.sapevt.sapStationMICFailureEvent.keyId = pCsrRoamInfo->u.pMICFailureInfo->keyId;
vos_mem_copy( sapApAppEvent.sapevt.sapStationMICFailureEvent.TSC,
pCsrRoamInfo->u.pMICFailureInfo->TSC,
SIR_CIPHER_SEQ_CTR_SIZE);
break;
case eSAP_ASSOC_STA_CALLBACK_EVENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_ASSOC_STA_CALLBACK_EVENT");
break;
case eSAP_WPS_PBC_PROBE_REQ_EVENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_WPS_PBC_PROBE_REQ_EVENT");
sapApAppEvent.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT;
vos_mem_copy( &sapApAppEvent.sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq,
pCsrRoamInfo->u.pWPSPBCProbeReq,
sizeof(tSirWPSPBCProbeReq));
break;
case eSAP_REMAIN_CHAN_READY:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_REMAIN_CHAN_READY");
sapApAppEvent.sapHddEventCode = eSAP_REMAIN_CHAN_READY;
break;
case eSAP_DISCONNECT_ALL_P2P_CLIENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_DISCONNECT_ALL_P2P_CLIENT");
sapApAppEvent.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context;
break;
case eSAP_MAC_TRIG_STOP_BSS_EVENT :
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_MAC_TRIG_STOP_BSS_EVENT");
sapApAppEvent.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context;
break;
case eSAP_UNKNOWN_STA_JOIN:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_UNKNOWN_STA_JOIN");
sapApAppEvent.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN;
vos_mem_copy((v_PVOID_t)sapApAppEvent.sapevt.sapUnknownSTAJoin.macaddr.bytes,
(v_PVOID_t)context, sizeof(v_MACADDR_t));
break;
case eSAP_MAX_ASSOC_EXCEEDED:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("SAP event callback event = %s"),
"eSAP_MAX_ASSOC_EXCEEDED");
sapApAppEvent.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED;
vos_mem_copy((v_PVOID_t)sapApAppEvent.sapevt.sapMaxAssocExceeded.macaddr.bytes,
(v_PVOID_t)pCsrRoamInfo->peerMac, sizeof(v_MACADDR_t));
break;
case eSAP_CHANNEL_CHANGE_EVENT:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, SAP event callback event = %s",
__func__, "eSAP_CHANNEL_CHANGE_EVENT");
/* Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS
* follows pri AP
*/
sapContext->acs_cfg->pri_ch = sapContext->channel;
sapContext->acs_cfg->ch_width = sapContext->vht_channel_width;
sap_config_acs_result(hHal, sapContext, sapContext->secondary_ch);
sapApAppEvent.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
sapApAppEvent.sapevt.sapChSelected.pri_ch =
sapContext->acs_cfg->pri_ch;
sapApAppEvent.sapevt.sapChSelected.ht_sec_ch =
sapContext->acs_cfg->ht_sec_ch;
sapApAppEvent.sapevt.sapChSelected.ch_width =
sapContext->acs_cfg->ch_width;
sapApAppEvent.sapevt.sapChSelected.vht_seg0_center_ch =
sapContext->acs_cfg->vht_seg0_center_ch;
sapApAppEvent.sapevt.sapChSelected.vht_seg1_center_ch =
sapContext->acs_cfg->vht_seg1_center_ch;
break;
case eSAP_DFS_NOL_GET:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, SAP event callback event = %s",
__func__, "eSAP_DFS_NOL_GET");
sapApAppEvent.sapHddEventCode = eSAP_DFS_NOL_GET;
sapApAppEvent.sapevt.sapDfsNolInfo.sDfsList =
NUM_5GHZ_CHANNELS * sizeof(tSapDfsNolInfo);
sapApAppEvent.sapevt.sapDfsNolInfo.pDfsList =
(v_PVOID_t)(&pMac->sap.SapDfsInfo.sapDfsChannelNolList[0]);
break;
case eSAP_DFS_NOL_SET:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, SAP event callback event = %s",
__func__, "eSAP_DFS_NOL_SET");
sapApAppEvent.sapHddEventCode = eSAP_DFS_NOL_SET;
sapApAppEvent.sapevt.sapDfsNolInfo.sDfsList =
pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels *
sizeof(tSapDfsNolInfo);
sapApAppEvent.sapevt.sapDfsNolInfo.pDfsList =
(v_PVOID_t)(&pMac->sap.SapDfsInfo.sapDfsChannelNolList[0]);
break;
case eSAP_ECSA_CHANGE_CHAN_IND:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, SAP event callback event = %s",
__func__, "eSAP_ECSA_CHANGE_CHAN_IND");
sapApAppEvent.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND;
sapApAppEvent.sapevt.sap_chan_cng_ind.new_chan =
pCsrRoamInfo->target_channel;
break;
default:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("SAP Unknown callback event = %d"),
sapHddevent);
break;
}
vosStatus = (*sapContext->pfnSapEventCallback)
(
&sapApAppEvent,
sapContext->pUsrContext//userdataforcallback - hdd opaque handle
);
return vosStatus;
} /* sapSignalApAppStartBssEvent */
/*==========================================================================
FUNCTION sap_find_valid_concurrent_session
DESCRIPTION
This function will return sapcontext of any valid sap session.
PARAMETERS
IN
hHal : HAL pointer
RETURN VALUE
ptSapContext : valid sap context
SIDE EFFECTS
NA
============================================================================*/
ptSapContext sap_find_valid_concurrent_session (tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
v_U8_t intf = 0;
for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++)
{
if (((VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona) ||
(VOS_P2P_GO_MODE == pMac->sap.sapCtxList [intf].sapPersona)) &&
pMac->sap.sapCtxList[intf].pSapContext != NULL)
{
return pMac->sap.sapCtxList[intf].pSapContext;
}
}
return NULL;
}
/*==========================================================================
FUNCTION sap_CloseSession
DESCRIPTION
This function will close all the sme sessions as well as zero-out the
sap global structure
PARAMETERS
IN
hHal : HAL pointer
sapContext : Sap Context value
callback : Roam Session close callback
valid : Sap context is valid or no
RETURN VALUE
The eHalStatus code associated with performing the operation
eHAL_STATUS_SUCCESS: Success
SIDE EFFECTS
NA
============================================================================*/
eHalStatus sap_CloseSession(tHalHandle hHal,
ptSapContext sapContext,
csrRoamSessionCloseCallback callback,
v_BOOL_t valid)
{
eHalStatus halstatus;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
if (FALSE == valid)
{
halstatus = sme_CloseSession(hHal,
sapContext->sessionId,
callback, NULL);
}
else
{
halstatus = sme_CloseSession(hHal,
sapContext->sessionId,
callback, sapContext);
}
sapContext->isCacStartNotified = VOS_FALSE;
sapContext->isCacEndNotified = VOS_FALSE;
pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = NULL;
sapContext->isSapSessionOpen = false;
if (NULL == sap_find_valid_concurrent_session(hHal))
{
/* If timer is running then stop the timer and destory
* it
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: no session are valid, so clearing dfs global structure");
/* CAC timer will be initiated and started only when SAP starts on
* DFS channel and it will be stopped and destroyed immediately once the
* radar detected or timedout. So as per design CAC timer should be
* destroyed after stop..*/
if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)
{
vos_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
}
pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
sap_CacResetNotify(hHal);
vos_mem_zero(&pMac->sap, sizeof(pMac->sap));
/*
* No valid concurrent AP sessions(SAP/P2PGO), switch back the
* allowed action frames bitmask to STA mode and set the same
* to FW
*/
sme_set_allowed_action_frames(hHal,
ALLOWED_ACTION_FRAMES_BITMAP0_STA, true);
}
return halstatus;
}
/*==========================================================================
FUNCTION sap_CacResetNotify
DESCRIPTION Function will be called up on stop bss indication to clean up
DFS global structure.
DEPENDENCIES PARAMETERS
IN hHAL : HAL pointer
RETURN VALUE : void.
SIDE EFFECTS
============================================================================*/
void sap_CacResetNotify(tHalHandle hHal)
{
v_U8_t intf = 0;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++)
{
ptSapContext pSapContext =
(ptSapContext)pMac->sap.sapCtxList [intf].pSapContext;
if (((VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona) ||
(VOS_P2P_GO_MODE == pMac->sap.sapCtxList [intf].sapPersona)) &&
pMac->sap.sapCtxList [intf].pSapContext != NULL)
{
pSapContext->isCacStartNotified = VOS_FALSE;
pSapContext->isCacEndNotified = VOS_FALSE;
}
}
}
/*==========================================================================
FUNCTION sap_CacStartNotify
DESCRIPTION Function will be called to Notify eSAP_DFS_CAC_START event
to HDD
DEPENDENCIES PARAMETERS
IN hHAL : HAL pointer
RETURN VALUE : VOS_STATUS.
SIDE EFFECTS
============================================================================*/
VOS_STATUS sap_CacStartNotify(tHalHandle hHal)
{
v_U8_t intf = 0;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++)
{
ptSapContext pSapContext =
(ptSapContext)pMac->sap.sapCtxList [intf].pSapContext;
if (((VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona) ||
(VOS_P2P_GO_MODE == pMac->sap.sapCtxList [intf].sapPersona)) &&
pMac->sap.sapCtxList [intf].pSapContext != NULL &&
(VOS_FALSE == pSapContext->isCacStartNotified))
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]",
pSapContext);
vosStatus = sapSignalHDDevent(pSapContext, NULL,
eSAP_DFS_CAC_START,
(v_PVOID_t) eSAP_STATUS_SUCCESS);
if (VOS_STATUS_SUCCESS != vosStatus)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, failed setting isCacStartNotified on interface[%d]",
__func__, intf);
return vosStatus;
}
pSapContext->isCacStartNotified = VOS_TRUE;
}
}
return vosStatus;
}
/*==========================================================================
FUNCTION sap_CacEndNotify
DESCRIPTION Function will be called to Notify eSAP_DFS_CAC_END event
to HDD
DEPENDENCIES PARAMETERS
IN hHAL : HAL pointer
RETURN VALUE : VOS_STATUS.
SIDE EFFECTS
============================================================================*/
VOS_STATUS sap_CacEndNotify(tHalHandle hHal, tCsrRoamInfo *roamInfo)
{
v_U8_t intf;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
/*
* eSAP_DFS_CHANNEL_CAC_END:
* CAC Period elapsed and there was no radar
* found so, SAP can continue beaconing.
* sap_radar_found_status is set to 0
*/
for ( intf = 0; intf < SAP_MAX_NUM_SESSION; intf++)
{
ptSapContext pSapContext =
(ptSapContext)pMac->sap.sapCtxList [intf].pSapContext;
if (((VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona) ||
(VOS_P2P_GO_MODE == pMac->sap.sapCtxList [intf].sapPersona)) &&
pMac->sap.sapCtxList [intf].pSapContext != NULL &&
(VOS_FALSE == pSapContext->isCacEndNotified))
{
pSapContext = pMac->sap.sapCtxList [intf].pSapContext;
vosStatus = sapSignalHDDevent(pSapContext, NULL,
eSAP_DFS_CAC_END,
(v_PVOID_t) eSAP_STATUS_SUCCESS);
if (VOS_STATUS_SUCCESS != vosStatus)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, failed setting isCacEndNotified on interface[%d]",
__func__, intf);
return vosStatus;
}
pSapContext->isCacEndNotified = VOS_TRUE;
pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_FALSE;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: Start beacon request on sapctx[%pK]",
pSapContext);
/* Start beaconing on the new channel */
WLANSAP_StartBeaconReq((v_PVOID_t)pSapContext);
/* Transition from eSAP_STARTING to eSAP_STARTED
* (both without substates)
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: channel[%d] from state %s => %s",
pSapContext->channel, "eSAP_STARTING",
"eSAP_STARTED");
pSapContext->sapsMachine = eSAP_STARTED;
/*Action code for transition */
vosStatus = sapSignalHDDevent(pSapContext, roamInfo,
eSAP_START_BSS_EVENT,
(v_PVOID_t)eSAP_STATUS_SUCCESS);
if (VOS_STATUS_SUCCESS != vosStatus)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, failed setting isCacEndNotified on interface[%d]",
__func__, intf);
return vosStatus;
}
/* Transition from eSAP_STARTING to eSAP_STARTED
* (both without substates)
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, from state %s => %s",
__func__, "eSAP_DFS_CAC_WAIT", "eSAP_STARTED");
}
}
/*
* All APs are done with CAC timer, all APs should start beaconing.
* Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets
* say AP1 goes down and comes back on same DFS channel. In this case
* AP1 shouldn't start CAC timer and start beacon immediately beacause
* AP2 is already beaconing on this channel. This case will be handled
* by checking against eSAP_DFS_SKIP_CAC while starting the timer.
*/
pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC;
return vosStatus;
}
/**
* sap_relaunch_acs_result_handler() - handle relaunched ACS result
* @sap_context: pointer of ptSapContext
* @roam_info: pointer to tCsrRoamInfo which contains result channel
*
* This function handle the relaunched ACS result and check if need to
* trigger CSA.
*
* Return: VOS_STATUS
*/
VOS_STATUS
sap_relaunch_acs_result_handler(ptSapContext sap_context,
tCsrRoamInfo *roam_info)
{
VOS_STATUS vos_status;
vos_mem_zero(sap_context->acs_cfg,
sizeof(struct sap_acs_cfg));
vos_status = sapSignalHDDevent(sap_context, NULL,
eSAP_ACS_CHANNEL_SELECTED,
(v_PVOID_t)eSAP_STATUS_SUCCESS);
if (!VOS_IS_STATUS_SUCCESS(vos_status))
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("Failed to indicate ACS complete."));
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"In %s: acs_target_channel=%d cur_channel=%d",
__func__,
roam_info->target_channel,
sap_context->channel);
if (!((roam_info->target_channel == sap_context->channel) ||
(roam_info->target_channel == SAP_CHANNEL_NOT_SELECTED))) {
vos_status = sapSignalHDDevent(sap_context, roam_info,
eSAP_ECSA_CHANGE_CHAN_IND,
(v_PVOID_t)NULL);
if (!VOS_IS_STATUS_SUCCESS(vos_status))
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_ERROR,
FL("trigger channel switch failed"));
}
return vos_status;
}
/*==========================================================================
FUNCTION sapFsm
DESCRIPTION
SAP State machine entry function
DEPENDENCIES
NA.
PARAMETERS
IN
sapContext : Sap Context value
sapEvent : State machine event
status : Return the SAP status here
RETURN VALUE
The VOS_STATUS code associated with performing the operation
VOS_STATUS_SUCCESS: Success
SIDE EFFECTS
============================================================================*/
VOS_STATUS
sapFsm
(
ptSapContext sapContext, /* sapContext value */
ptWLAN_SAPEvent sapEvent /* State machine event */
)
{
/* Retrieve the phy link state machine structure
* from the sapContext value
*/
eSapFsmStates_t stateVar = sapContext->sapsMachine; /*state var that keeps track of state machine*/
tCsrRoamInfo *roamInfo = (tCsrRoamInfo *)(sapEvent->params);
v_U32_t msg = sapEvent->event; /* State machine input event message */
VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
tpAniSirGlobal pMac;
v_U32_t cbMode;
v_BOOL_t b_leak_chan = FALSE;
#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
v_U8_t temp_chan;
tSapDfsNolInfo *pNol;
#endif
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s invalid hHal", __func__);
return VOS_STATUS_E_FAILURE;
}
pMac = PMAC_STRUCT( hHal );
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG, "%s: sapContext=%pK, stateVar=%d, msg=0x%x", __func__, sapContext, stateVar, msg);
switch (stateVar)
{
case eSAP_DISCONNECTED:
if ((msg == eSAP_HDD_START_INFRA_BSS))
{
/* Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT (both without substates) */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, new from state %s => %s, session id %d",
__func__, "eSAP_DISCONNECTED", "eSAP_CH_SELECT", sapContext->sessionId);
if (sapContext->isSapSessionOpen == eSAP_FALSE) {
uint32_t type, subtype;
if (sapContext->csrRoamProfile.csrPersona ==
VOS_P2P_GO_MODE)
vosStatus = vos_get_vdev_types(VOS_P2P_GO_MODE,
&type, &subtype);
else
vosStatus = vos_get_vdev_types(VOS_STA_SAP_MODE,
&type, &subtype);
if (VOS_STATUS_SUCCESS != vosStatus) {
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_FATAL,
"failed to get vdev type");
return VOS_STATUS_E_FAILURE;
}
vosStatus = sme_OpenSession(hHal, &WLANSAP_RoamCallback,
sapContext, sapContext->self_mac_addr,
&sapContext->sessionId, type, subtype);
if (VOS_STATUS_SUCCESS != vosStatus) {
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_ERROR,
FL("Error: calling sme_OpenSession"));
return VOS_STATUS_E_FAILURE;
}
sapContext->isSapSessionOpen = eSAP_TRUE;
}
/* init dfs channel nol */
sapInitDfsChannelNolList(sapContext);
/* Set SAP device role */
sapContext->sapsMachine = eSAP_CH_SELECT;
/*
* Perform sme_ScanRequest
* This scan request is post start bss
* request so, set the third to false.
*/
vosStatus = sapGotoChannelSel(sapContext, sapEvent, VOS_FALSE);
}
else if (msg == eSAP_DFS_CHANNEL_CAC_START)
{
/* No need of state check here, caller is expected to perform
* the checks before sending the event
*/
sapContext->sapsMachine = eSAP_DFS_CAC_WAIT;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT");
if ( pMac->sap.SapDfsInfo.is_dfs_cac_timer_running != VOS_TRUE)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: starting dfs cac timer on sapctx[%pK]",
sapContext);
sapStartDfsCacTimer(sapContext);
}
vosStatus = sap_CacStartNotify(hHal);
}
else if (msg == eSAP_CHANNEL_SELECTION_RETRY)
{
/* Set SAP device role */
sapContext->sapsMachine = eSAP_CH_SELECT;
/*
* Perform sme_ScanRequest
* This scan request is post start bss
* request so, set the third to false.
*/
vosStatus = sapGotoChannelSel(sapContext, sapEvent, VOS_FALSE);
}
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, event msg %d",
__func__, "eSAP_DISCONNECTED", msg);
}
break;
case eSAP_CH_SELECT:
if (msg == eSAP_MAC_SCAN_COMPLETE)
{
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, NULL hHal in state %s, msg %d ", __func__,
"eSAP_CH_SELECT", msg);
return VOS_STATUS_E_FAULT;
}
cbMode = sme_SelectCBMode(hHal,
sapContext->csrRoamProfile.phyMode,
sapContext->channel,
sapContext->secondary_ch,
&sapContext->vht_channel_width,
sapContext->ch_width_orig);
cbMode = sme_GetCBPhyStateFromCBIniValue(cbMode);
#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
temp_chan = sapContext->channel;
pNol = pMac->sap.SapDfsInfo.sapDfsChannelNolList;
sapMarkChannelsLeakingIntoNOL(sapContext,
cbMode, pNol, 1, &temp_chan);
/* if selelcted channel has leakage to channels
in NOL, the temp_chan will be reset */
b_leak_chan = (temp_chan != sapContext->channel);
#endif
/* check if channel is in DFS_NOL or
if the channel has leakage to the channels in NOL */
if (sapDfsIsChannelInNolList(sapContext, sapContext->channel,
cbMode) || b_leak_chan)
{
v_U8_t ch;
/* find a new available channel */
ch = sapRandomChannelSel(sapContext);
if (ch == 0) {
/* No available channel found */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("No available channel found!!!"));
sapSignalHDDevent(sapContext, NULL,
eSAP_DFS_NO_AVAILABLE_CHANNEL,
(v_PVOID_t) eSAP_STATUS_SUCCESS);
return VOS_STATUS_E_FAULT;
}
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("channel %d is in NOL, StartBss on new channel %d"),
sapContext->channel, ch);
sapContext->channel = ch;
sme_SelectCBMode(hHal, sapContext->csrRoamProfile.phyMode,
sapContext->channel,
sapContext->secondary_ch,
&sapContext->vht_channel_width,
sapContext->ch_width_orig);
}
if (sapContext->channel > 14 &&
(sapContext->csrRoamProfile.phyMode ==
eCSR_DOT11_MODE_11g ||
sapContext->csrRoamProfile.phyMode ==
eCSR_DOT11_MODE_11g_ONLY))
sapContext->csrRoamProfile.phyMode = eCSR_DOT11_MODE_11a;
/* when AP2 is started while AP1 is performing ACS, we may not
* have the AP1 channel yet.So here after the completion of AP2
* ACS check if AP1 ACS resulting channel is DFS and if yes
* override AP2 ACS scan result with AP1 DFS channel
*/
if (vos_concurrent_beaconing_sessions_running()) {
v_U16_t con_ch;
con_ch = sme_GetConcurrentOperationChannel(hHal);
if (con_ch && VOS_IS_DFS_CH(con_ch))
sapContext->channel = con_ch;
}
/* Transition from eSAP_CH_SELECT to eSAP_STARTING (both without substates) */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s",
__func__, "eSAP_CH_SELECT", "eSAP_STARTING");
// Channel selected. Now can sapGotoStarting
sapContext->sapsMachine = eSAP_STARTING;
// Specify the channel
sapContext->csrRoamProfile.ChannelInfo.numOfChannels = 1;
sapContext->csrRoamProfile.ChannelInfo.ChannelList = &sapContext->csrRoamProfile.operationChannel;
sapContext->csrRoamProfile.operationChannel = (tANI_U8)sapContext->channel;
sapContext->csrRoamProfile.vht_channel_width =
sapContext->vht_channel_width;
sapContext->csrRoamProfile.beacon_tx_rate =
sapContext->beacon_tx_rate;
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"%s: notify hostapd about channel selection: %d",
__func__, sapContext->channel);
sapSignalHDDevent(sapContext, NULL, eSAP_CHANNEL_CHANGE_EVENT,
(v_PVOID_t) eSAP_STATUS_SUCCESS);
vosStatus = sapGotoStarting( sapContext, sapEvent, eCSR_BSS_TYPE_INFRA_AP);
}
else if (msg == eSAP_CHANNEL_SELECTION_FAILED) {
sapContext->sapsMachine = eSAP_DISCONNECTED;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"\n\n***In %s, Cannot start BSS, ACS Fail***\n\n",
__func__);
sapSignalHDDevent(sapContext, NULL, eSAP_START_BSS_EVENT,
(v_PVOID_t) eSAP_STATUS_FAILURE);
} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
sapContext->sapsMachine = eSAP_DISCONNECTED;
sapSignalHDDevent(sapContext, NULL, eSAP_START_BSS_EVENT,
(v_PVOID_t)eSAP_STATUS_FAILURE);
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s: BSS stopped during Ch select in Progress", __func__);
} else {
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, invalid event msg %d",
__func__, "eSAP_CH_SELECT", msg);
}
break;
case eSAP_DFS_CAC_WAIT:
if (msg == eSAP_DFS_CHANNEL_CAC_START)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s",
__func__, "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT");
if ( pMac->sap.SapDfsInfo.is_dfs_cac_timer_running != VOS_TRUE)
sapStartDfsCacTimer(sapContext);
vosStatus = sap_CacStartNotify(hHal);
}
else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND)
{
v_U8_t intf;
/* Radar found while performing channel availability
* check, need to switch the channel again
*/
eCsrPhyMode phyMode = sapContext->csrRoamProfile.phyMode;
tHalHandle hHal =
(tHalHandle)vos_get_context(VOS_MODULE_ID_SME, sapContext->pvosGCtx);
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n");
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, NULL hHal in state %s, msg %d",
__func__, "eSAP_DFS_CAC_WAIT", msg);
}
else if (pMac->sap.SapDfsInfo.target_channel)
{
sme_SelectCBMode(hHal, phyMode,
pMac->sap.SapDfsInfo.target_channel,
0, &sapContext->vht_channel_width,
sapContext->ch_width_orig);
}
for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++)
{
ptSapContext sapContext;
sapContext = pMac->sap.sapCtxList [intf].pSapContext;
if (((VOS_STA_SAP_MODE ==
pMac->sap.sapCtxList[intf].sapPersona) ||
(VOS_P2P_GO_MODE ==
pMac->sap.sapCtxList[intf].sapPersona)) &&
sapContext != NULL &&
sapContext->sapsMachine != eSAP_DISCONNECTED)
{
/* SAP to be moved to DISCONNECTING state */
sapContext->sapsMachine = eSAP_DISCONNECTING;
/*
* eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
* A Radar is found on current DFS Channel
* while in CAC WAIT period So, do a channel switch
* to randomly selected target channel.
* Send the Channel change message to SME/PE.
* sap_radar_found_status is set to 1
*/
sapSignalHDDevent(sapContext, NULL,
eSAP_DFS_RADAR_DETECT,
(v_PVOID_t) eSAP_STATUS_SUCCESS);
WLANSAP_ChannelChangeRequest((v_PVOID_t)sapContext,
pMac->sap.SapDfsInfo.target_channel);
}
}
}
else if (msg == eSAP_DFS_CHANNEL_CAC_END)
{
vosStatus = sap_CacEndNotify(hHal, roamInfo);
}
else if (msg == eSAP_HDD_STOP_INFRA_BSS)
{
/* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, from state %s => %s",
__func__,
"eSAP_DFS_CAC_WAIT",
"eSAP_DISCONNECTING");
/*
* Stop the CAC timer only in following conditions
* single AP: if there is a single AP then stop the timer
* mulitple APs: incase of multiple APs, make sure that
* all APs are down.
*/
if (NULL == sap_find_valid_concurrent_session(hHal))
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: no sessions are valid, stopping timer");
sapStopDfsCacTimer(sapContext);
}
sapContext->sapsMachine = eSAP_DISCONNECTING;
vosStatus = sapGotoDisconnecting(sapContext);
}
else
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, in state %s, invalid event msg %d",
__func__, "eSAP_DFS_CAC_WAIT", msg);
}
break;
case eSAP_STARTING:
if (msg == eSAP_MAC_START_BSS_SUCCESS )
{
/* Transition from eSAP_STARTING to eSAP_STARTED (both without substates) */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state channel = %d %s => %s",
__func__,sapContext->channel, "eSAP_STARTING", "eSAP_STARTED");
sapContext->sapsMachine = eSAP_STARTED;
/*Action code for transition */
vosStatus = sapSignalHDDevent( sapContext, roamInfo, eSAP_START_BSS_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS);
/* The upper layers have been informed that AP is up and
* running, however, the AP is still not beaconing, until
* CAC is done if the operating channel is DFS
*/
if (NV_CHANNEL_DFS ==
vos_nv_getChannelEnabledState(sapContext->channel)
)
{
if ((VOS_FALSE == pMac->sap.SapDfsInfo.ignore_cac) &&
(eSAP_DFS_DO_NOT_SKIP_CAC ==
pMac->sap.SapDfsInfo.cac_state))
{
/* Move the device in CAC_WAIT_STATE */
sapContext->sapsMachine = eSAP_DFS_CAC_WAIT;
/* TODO: Need to stop the OS transmit queues,
* so that no traffic can flow down the stack
*/
/* Start CAC wait timer */
if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running !=
TRUE)
sapStartDfsCacTimer(sapContext);
vosStatus = sap_CacStartNotify(hHal);
}
else
{
WLANSAP_StartBeaconReq((v_PVOID_t)sapContext);
}
}
}
else if (msg == eSAP_HDD_STOP_INFRA_BSS)
{
/* Transition from eSAP_STARTING to eSAP_DISCONNECTPENDING */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s",
__func__, "eSAP_STARTING", "eSAP_DISCONNECTPENDING");
sapContext->sapsMachine = eSAP_DISCONNECTPENDING;
}
else if (msg == eSAP_MAC_START_FAILS)
{
/*Transition from eSAP_STARTING to eSAP_DISCONNECTED (both without substates)*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, from state %s => %s", __func__,
"eSAP_STARTING", "eSAP_DISCONNECTED");
/*Advance outer statevar */
sapContext->sapsMachine = eSAP_DISCONNECTED;
vosStatus = sapSignalHDDevent(sapContext, NULL,
eSAP_START_BSS_EVENT,
(v_PVOID_t)eSAP_STATUS_FAILURE);
vosStatus = sapGotoDisconnected(sapContext);
/* Close the SME session*/
if (eSAP_TRUE == sapContext->isSapSessionOpen)
{
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, NULL hHal in state %s, msg %d",
__func__, "eSAP_STARTING", msg);
}
else if (eHAL_STATUS_SUCCESS ==
sap_CloseSession(hHal,
sapContext, NULL, FALSE))
{
sapContext->isSapSessionOpen = eSAP_FALSE;
}
}
}
else if (msg == eSAP_OPERATING_CHANNEL_CHANGED)
{
/* The operating channel has changed, update hostapd */
sapContext->channel =
(tANI_U8)pMac->sap.SapDfsInfo.target_channel;
sapContext->sapsMachine = eSAP_STARTED;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, from state %s => %s",
__func__, "eSAP_STARTING", "eSAP_STARTED");
/* Indicate change in the state to upper layers */
vosStatus = sapSignalHDDevent(sapContext, roamInfo,
eSAP_START_BSS_EVENT,
(v_PVOID_t)eSAP_STATUS_SUCCESS);
}
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, in state %s, invalid event msg %d",
__func__, "eSAP_STARTING", msg);
/* Intentionally left blank */
}
break;
case eSAP_DISCONNECTPENDING:
/* eSAP_DISCONNECTPENDING is state for handling SAP Disconnection
* when DUT is in eSAP_STARTING state. Should not used for OTHER
* purpose.
*/
if (msg == eSAP_MAC_START_BSS_SUCCESS) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, from state %s => %s", __func__,
"eSAP_DISCONNECTPENDING", "eSAP_DISCONNECTING");
sapContext->sapsMachine = eSAP_DISCONNECTING;
vosStatus = sapSignalHDDevent(sapContext, NULL,
eSAP_START_BSS_EVENT,
(v_PVOID_t)eSAP_STATUS_FAILURE);
vosStatus = sapGotoDisconnecting(sapContext);
} else if (msg == eSAP_MAC_START_FAILS) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, from state %s => %s", __func__,
"eSAP_DISCONNECTPENDING", "eSAP_DISCONNECTED");
sapContext->sapsMachine = eSAP_DISCONNECTED;
vosStatus = sapSignalHDDevent(sapContext, NULL,
eSAP_START_BSS_EVENT,
(v_PVOID_t)eSAP_STATUS_FAILURE);
vosStatus = sapGotoDisconnected(sapContext);
if (eSAP_TRUE == sapContext->isSapSessionOpen)
{
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, NULL hHal in state %s, msg %d",
__func__, "eSAP_DISCONNECTPENDING", msg);
}
else if (eHAL_STATUS_SUCCESS ==
sap_CloseSession(hHal, sapContext, NULL, FALSE))
{
sapContext->isSapSessionOpen = eSAP_FALSE;
}
}
} else {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, in state %s, invalid event msg %d",
__func__, "eSAP_DISCONNECTPENDING", msg);
}
break;
case eSAP_STARTED:
if (msg == eSAP_HDD_STOP_INFRA_BSS)
{
/* Transition from eSAP_STARTED to eSAP_DISCONNECTING (both without substates) */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s",
__func__, "eSAP_STARTED", "eSAP_DISCONNECTING");
sapContext->sapsMachine = eSAP_DISCONNECTING;
vosStatus = sapGotoDisconnecting(sapContext);
}
else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg)
{
v_U8_t intf;
/* Radar is seen on the current operating channel
* send CSA IE for all associated stations
*/
if (pMac != NULL)
{
/* Request for CSA IE transmission */
for ( intf = 0; intf < SAP_MAX_NUM_SESSION; intf++)
{
ptSapContext pSapContext;
if (((VOS_STA_SAP_MODE ==
pMac->sap.sapCtxList [intf].sapPersona) ||
(VOS_P2P_GO_MODE ==
pMac->sap.sapCtxList [intf].sapPersona)) &&
pMac->sap.sapCtxList [intf].pSapContext != NULL )
{
pSapContext = pMac->sap.sapCtxList [intf].pSapContext;
VOS_TRACE(VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: Sending CSAIE for sapctx[%pK]",
pSapContext);
vosStatus =
WLANSAP_DfsSendCSAIeRequest((v_PVOID_t)pSapContext);
}
}
}
} else if (eSAP_MAC_SCAN_COMPLETE == msg) {
if (!sapContext->acs_cfg->acs_mode) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, not a in ACS mode", __func__);
return VOS_STATUS_E_INVAL;
}
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, ACS scan complete in state %s",
__func__,
"eSAP_STARTED");
if (!roamInfo) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, roam info can't be NULL",
__func__);
return VOS_STATUS_E_INVAL;
}
vosStatus = sap_relaunch_acs_result_handler(sapContext,
roamInfo);
}
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, invalid event msg %d",
__func__, "eSAP_STARTED", msg);
}
break;
case eSAP_DISCONNECTING:
if (msg == eSAP_MAC_READY_FOR_CONNECTIONS)
{
/* Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED (both without substates) */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s",
__func__, "eSAP_DISCONNECTING", "eSAP_DISCONNECTED");
sapContext->sapsMachine = eSAP_DISCONNECTED;
/* Close the SME session*/
if (eSAP_TRUE == sapContext->isSapSessionOpen)
{
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, NULL hHal in state %s, msg %d",
__func__, "eSAP_DISCONNECTING", msg);
}
else
{
sapContext->isSapSessionOpen = eSAP_FALSE;
if (!(eHAL_STATUS_SUCCESS ==
sap_CloseSession(hHal,
sapContext,
sapRoamSessionCloseCallback, TRUE)))
{
vosStatus = sapSignalHDDevent(sapContext, NULL,
eSAP_STOP_BSS_EVENT,
(v_PVOID_t) eSAP_STATUS_SUCCESS);
}
}
}
}
else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: Send channel change request on sapctx[%pK]",
sapContext);
/* Most likely, radar has been detected and SAP wants to
* change the channel
*/
vosStatus = WLANSAP_ChannelChangeRequest((v_PVOID_t)sapContext,
pMac->sap.SapDfsInfo.target_channel);
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"In %s, Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ",
__func__);
}
else if (msg == eWNI_SME_CHANNEL_CHANGE_RSP)
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"In %s, in state %s, event msg %d result %d",
__func__, "eSAP_DISCONNECTING ", msg, sapEvent->u2);
if (sapEvent->u2 == eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE)
{
vosStatus = sapGotoDisconnecting(sapContext);
}
}
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s, in state %s, invalid event msg %d",
__func__, "eSAP_DISCONNECTING", msg);
}
break;
}
return vosStatus;
}// sapFsm
eSapStatus
sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, tCsrRoamProfile *profile)
{
//Create Roam profile for SoftAP to connect
profile->BSSType = eCSR_BSS_TYPE_INFRA_AP;
profile->SSIDs.numOfSSIDs = 1;
profile->csrPersona = pconfig_params->persona;
profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch;
vos_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId,
sizeof(profile->SSIDs.SSIDList[0].SSID.ssId));
//Flag to not broadcast the SSID information
profile->SSIDs.SSIDList[0].ssidHidden = pconfig_params->SSIDinfo.ssidHidden;
profile->SSIDs.SSIDList[0].SSID.length = pconfig_params->SSIDinfo.ssid.length;
vos_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId, pconfig_params->SSIDinfo.ssid.ssId,
sizeof(pconfig_params->SSIDinfo.ssid.ssId));
profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
if (pconfig_params->authType == eSAP_OPEN_SYSTEM)
{
profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
}
else if (pconfig_params->authType == eSAP_SHARED_KEY)
{
profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY;
}
else
{
profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH;
}
profile->AuthType.numEntries = 1;
profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
//Always set the Encryption Type
profile->EncryptionType.numEntries = 1;
profile->EncryptionType.encryptionType[0] = pconfig_params->RSNEncryptType;
profile->mcEncryptionType.numEntries = 1;
profile->mcEncryptionType.encryptionType[0] = pconfig_params->mcRSNEncryptType;
if (pconfig_params->privacy & eSAP_SHARED_KEY)
{
profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
}
profile->privacy = pconfig_params->privacy;
profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq;
if (pconfig_params->authType == eSAP_SHARED_KEY)
{
profile->csr80211AuthType = eSIR_SHARED_KEY;
}
else if (pconfig_params->authType == eSAP_OPEN_SYSTEM)
{
profile->csr80211AuthType = eSIR_OPEN_SYSTEM;
}
else
{
profile->csr80211AuthType = eSIR_AUTO_SWITCH;
}
//Initialize we are not going to use it
profile->pWPAReqIE = NULL;
profile->nWPAReqIELength = 0;
//set the RSN/WPA IE
profile->pRSNReqIE = NULL;
profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
if (pconfig_params->RSNWPAReqIELength)
{
profile->pRSNReqIE = vos_mem_malloc(pconfig_params->RSNWPAReqIELength);
if( NULL == profile->pRSNReqIE )
{
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, " %s Fail to alloc memory", __func__);
return eSAP_STATUS_FAILURE;
}
vos_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE,
pconfig_params->RSNWPAReqIELength);
profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
}
// Turn off CB mode
profile->CBMode = eCSR_CB_OFF;
//set the phyMode to accept anything
//Best means everything because it covers all the things we support
/*eCSR_DOT11_MODE_BEST*/
profile->phyMode = pconfig_params->SapHw_mode;
//Configure beaconInterval
profile->beaconInterval = (tANI_U16)pconfig_params->beacon_int;
// set DTIM period
profile->dtimPeriod = pconfig_params->dtim_period;
//set Uapsd enable bit
profile->ApUapsdEnable = pconfig_params->UapsdEnable;
//Enable protection parameters
profile->protEnabled = pconfig_params->protEnabled;
profile->obssProtEnabled = pconfig_params->obssProtEnabled;
profile->cfg_protection = pconfig_params->ht_capab;
//country code
if (pconfig_params->countryCode[0])
vos_mem_copy(profile->countryCode, pconfig_params->countryCode, WNI_CFG_COUNTRY_CODE_LEN);
profile->ieee80211d = pconfig_params->ieee80211d;
//wps config info
profile->wps_state = pconfig_params->wps_state;
#ifdef WLAN_FEATURE_11W
// MFP capable/required
profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0;
profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0;
#endif
if (pconfig_params->probeRespIEsBufferLen > 0 &&
pconfig_params->pProbeRespIEsBuffer != NULL)
{
profile->addIeParams.probeRespDataLen =
pconfig_params->probeRespIEsBufferLen;
profile->addIeParams.probeRespData_buff =
pconfig_params->pProbeRespIEsBuffer;
}
else
{
profile->addIeParams.probeRespDataLen = 0;
profile->addIeParams.probeRespData_buff = NULL;
}
/*assoc resp IE */
if (pconfig_params->assocRespIEsLen > 0 &&
pconfig_params->pAssocRespIEsBuffer != NULL)
{
profile->addIeParams.assocRespDataLen =
pconfig_params->assocRespIEsLen;
profile->addIeParams.assocRespData_buff =
pconfig_params->pAssocRespIEsBuffer;
}
else
{
profile->addIeParams.assocRespDataLen = 0;
profile->addIeParams.assocRespData_buff = NULL;
}
if (pconfig_params->probeRespBcnIEsLen > 0 &&
pconfig_params->pProbeRespBcnIEsBuffer!= NULL)
{
profile->addIeParams.probeRespBCNDataLen =
pconfig_params->probeRespBcnIEsLen;
profile->addIeParams.probeRespBCNData_buff =
pconfig_params->pProbeRespBcnIEsBuffer;
}
else
{
profile->addIeParams.probeRespBCNDataLen = 0;
profile->addIeParams.probeRespBCNData_buff = NULL;
}
profile->sap_dot11mc = pconfig_params->sap_dot11mc;
if (pconfig_params->supported_rates.numRates) {
vos_mem_copy(profile->supported_rates.rate,
pconfig_params->supported_rates.rate,
pconfig_params->supported_rates.numRates);
profile->supported_rates.numRates =
pconfig_params->supported_rates.numRates;
}
if (pconfig_params->extended_rates.numRates) {
vos_mem_copy(profile->extended_rates.rate,
pconfig_params->extended_rates.rate,
pconfig_params->extended_rates.numRates);
profile->extended_rates.numRates =
pconfig_params->extended_rates.numRates;
}
return eSAP_STATUS_SUCCESS; /* Success. */
}
void sapFreeRoamProfile(tCsrRoamProfile *profile)
{
if(profile->pRSNReqIE)
{
vos_mem_free(profile->pRSNReqIE);
profile->pRSNReqIE = NULL;
}
}
void
sapSortMacList(v_MACADDR_t *macList, v_U8_t size)
{
v_U8_t outer, inner;
v_MACADDR_t temp;
v_SINT_t nRes = -1;
if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("either buffer is NULL or size = %d is more."), size);
return;
}
for(outer = 0; outer < size; outer++)
{
for(inner = 0; inner < size - 1; inner++)
{
nRes = vos_mem_compare2((macList + inner)->bytes, (macList + inner + 1)->bytes, sizeof(v_MACADDR_t));
if (nRes > 0)
{
vos_mem_copy(temp.bytes, (macList + inner + 1)->bytes, sizeof(v_MACADDR_t));
vos_mem_copy((macList + inner + 1)->bytes, (macList + inner)->bytes, sizeof(v_MACADDR_t));
vos_mem_copy((macList + inner)->bytes, temp.bytes, sizeof(v_MACADDR_t));
}
}
}
}
eSapBool
sapSearchMacList(v_MACADDR_t *macList, v_U8_t num_mac, v_U8_t *peerMac, v_U8_t *index)
{
v_SINT_t nRes = -1;
v_S7_t nStart = 0, nEnd, nMiddle;
nEnd = num_mac - 1;
if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("either buffer is NULL or size = %d is more."),
num_mac);
return eSAP_FALSE;
}
while (nStart <= nEnd)
{
nMiddle = (nStart + nEnd) / 2;
nRes = vos_mem_compare2(&macList[nMiddle], peerMac, sizeof(v_MACADDR_t));
if (0 == nRes)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"search SUCC");
// "index equals NULL" means the caller does not need the
// index value of the peerMac being searched
if (index != NULL)
{
*index = (v_U8_t) nMiddle;
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"index %d", *index);
}
return eSAP_TRUE;
}
if (nRes < 0)
nStart = nMiddle + 1;
else
nEnd = nMiddle - 1;
}
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"search not succ");
return eSAP_FALSE;
}
void
sapAddMacToACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t *peerMac)
{
v_SINT_t nRes = -1;
int i;
if ((NULL == macList) || (*size > MAX_ACL_MAC_ADDRESS)) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("either buffer is NULL or size = %d is incorrect."),
*size);
return;
}
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"add acl entered");
for (i=((*size)-1); i>=0; i--)
{
nRes = vos_mem_compare2(&macList[i], peerMac, sizeof(v_MACADDR_t));
if (nRes > 0)
{
/* Move alphabetically greater mac addresses one index down to allow for insertion
of new mac in sorted order */
vos_mem_copy((macList+i+1)->bytes,(macList+i)->bytes, sizeof(v_MACADDR_t));
}
else
{
break;
}
}
//This should also take care of if the element is the first to be added in the list
vos_mem_copy((macList+i+1)->bytes, peerMac, sizeof(v_MACADDR_t));
// increment the list size
(*size)++;
}
void
sapRemoveMacFromACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t index)
{
int i;
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"remove acl entered");
/* return if the list passed is empty. Ideally this should never happen since this funcn is always
called after sapSearchMacList to get the index of the mac addr to be removed and this will
only get called if the search is successful. Still no harm in having the check */
if ((NULL == macList) || (*size == 0) || (*size > MAX_ACL_MAC_ADDRESS)) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
FL("either buffer is NULL or size = %d is incorrect"),
*size);
return;
}
for (i=index; i<((*size)-1); i++)
{
/* Move mac addresses starting from "index" passed one index up to delete the void
created by deletion of a mac address in ACL */
vos_mem_copy((macList+i)->bytes,(macList+i+1)->bytes, sizeof(v_MACADDR_t));
}
// The last space should be made empty since all mac addesses moved one step up
vos_mem_zero((macList+(*size)-1)->bytes, sizeof(v_MACADDR_t));
//reduce the list size by 1
(*size)--;
}
void sapPrintACL(v_MACADDR_t *macList, v_U8_t size)
{
int i;
v_BYTE_t *macArray;
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"print acl entered");
if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS))
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, either buffer is NULL or size %d is incorrect."
, __func__, size);
return;
}
for (i=0; i<size; i++)
{
macArray = (macList+i)->bytes;
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"** ACL entry %i - "MAC_ADDRESS_STR, i,
MAC_ADDR_ARRAY(macArray));
}
return;
}
VOS_STATUS
sapIsPeerMacAllowed(ptSapContext sapContext, v_U8_t *peerMac)
{
if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode)
return VOS_STATUS_SUCCESS;
if (sapSearchMacList(sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL))
return VOS_STATUS_SUCCESS;
if (sapSearchMacList(sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL))
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, Peer "MAC_ADDRESS_STR" in deny list",
__func__, MAC_ADDR_ARRAY(peerMac));
return VOS_STATUS_E_FAILURE;
}
// A new station CAN associate, unless in deny list. Less stringent mode
if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode)
return VOS_STATUS_SUCCESS;
// A new station CANNOT associate, unless in accept list. More stringent mode
if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, Peer "MAC_ADDRESS_STR" denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED",
__func__, MAC_ADDR_ARRAY(peerMac));
return VOS_STATUS_E_FAILURE;
}
/* The new STA is neither in accept list nor in deny list. In this case, deny the association
* but send a wifi event notification indicating the mac address being denied
*/
if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode)
{
sapSignalHDDevent(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN, (v_PVOID_t)peerMac);
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
"In %s, Peer "MAC_ADDRESS_STR" denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY",
__func__, MAC_ADDR_ARRAY(peerMac));
return VOS_STATUS_E_FAILURE;
}
return VOS_STATUS_SUCCESS;
}
#ifdef SOFTAP_CHANNEL_RANGE
static VOS_STATUS sapGetChannelList(ptSapContext sapContext,
v_U8_t **channelList, v_U8_t *numberOfChannels)
{
v_U8_t loopCount;
v_U8_t *list;
v_U8_t channelCount;
v_U8_t startChannelNum, bandStartChannel;
v_U8_t endChannelNum, bandEndChannel ;
v_U32_t enableLTECoex;
tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
#ifdef FEATURE_WLAN_CH_AVOID
v_U8_t i;
#endif
tpAniSirGlobal pmac = PMAC_STRUCT(hHal);
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"Invalid HAL pointer from pvosGCtx on sapGetChannelList");
*numberOfChannels = 0;
*channelList = NULL;
return VOS_STATUS_E_FAULT;
}
if ( eCSR_BAND_ALL == sapContext->scanBandPreference)
{
startChannelNum = sapContext->acs_cfg->start_ch;
endChannelNum = sapContext->acs_cfg->end_ch;
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s: startChannel %d, EndChannel %d, HW:%d",
__func__, startChannelNum, endChannelNum,
sapContext->acs_cfg->hw_mode);
WLANSAP_extend_to_acs_range(&startChannelNum, &endChannelNum,
&bandStartChannel, &bandEndChannel);
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
"%s: expanded startChannel %d,EndChannel %d",
__func__,startChannelNum,endChannelNum);
}
else
{
if ( sapContext->allBandScanned == eSAP_FALSE )
{
//first band scan
sapContext->currentPreferredBand = sapContext->scanBandPreference;
}
else
{
//scan next band
if ( eCSR_BAND_24 == sapContext->scanBandPreference )
sapContext->currentPreferredBand = eCSR_BAND_5G;
else
sapContext->currentPreferredBand = eCSR_BAND_24;
}
switch(sapContext->currentPreferredBand)
{
case eCSR_BAND_24:
bandStartChannel = RF_CHAN_1;
bandEndChannel = RF_CHAN_14;
startChannelNum = 1;
endChannelNum = 14;
break;
case eCSR_BAND_5G:
bandStartChannel = RF_CHAN_36;
bandEndChannel = RF_CHAN_165;
startChannelNum = 36;
endChannelNum = 165;
break;
default:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"sapGetChannelList:bandPreference not valid ");
/* assume 2.4 GHz */
bandStartChannel = RF_CHAN_1;
bandEndChannel = RF_CHAN_14;
startChannelNum = 1;
endChannelNum = 14;
break;
}
}
ccmCfgGetInt(hHal, WNI_CFG_ENABLE_LTE_COEX, &enableLTECoex);
/*Check if LTE coex is enabled and 2.4GHz is selected*/
if (enableLTECoex && (bandStartChannel == RF_CHAN_1)
&& (bandEndChannel == RF_CHAN_14))
{
/*Set 2.4GHz upper limit to channel 9 for LTE COEX*/
bandEndChannel = RF_CHAN_9;
}
/* Allocate the max number of channel supported */
list = (v_U8_t *)vos_mem_malloc(NUM_5GHZ_CHANNELS);
if (NULL == list)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"%s: Unable to allocate channel list", __func__);
*numberOfChannels = 0;
*channelList = NULL;
return VOS_STATUS_E_RESOURCES;
}
/*Search for the Active channels in the given range */
channelCount = 0;
for( loopCount = bandStartChannel; loopCount <= bandEndChannel; loopCount++ )
{
if((startChannelNum <= rfChannels[loopCount].channelNum)&&
(endChannelNum >= rfChannels[loopCount].channelNum ))
{
if (((TRUE == pmac->scan.fEnableDFSChnlScan) &&
(regChannels[loopCount].enabled)) ||
((FALSE == pmac->scan.fEnableDFSChnlScan) &&
(NV_CHANNEL_ENABLE == regChannels[loopCount].enabled)))
{
#ifdef FEATURE_WLAN_CH_AVOID
for( i = 0; i < NUM_20MHZ_RF_CHANNELS; i++ )
{
if( (safeChannels[i].channelNumber ==
rfChannels[loopCount].channelNum) )
{
/* Check if channel is safe */
if(VOS_TRUE == safeChannels[i].isSafe)
{
#endif
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
v_U8_t ch;
ch = rfChannels[loopCount].channelNum;
if ((sapContext->acs_cfg->skip_scan_status
== eSAP_DO_PAR_ACS_SCAN)) {
if ((ch >= sapContext->acs_cfg->skip_scan_range1_stch &&
ch <= sapContext->acs_cfg->skip_scan_range1_endch) ||
(ch >= sapContext->acs_cfg->skip_scan_range2_stch &&
ch <= sapContext->acs_cfg->skip_scan_range2_endch)) {
list[channelCount] =
rfChannels[loopCount].channelNum;
channelCount++;
VOS_TRACE( VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_INFO,
"%s:%d %d added to ACS ch range",
__func__, channelCount, ch);
} else
VOS_TRACE( VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_INFO_HIGH,
"%s:%d %d skipped from ACS ch range",
__func__, channelCount, ch);
} else {
list[channelCount] =
rfChannels[loopCount].channelNum;
channelCount++;
VOS_TRACE( VOS_MODULE_ID_SAP,
VOS_TRACE_LEVEL_INFO,
"%s:%d %d added to ACS ch range",
__func__, channelCount, ch);
}
#else
list[channelCount] =
rfChannels[loopCount].channelNum;
channelCount++;
#endif
#ifdef FEATURE_WLAN_CH_AVOID
}
break;
}
}
#endif
}
}
}
if (0 == channelCount)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"sapGetChannelList:No active channels present in the given range for the current region");
/*LTE COEX: channel range outside the restricted 2.4GHz band limits*/
if (enableLTECoex && (startChannelNum > bandEndChannel))
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
"sapGetChannelList:SAP cannot be started as LTE COEX restricted 2.4GHz limits");
}
}
/* return the channel list and number of channels to scan*/
*numberOfChannels = channelCount;
if(channelCount != 0)
{
*channelList = list;
}
else
{
*channelList = NULL;
vos_mem_free(list);
}
for (loopCount = 0; loopCount <channelCount; loopCount ++ )
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG,
"%s: channel number: %d",
__func__,list[loopCount]);
}
return VOS_STATUS_SUCCESS;
}
#endif
/*
* Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS]
* available channels in the current regulatory domain.
*/
static VOS_STATUS sapGet5GHzChannelList(ptSapContext sapContext)
{
v_U8_t count = 0;
int i;
if (NULL == sapContext)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"Invalid sapContext pointer on sapGetChannelList");
return VOS_STATUS_E_FAULT;
}
if (sapContext->SapAllChnlList.channelList) {
vos_mem_free(sapContext->SapAllChnlList.channelList);
sapContext->SapAllChnlList.channelList = NULL;
}
sapContext->SapAllChnlList.channelList =
(tChannelInfo *)vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN *
sizeof(tChannelInfo));
if (NULL == sapContext->SapAllChnlList.channelList)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
" Memory Allocation failed sapGetChannelList");
return VOS_STATUS_E_FAULT;
}
for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
{
if( regChannels[i].enabled == NV_CHANNEL_ENABLE ||
regChannels[i].enabled == NV_CHANNEL_DFS )
{
sapContext->SapAllChnlList.channelList[count].channel =
rfChannels[i].channelNum;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
"%s[%d] CHANNEL = %d",__func__, __LINE__,
sapContext->SapAllChnlList.channelList[count].channel);
sapContext->SapAllChnlList.channelList[count].valid = VOS_TRUE;
count++;
}
}
sapContext->SapAllChnlList.numChannel = count;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
"%s[%d] NUMBER OF CHANNELS count = %d"
"sapContext->SapAllChnlList.numChannel = %d",
__func__,__LINE__,count,sapContext->SapAllChnlList.numChannel);
return VOS_STATUS_SUCCESS;
}
/*
* This function randomly selects the channel to switch after the detection
* of radar
* param sapContext - sap context
* dfs_event - Dfs information from DFS
* return - channel to which AP wishes to switch
*/
v_U8_t sapIndicateRadar(ptSapContext sapContext, tSirSmeDfsEventInd *dfs_event)
{
v_U8_t target_channel = 0;
tHalHandle hHal;
tpAniSirGlobal pMac;
if (NULL == sapContext || NULL == dfs_event)
{
/* Invalid sap context of dfs event passed */
return 0;
}
hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s invalid hHal", __func__);
return 0;
}
pMac = PMAC_STRUCT( hHal );
if (!dfs_event->dfs_radar_status)
{
/*dfs status does not indicate a radar on the channel-- False Alarm*/
return 0;
}
/*
* SAP needs to generate Channel Switch IE
* if the radar is found in the STARTED state
*/
if (eSAP_STARTED == sapContext->sapsMachine)
pMac->sap.SapDfsInfo.csaIERequired = VOS_TRUE;
if (sapContext->csrRoamProfile.disableDFSChSwitch)
{
return sapContext->channel;
}
/* set the Radar Found flag in SapDfsInfo */
pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_TRUE;
sapGet5GHzChannelList(sapContext);
if (dfs_event->chan_list.nchannels > SIR_DFS_MAX_20M_SUB_CH) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
FL("nchannels >SIR_DFS_MAX_20M_SUB_CH so resetting"));
dfs_event->chan_list.nchannels = SIR_DFS_MAX_20M_SUB_CH;
}
sapMarkDfsChannels(sapContext, dfs_event->chan_list.channels,
dfs_event->chan_list.nchannels, vos_get_monotonic_boottime());
/*
* (1) skip static turbo channel as it will require STA to be in
* static turbo to work.
* (2) skip channel which's marked with radar detction
* (3) WAR: we allow user to config not to use any DFS channel
* (4) When we pick a channel, skip excluded 11D channels
* (5) Create the available channel list with the above rules
*/
target_channel = sapRandomChannelSel(sapContext);
if (0 == target_channel)
{
sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NO_AVAILABLE_CHANNEL,
(v_PVOID_t) eSAP_STATUS_SUCCESS);
}
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
FL("sapdfs: New selected target channel is [%d]"),
target_channel);
return target_channel;
}
/*
* CAC timer callback function.
* Post eSAP_DFS_CHANNEL_CAC_END event to sapFsm().
*/
void sapDfsCacTimerCallback(void *data)
{
ptSapContext sapContext;
tWLAN_SAPEvent sapEvent;
tHalHandle hHal = (tHalHandle)data;
tpAniSirGlobal pMac;
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s invalid hHal", __func__);
return;
}
pMac = PMAC_STRUCT( hHal );
sapContext = sap_find_valid_concurrent_session(hHal);
if (NULL == sapContext)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s no SAP contexts are found", __func__);
return;
}
/*
* SAP may not be in CAC wait state, when the timer runs out.
* if following flag is set, then timer is in initialized state,
* destroy timer here.
*/
if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) {
vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
}
/* Check to ensure that SAP is in DFS WAIT state*/
if (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)
{
/*
* CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sapFsm
*/
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%pK]",
sapContext->channel, sapContext);
sapEvent.event = eSAP_DFS_CHANNEL_CAC_END;
sapEvent.params = 0;
sapEvent.u1 = 0;
sapEvent.u2 = 0;
sapFsm(sapContext, &sapEvent);
}
}
/*
* Function to stop the DFS CAC Timer
*/
static int sapStopDfsCacTimer(ptSapContext sapContext)
{
tHalHandle hHal;
tpAniSirGlobal pMac;
if (sapContext == NULL)
return 0;
hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s invalid hHal", __func__);
return 0;
}
pMac = PMAC_STRUCT(hHal);
if (VOS_TIMER_STATE_RUNNING !=
vos_timer_getCurrentState(
&pMac->sap.SapDfsInfo.sap_dfs_cac_timer)) {
return 0;
}
vos_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
return 0;
}
/**
* sap_is_channel_bonding_etsi_weather_channel() - Routine to check if
* sap channel is bonded to
* weather radar channel.
* @sap_context: SAP context
*
* Check if the current SAP operating channel is bonded to weather radar
* channel in ETSI domain.
*
* Return: True if bonded to weather channel in ETSI
*/
static bool
sap_is_channel_bonding_etsi_weather_channel(ptSapContext sap_context)
{
if(IS_CH_BONDING_WITH_WEATHER_CH(sap_context->channel) &&
(sap_context->vht_channel_width != eHT_CHANNEL_WIDTH_20MHZ)) {
return true;
}
return false;
}
/*
* Function to start the DFS CAC Timer
* when SAP is started on a DFS channel
*/
int sapStartDfsCacTimer(ptSapContext sapContext)
{
VOS_STATUS status;
v_U32_t cacTimeOut;
tHalHandle hHal = NULL;
tpAniSirGlobal pMac = NULL;
uint8_t dfs_region;
if (sapContext == NULL)
{
return 0;
}
hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s invalid hHal", __func__);
return 0;
}
pMac = PMAC_STRUCT( hHal );
if (pMac->sap.SapDfsInfo.ignore_cac)
{
/*
* If User has set to ignore the CAC
* so, continue without CAC Timer.
*/
return 2;
}
cacTimeOut = DEFAULT_CAC_TIMEOUT;
vos_nv_get_dfs_region(&dfs_region);
if ((dfs_region == DFS_ETSI_DOMAIN) &&
((IS_ETSI_WEATHER_CH(sapContext->channel)) ||
(sap_is_channel_bonding_etsi_weather_channel(sapContext))))
{
cacTimeOut = ETSI_WEATHER_CH_CAC_TIMEOUT;
}
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
"sapdfs: SAP_DFS_CHANNEL_CAC_START on CH - %d, CAC TIMEOUT - %d sec",
sapContext->channel, cacTimeOut/1000);
vos_timer_init(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer,
VOS_TIMER_TYPE_SW,
sapDfsCacTimerCallback, (v_PVOID_t)hHal);
/*Start the CAC timer*/
status = vos_timer_start(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer, cacTimeOut);
if (status == VOS_STATUS_SUCCESS)
{
pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
return 1;
}
else
{
pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
return 0;
}
}
/*
* This function initializes the NOL list
* parameters required to track the radar
* found DFS channels in the current Reg. Domain .
*/
VOS_STATUS sapInitDfsChannelNolList(ptSapContext sapContext)
{
v_U8_t count = 0;
int i;
v_BOOL_t bFound = FALSE;
tHalHandle hHal;
tpAniSirGlobal pMac;
if (NULL == sapContext)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"Invalid sapContext pointer on sapInitDfsChannelNolList");
return VOS_STATUS_E_FAULT;
}
hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
"In %s invalid hHal", __func__);
return VOS_STATUS_E_FAULT;
}
pMac = PMAC_STRUCT( hHal );
/* to indicate hdd to get cnss dfs nol */
if (VOS_STATUS_SUCCESS == sapSignalHDDevent(sapContext, NULL,
eSAP_DFS_NOL_GET,
(v_PVOID_t) eSAP_STATUS_SUCCESS))
{
bFound = TRUE;
}
for ( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
{
if ( regChannels[i].enabled == NV_CHANNEL_DFS )
{
/* if dfs nol is not found, initialize it */
if (!bFound)
{
pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
.dfs_channel_number = rfChannels[i].channelNum;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
"%s: CHANNEL = %d", __func__,
pMac->sap.SapDfsInfo
.sapDfsChannelNolList[count].dfs_channel_number);
pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
.radar_status_flag = eSAP_DFS_CHANNEL_USABLE;
pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
.radar_found_timestamp = 0;
}
count++;
}
}
pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels = count;
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
"%s[%d] NUMBER OF DFS CHANNELS = %d",
__func__, __LINE__,
pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels);
return VOS_STATUS_SUCCESS;
}
/*
* This function will calculate how many interfaces
* have sap persona and returns total number of sap persona.
*/
v_U8_t sap_get_total_number_sap_intf(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
v_U8_t intf = 0;
v_U8_t intf_count = 0;
for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
if (((VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona) ||
(VOS_P2P_GO_MODE == pMac->sap.sapCtxList [intf].sapPersona)) &&
pMac->sap.sapCtxList[intf].pSapContext != NULL) {
intf_count++;
}
}
return intf_count;
}
/*
* This function will find the concurrent sap context apart from
* passed sap context and return its channel change ready status
*/
tANI_BOOLEAN is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
ptSapContext sapContext)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
ptSapContext pSapContext;
v_U8_t intf = 0;
tANI_BOOLEAN is_ready_for_chng = VOS_TRUE;
for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
if (((VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona) ||
(VOS_P2P_GO_MODE == pMac->sap.sapCtxList [intf].sapPersona)) &&
pMac->sap.sapCtxList[intf].pSapContext != NULL) {
pSapContext =
(ptSapContext)pMac->sap.sapCtxList [intf].pSapContext;
if (pSapContext == sapContext) {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("sapCtx matched [%pK]"), sapContext);
continue;
} else {
VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
FL("concurrent sapCtx[%pK] didn't matche with [%pK]"),
pSapContext, sapContext);
is_ready_for_chng = is_ready_for_chng &&
pSapContext->is_sap_ready_for_chnl_chng;
}
}
}
return is_ready_for_chng;
}