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);