diff options
| -rw-r--r-- | core/cds/inc/cds_reg_service.h | 10 | ||||
| -rw-r--r-- | core/cds/src/cds_reg_service.c | 8 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_cfg.h | 25 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg.c | 14 | ||||
| -rw-r--r-- | core/mac/inc/ani_global.h | 1 | ||||
| -rw-r--r-- | core/mac/inc/sir_api.h | 23 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_scan_result_utils.c | 21 | ||||
| -rw-r--r-- | core/sme/inc/csr_api.h | 1 | ||||
| -rw-r--r-- | core/sme/inc/csr_internal.h | 1 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_api_roam.c | 37 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_api_scan.c | 652 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_inside_api.h | 39 |
12 files changed, 525 insertions, 307 deletions
diff --git a/core/cds/inc/cds_reg_service.h b/core/cds/inc/cds_reg_service.h index 5549493b414b..137e8512d980 100644 --- a/core/cds/inc/cds_reg_service.h +++ b/core/cds/inc/cds_reg_service.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -407,5 +407,11 @@ QDF_STATUS cds_set_reg_domain(void *client_ctxt, v_REGDOMAIN_t reg_domain); QDF_STATUS cds_put_default_country(uint8_t *def_country); uint16_t cds_bw_value(enum phy_ch_width bw); uint8_t cds_skip_dfs_and_2g(uint32_t rf_channel); - +/** + * cds_get_channel_enum() - get the channel enumeration + * @chan_num: channel number + * + * Return: enum for the channel + */ +enum channel_enum cds_get_channel_enum(uint32_t chan_num); #endif /* __CDS_REG_SERVICE_H */ diff --git a/core/cds/src/cds_reg_service.c b/core/cds/src/cds_reg_service.c index ac483b80e500..5b7f715b4086 100644 --- a/core/cds/src/cds_reg_service.c +++ b/core/cds/src/cds_reg_service.c @@ -204,13 +204,7 @@ QDF_STATUS cds_read_default_country(uint8_t *def_ctry) return QDF_STATUS_SUCCESS; } -/** - * cds_get_channel_enum() - get the channel enumeration - * @chan_num: channel number - * - * Return: enum for the channel - */ -static enum channel_enum cds_get_channel_enum(uint32_t chan_num) +enum channel_enum cds_get_channel_enum(uint32_t chan_num) { uint32_t loop; diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index ad84660aec37..93dae4de22df 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -10610,10 +10610,34 @@ enum dot11p_mode { #define CFG_SAP_MAX_MCS_FOR_TX_DATA_MAX (383) #define CFG_SAP_MAX_MCS_FOR_TX_DATA_DEFAULT (0) +/* + * g_is_bssid_hint_priority - Set priority for connection with bssid_hint + * BSSID. + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to give priority to BSS for connection which comes + * as part of bssid_hint + * + * Related: None + * + * Supported Feature: STA + * + * Usage: External + * + * </ini> + */ +#define CFG_IS_BSSID_HINT_PRIORITY_NAME "g_is_bssid_hint_priority" +#define CFG_IS_BSSID_HINT_PRIORITY_DEFAULT (1) +#define CFG_IS_BSSID_HINT_PRIORITY_MIN (0) +#define CFG_IS_BSSID_HINT_PRIORITY_MAX (1) + /*--------------------------------------------------------------------------- Type declarations -------------------------------------------------------------------------*/ + struct hdd_config { /* Bitmap to track what is explicitly configured */ DECLARE_BITMAP(bExplicitCfg, MAX_CFG_INI_ITEMS); @@ -11371,6 +11395,7 @@ struct hdd_config { uint8_t enable_rts_sifsbursting; uint8_t max_mpdus_inampdu; uint16_t sap_max_mcs_txdata; + bool is_bssid_hint_priority; }; #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var)) diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 73ffca60dc8c..ab25107a958c 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -4549,6 +4549,13 @@ struct reg_table_entry g_registry_table[] = { CFG_SAP_MAX_MCS_FOR_TX_DATA_DEFAULT, CFG_SAP_MAX_MCS_FOR_TX_DATA_MIN, CFG_SAP_MAX_MCS_FOR_TX_DATA_MAX), + + REG_VARIABLE(CFG_IS_BSSID_HINT_PRIORITY_NAME, WLAN_PARAM_Integer, + struct hdd_config, is_bssid_hint_priority, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IS_BSSID_HINT_PRIORITY_DEFAULT, + CFG_IS_BSSID_HINT_PRIORITY_MIN, + CFG_IS_BSSID_HINT_PRIORITY_MAX), }; /** @@ -6075,6 +6082,10 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) hdd_info("Name = [%s] value = [%u]", CFG_DROPPED_PKT_DISCONNECT_TH_NAME, pHddCtx->config->pkt_err_disconn_th); + hdd_info("Name = [%s] Value = [%u]", + CFG_IS_BSSID_HINT_PRIORITY_NAME, + pHddCtx->config->is_bssid_hint_priority); + } /** @@ -7652,6 +7663,9 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx) pHddCtx->config->fils_max_chan_guard_time; smeConfig->csrConfig.pkt_err_disconn_th = pHddCtx->config->pkt_err_disconn_th; + smeConfig->csrConfig.is_bssid_hint_priority = + pHddCtx->config->is_bssid_hint_priority; + status = sme_update_config(pHddCtx->hHal, smeConfig); if (!QDF_IS_STATUS_SUCCESS(status)) hdd_err("sme_update_config() failure: %d", status); diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index 220d338564cc..99373cb96eb7 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -969,6 +969,7 @@ typedef struct sAniSirGlobal { bool sta_prefer_80MHz_over_160MHz; enum country_src reg_hint_src; uint32_t rx_packet_drop_counter; + struct candidate_chan_info candidate_channel_info[QDF_MAX_NUM_CHAN]; } tAniSirGlobal; typedef enum { diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 8f801e995b03..bca38e5be28b 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -735,12 +735,11 @@ typedef struct sSirBssDescription { uint8_t mdiePresent; /* MDIE for 11r, picked from the beacons */ uint8_t mdie[SIR_MDIE_SIZE]; -#ifdef FEATURE_WLAN_ESE - uint16_t QBSSLoad_present; + uint8_t QBSSLoad_present; + uint8_t qbss_chan_load; uint16_t QBSSLoad_avail; /* To achieve 8-byte alignment with ESE enabled */ uint32_t reservedPadding5; -#endif /* Please keep the structure 4 bytes aligned above the ieFields */ /* whether it is from a probe rsp */ @@ -753,7 +752,12 @@ typedef struct sSirBssDescription { uint8_t reservedPadding4; uint32_t tsf_delta; + uint8_t ht_caps_present; + uint8_t vht_caps_present; + uint8_t beacomforming_capable; + uint8_t chan_width; uint32_t ieFields[1]; + } tSirBssDescription, *tpSirBssDescription; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH @@ -3012,6 +3016,19 @@ typedef struct { } tSirPrefNetworkFoundInd, *tpSirPrefNetworkFoundInd; #endif /* FEATURE_WLAN_SCAN_PNO */ + +/** + * struct candidate_chan_info - channel information for candidate + * @channel_num: channel number. + * @other_ap_count: other ap count on candidate channel. + * @max_rssi_on_channel: Max best rssi on candiate channel + */ +struct candidate_chan_info { + uint8_t channel_num; + uint8_t other_ap_count; + int8_t max_rssi_on_channel; +}; + /* * ALLOWED_ACTION_FRAMES_BITMAP * diff --git a/core/mac/src/pe/lim/lim_scan_result_utils.c b/core/mac/src/pe/lim/lim_scan_result_utils.c index 493d1ba3d785..36fde037fab0 100644 --- a/core/mac/src/pe/lim/lim_scan_result_utils.c +++ b/core/mac/src/pe/lim/lim_scan_result_utils.c @@ -123,6 +123,22 @@ lim_collect_bss_description(tpAniSirGlobal pMac, pBssDescr->capabilityInfo = lim_get_u16((uint8_t *) &pBPR->capabilityInfo); + /* HT capability */ + if (pBPR->HTCaps.present) { + pBssDescr->ht_caps_present = 1; + if (pBPR->HTCaps.supportedChannelWidthSet) + pBssDescr->chan_width = eHT_CHANNEL_WIDTH_40MHZ; + } + /* VHT Parameters */ + if (pBPR->VHTCaps.present) { + pBssDescr->vht_caps_present = 1; + if (pBPR->VHTCaps.muBeamformerCap) + pBssDescr->beacomforming_capable = 1; + } + if (pBPR->VHTOperation.present) + if (pBPR->VHTOperation.chanWidth == 1) + pBssDescr->chan_width = eHT_CHANNEL_WIDTH_80MHZ; + if (!pBssDescr->beaconInterval) { pe_warn("Beacon Interval is ZERO, making it to default 100 " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHdr->bssId)); @@ -202,14 +218,11 @@ lim_collect_bss_description(tpAniSirGlobal pMac, pBssDescr->mdie[2] = pBPR->mdie[2]; } -#ifdef FEATURE_WLAN_ESE - pBssDescr->QBSSLoad_present = false; - pBssDescr->QBSSLoad_avail = 0; if (pBPR->QBSSLoad.present) { pBssDescr->QBSSLoad_present = true; pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail; + pBssDescr->qbss_chan_load = pBPR->QBSSLoad.chautil; } -#endif /* Copy IE fields */ qdf_mem_copy((uint8_t *) &pBssDescr->ieFields, pBody + SIR_MAC_B_PR_SSID_OFFSET, ieLen); diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 1f13a8cc678e..998c4665e3da 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -1322,6 +1322,7 @@ typedef struct tagCsrConfigParam { bool qcn_ie_support; uint8_t fils_max_chan_guard_time; uint16_t pkt_err_disconn_th; + bool is_bssid_hint_priority; } tCsrConfigParam; /* Tush */ diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index afc47de1053d..a41c57d9c0dc 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -652,6 +652,7 @@ typedef struct tagCsrConfig { bool qcn_ie_support; uint8_t fils_max_chan_guard_time; uint16_t pkt_err_disconn_th; + bool is_bssid_hint_priority; } tCsrConfig; typedef struct tagCsrChannelPowerInfo { diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 3bbf8521d2e9..b0e50235a0c6 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -2707,6 +2707,9 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac, pParam->qcn_ie_support; pMac->roam.configParam.fils_max_chan_guard_time = pParam->fils_max_chan_guard_time; + pMac->roam.configParam.is_bssid_hint_priority = + pParam->is_bssid_hint_priority; + } return status; @@ -2949,6 +2952,8 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam) pMac->roam.configParam.qcn_ie_support; pParam->fils_max_chan_guard_time = pMac->roam.configParam.fils_max_chan_guard_time; + pParam->is_bssid_hint_priority = + pMac->roam.configParam.is_bssid_hint_priority; return QDF_STATUS_SUCCESS; } @@ -7781,6 +7786,37 @@ QDF_STATUS csr_dequeue_roam_command(tpAniSirGlobal pMac, eCsrRoamReason reason) return QDF_STATUS_SUCCESS; } +/** + * csr_roam_print_candidate_aps() - print all candidate AP in sorted + * score. + * @pMac: global mac context + * @hScanList: Handle for scan list + * + * Return : void + */ +static void csr_roam_print_candidate_aps(tpAniSirGlobal pMac, + tScanResultHandle hScanList) +{ + tListElem *pEntry; + struct tag_csrscan_result *pBssDesc = NULL; + struct scan_result_list *bss_list = NULL; + + bss_list = (struct scan_result_list *)hScanList; + pEntry = csr_ll_peek_head(&bss_list->List, LL_ACCESS_NOLOCK); + while (pEntry) { + pBssDesc = GET_BASE_ADDR(pEntry, + struct tag_csrscan_result, Link); + sme_info("BSSID "MAC_ADDRESS_STR" score is %d", + MAC_ADDR_ARRAY(pBssDesc->Result.BssDescriptor.bssId), + pBssDesc->bss_score); + + pEntry = csr_ll_next(&bss_list->List, pEntry, + LL_ACCESS_NOLOCK); + } + return; + +} + QDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId, tCsrRoamProfile *pProfile, uint32_t *pRoamId) @@ -7888,6 +7924,7 @@ QDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId, } status = csr_scan_get_result(pMac, pScanFilter, &hBSSList); sme_debug("csr_scan_get_result Status: %d", status); + csr_roam_print_candidate_aps(pMac, hBSSList); if (QDF_IS_STATUS_SUCCESS(status)) { /* check if set hw mode needs to be done */ if ((pScanFilter->csrPersona == QDF_STA_MODE) || diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index eb014122d0af..81050f3eebe3 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -80,7 +80,7 @@ #define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 30 #define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 20 -#define PCL_ADVANTAGE 30 +#define PCL_ADVANTAGE 20 #define PCL_RSSI_THRESHOLD -75 #define CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) \ @@ -1361,17 +1361,21 @@ static int csr_derive_prefer_value_from_rssi(tpAniSirGlobal mac_ctx, int rssi) } /** - * is_channel_found_in_pcl() - to check if channel is present in pcl + * csr_get_pcl_weight_of_channel() - Get PCL weight if channel is present in pcl * @mac_ctx: Global MAC Context * @channel_id: channel of bss * @filter: pointer to filter created through profile + * @pcl_chan_weight: Get PCL weight for corresponding channel + * @weight_list: Weight list for all the pcl channels. * - * to check if provided channel is present in pcl + * Get pcl_chan_weight if provided channel is present in pcl list * * Return: true or false */ -static bool is_channel_found_in_pcl(tpAniSirGlobal mac_ctx, int channel_id, - tCsrScanResultFilter *filter) +static bool csr_get_pcl_weight_of_channel(tpAniSirGlobal mac_ctx, + int channel_id, + tCsrScanResultFilter *filter, int *pcl_chan_weight, + uint8_t *weight_list) { int i; bool status = false; @@ -1381,6 +1385,7 @@ static bool is_channel_found_in_pcl(tpAniSirGlobal mac_ctx, int channel_id, for (i = 0; i < filter->pcl_channels.numChannels; i++) { if (filter->pcl_channels.channelList[i] == channel_id) { + *pcl_chan_weight = weight_list[i]; status = true; break; } @@ -1524,59 +1529,13 @@ static uint32_t csr_get_bss_cap_value(tpAniSirGlobal pMac, return ret; } - -/** - * csr_is_better_rssi() - Is bss1 better than bss2 - * @mac_ctx: Global MAC Context pointer. - * @bss1: Pointer to the first BSS. - * @bss2: Pointer to the second BSS. - * - * This routine helps in determining the preference value - * of a particular BSS in the scan result which is further - * used in the sorting logic of the final candidate AP's. - * - * Return: true, if bss1 is better than bss2 - * false, if bss2 is better than bss1. - */ -static bool csr_is_better_rssi(tpAniSirGlobal mac_ctx, - struct tag_csrscan_result *bss1, struct tag_csrscan_result - *bss2) -{ - bool ret; - int rssi1, rssi2; - struct qdf_mac_addr local_mac; - - rssi1 = bss1->Result.BssDescriptor.rssi; - rssi2 = bss2->Result.BssDescriptor.rssi; - /* - * Apply the boost and penlty logic and check - * which is the best RSSI - */ - qdf_mem_zero(&local_mac.bytes, QDF_MAC_ADDR_SIZE); - qdf_mem_copy(&local_mac.bytes, - &bss1->Result.BssDescriptor.bssId, QDF_MAC_ADDR_SIZE); - rssi1 = csr_get_altered_rssi(mac_ctx, rssi1, - bss1->Result.BssDescriptor.channelId, - &local_mac); - qdf_mem_copy(&local_mac.bytes, - &bss2->Result.BssDescriptor.bssId, QDF_MAC_ADDR_SIZE); - rssi2 = csr_get_altered_rssi(mac_ctx, rssi2, - bss2->Result.BssDescriptor.channelId, - &local_mac); - if (CSR_IS_BETTER_RSSI(rssi1, rssi2)) - ret = true; - else - ret = false; - return ret; -} - /** * csr_is_better_bss() - Is bss1 better than bss2 * @mac_ctx: Global MAC Context pointer. * @bss1: Pointer to the first BSS. * @bss2: Pointer to the second BSS. * - * This routine helps in determining the preference value + * This function helps in determining the preference value * of a particular BSS in the scan result which is further * used in the sorting logic of the final candidate AP's. * @@ -1587,26 +1546,11 @@ static bool csr_is_better_bss(tpAniSirGlobal mac_ctx, struct tag_csrscan_result *bss1, struct tag_csrscan_result *bss2) { bool ret; - - if (CSR_IS_BETTER_PREFER_VALUE(bss1->preferValue, bss2->preferValue)) { + if (CSR_IS_BETTER_PREFER_VALUE(bss1->bss_score, + bss2->bss_score)) ret = true; - } else if (CSR_IS_EQUAL_PREFER_VALUE - (bss1->preferValue, bss2->preferValue)) { - if (CSR_IS_BETTER_CAP_VALUE(bss1->capValue, bss2->capValue)) - ret = true; - else if (CSR_IS_EQUAL_CAP_VALUE - (bss1->capValue, bss2->capValue)) { - if (csr_is_better_rssi(mac_ctx, bss1, bss2)) - ret = true; - else - ret = false; - } else { - ret = false; - } - } else { + else ret = false; - } - return ret; } @@ -1681,156 +1625,6 @@ static void csr_scan_add_result(tpAniSirGlobal pMac, struct tag_csrscan_result } } -static void -csr_parser_scan_result_for_5ghz_preference(tpAniSirGlobal pMac, - tCsrScanResultFilter *pFilter) -{ - bool fMatch; - QDF_STATUS status; - tListElem *pEntry; - tDot11fBeaconIEs *pIes; - struct tag_csrscan_result *pBssDesc; - uint8_t i = 0; - - /* Find out the best AP Rssi going thru the scan results */ - pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK); - while (NULL != pEntry) { - pBssDesc = GET_BASE_ADDR(pEntry, struct tag_csrscan_result, - Link); - fMatch = false; - - for (i = 0; pFilter && (i < pFilter->SSIDs.numOfSSIDs); i++) { - fMatch = csr_is_ssid_match(pMac, - pFilter->SSIDs.SSIDList[i].SSID.ssId, - pFilter->SSIDs.SSIDList[i].SSID.length, - pBssDesc->Result.ssId.ssId, - pBssDesc->Result.ssId.length, true); - if (!fMatch) - continue; - - pIes = (tDot11fBeaconIEs *)(pBssDesc->Result.pvIes); - /* At this time, Result.pvIes may be NULL */ - if (NULL == pIes) { - status = csr_get_parsed_bss_description_ies( - pMac, - &pBssDesc->Result.BssDescriptor, - &pIes); - if (!pIes && (!QDF_IS_STATUS_SUCCESS(status))) - continue; - } - - sme_debug("SSID Matched"); - if (pFilter->bOSENAssociation) { - fMatch = true; - sme_debug("Security Matched"); - if ((pBssDesc->Result.pvIes == NULL) && pIes) - qdf_mem_free(pIes); - continue; - } -#ifdef WLAN_FEATURE_11W - fMatch = csr_is_security_match(pMac, &pFilter->authType, - &pFilter->EncryptionType, - &pFilter->mcEncryptionType, - &pFilter->MFPEnabled, - &pFilter->MFPRequired, - &pFilter->MFPCapable, - &pBssDesc->Result.BssDescriptor, - pIes, NULL, NULL, NULL); -#else - fMatch = csr_is_security_match(pMac, &pFilter->authType, - &pFilter->EncryptionType, - &pFilter->mcEncryptionType, - NULL, NULL, NULL, - &pBssDesc->Result.BssDescriptor, - pIes, NULL, NULL, NULL); -#endif - if ((pBssDesc->Result.pvIes == NULL) && pIes) - qdf_mem_free(pIes); - if (fMatch) - sme_debug("Security Matched"); - } /* for loop ends */ - - if (fMatch - && (pBssDesc->Result.BssDescriptor.rssi > - pMac->scan.inScanResultBestAPRssi)) { - sme_debug("Best AP Rssi changed from %d to %d", - pMac->scan.inScanResultBestAPRssi, - pBssDesc->Result.BssDescriptor.rssi); - pMac->scan.inScanResultBestAPRssi = - pBssDesc->Result.BssDescriptor.rssi; - } - pEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry, - LL_ACCESS_NOLOCK); - } -} - -static void -csr_prefer_5ghz(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter) -{ - tListElem *pEntry; - struct tag_csrscan_result *pBssDesc; - struct roam_ext_params *roam_params = NULL; - - if (!pMac->roam.configParam.nSelect5GHzMargin && - !CSR_IS_SELECT_5G_PREFERRED(pMac)) - return; - - pMac->scan.inScanResultBestAPRssi = -128; - roam_params = &pMac->roam.configParam.roam_params; -#ifdef WLAN_DEBUG_ROAM_OFFLOAD - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL("nSelect5GHzMargin")); -#endif - csr_ll_lock(&pMac->scan.scanResultList); - /* - * For 5G preference feature, there is no - * need to check the filter match and also re-program the - * RSSI bucket categories, since we use the RSSI values - * while setting the preference value for the BSS. - * There is no need to check the match for roaming since - * it is already done. - */ - if (!CSR_IS_SELECT_5G_PREFERRED(pMac)) - csr_parser_scan_result_for_5ghz_preference(pMac, pFilter); - if (-128 != pMac->scan.inScanResultBestAPRssi || - CSR_IS_SELECT_5G_PREFERRED(pMac)) { - sme_debug("Best AP Rssi is %d", - pMac->scan.inScanResultBestAPRssi); - /* Modify Rssi category based on best AP Rssi */ - if (-128 != pMac->scan.inScanResultBestAPRssi) - csr_assign_rssi_for_category(pMac, - pMac->scan.inScanResultBestAPRssi, - pMac->roam.configParam.bCatRssiOffset); - pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, - LL_ACCESS_NOLOCK); - while (NULL != pEntry) { - pBssDesc = GET_BASE_ADDR(pEntry, struct - tag_csrscan_result, Link); - /* - * re-assign preference value based on modified - * rssi bucket (or) 5G Preference feature. - */ - pBssDesc->preferValue = csr_get_bss_prefer_value(pMac, - (int)pBssDesc->Result.BssDescriptor.rssi, - (struct qdf_mac_addr *) - &pBssDesc->Result.BssDescriptor.bssId, - pBssDesc->Result.BssDescriptor.channelId); - - sme_debug("BSSID("MAC_ADDRESS_STR") Rssi(%d) Chnl(%d) PrefVal(%u) SSID=%.*s", - MAC_ADDR_ARRAY( - pBssDesc->Result.BssDescriptor.bssId), - pBssDesc->Result.BssDescriptor.rssi, - pBssDesc->Result.BssDescriptor.channelId, - pBssDesc->preferValue, - pBssDesc->Result.ssId.length, - pBssDesc->Result.ssId.ssId); - pEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry, - LL_ACCESS_NOLOCK); - } - } - csr_ll_unlock(&pMac->scan.scanResultList); -} - static QDF_STATUS csr_save_ies(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter, @@ -1885,17 +1679,263 @@ csr_save_ies(tpAniSirGlobal pMac, return status; } +/** + * csr_calc_other_rssi_count_weight() - Calculate channel weight based on other + * APs RSSI and count for candiate selection. + * @rssi: Best rssi on that channel + * @count: No. of APs on that channel + * + * Return : uint32_t + */ +static uint32_t csr_calc_other_rssi_count_weight(int32_t rssi, int32_t count) +{ + int32_t rssi_weight = 0; + int32_t count_weight = 0; + int32_t rssi_count_weight = 0; + + rssi_weight = BEST_CANDIDATE_RSSI_WEIGHT * (rssi - MIN_RSSI); + + do_div(rssi_weight, (MAX_RSSI - MIN_RSSI)); + + if (rssi_weight > BEST_CANDIDATE_RSSI_WEIGHT) + rssi_weight = BEST_CANDIDATE_RSSI_WEIGHT; + else if (rssi_weight < 0) + rssi_weight = 0; + + count_weight = BEST_CANDIDATE_AP_COUNT_WEIGHT * + (count + BEST_CANDIDATE_MIN_COUNT); + + do_div(count_weight, + (BEST_CANDIDATE_MAX_COUNT + BEST_CANDIDATE_MIN_COUNT)); + + if (count_weight > BEST_CANDIDATE_AP_COUNT_WEIGHT) + count_weight = BEST_CANDIDATE_AP_COUNT_WEIGHT; + + rssi_count_weight = ROAM_MAX_CHANNEL_WEIGHT - + (rssi_weight + count_weight); + + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL("rssi_weight=%d, count_weight=%d, rssi_count_weight=%d rssi=%d count=%d"), + rssi_weight, count_weight, rssi_count_weight, rssi, count); + + return rssi_count_weight; +} + +/** + * _csr_calculate_bss_score () - Calculate BSS score based on AP capabilty + * and channel condition for best candidate + * selection + * @bss_info: bss information + * @best_rssi : Best rssi on BSS channel + * @ap_cnt: No of AP count on BSS channel + * @pcl_chan_weight: pcl weight of BSS channel + * + * Return : int32_t + */ +static int32_t _csr_calculate_bss_score(tSirBssDescription *bss_info, + int32_t best_rssi, int32_t ap_cnt, int pcl_chan_weight) +{ + int32_t score = 0; + int32_t ap_load = 0; + int32_t normalised_width = BEST_CANDIDATE_20MHZ; + int32_t normalised_rssi = 0; + int32_t channel_weight; + int32_t pcl_score = 0; + int32_t modified_rssi = 0; + int32_t temp_pcl_chan_weight = 0; + + /* + * Total weight of a BSSID is calculated on basis of 100 in which + * contribution of every factor is considered like this. + * RSSI: RSSI_WEIGHTAGE : 25 + * HT_CAPABILITY_WEIGHTAGE: 7 + * VHT_CAP_WEIGHTAGE: 5 + * BEAMFORMING_CAP_WEIGHTAGE: 2 + * CHAN_WIDTH_WEIGHTAGE:10 + * CHAN_BAND_WEIGHTAGE: 5 + * CCA_WEIGHTAGE: 8 + * OTHER_AP_WEIGHT: 28 + * PCL: 10 + * + * Rssi_weightage is again divided in another factors like if Rssi is + * very good, very less or medium. + * According to this FR, best rssi is being considered as -40. + * EXCELLENT_RSSI = -40 + * GOOD_RSSI = -55 + * POOR_RSSI = -65 + * BAD_RSSI = -80 + * + * And weightage to all the RSSI type is given like this. + * ROAM_EXCELLENT_RSSI_WEIGHT = 100 + * ROAM_GOOD_RSSI_WEIGHT = 80 + * ROAM_BAD_RSSI_WEIGHT = 60 + * + */ + + if (bss_info->rssi) { + /* + * if RSSI of AP is less then -80, driver should ignore that + * candidate. + */ + if (bss_info->rssi < BAD_RSSI) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL("Drop this BSS "MAC_ADDRESS_STR " due to low rssi %d"), + MAC_ADDR_ARRAY(bss_info->bssId), bss_info->rssi); + score = 0; + return score; + } + /* If BSS is in PCL list, give a boost of -20dbm */ + if (pcl_chan_weight) + modified_rssi = bss_info->rssi + PCL_ADVANTAGE; + else + modified_rssi = bss_info->rssi; + /* + * Calculate % of rssi we are getting + * max = 100 + * min = 0 + * less than -40 = 100% + * -40 - -55 = 80% + * -55 - -65 = 60% + * below that = 100 - value + **/ + if (modified_rssi >= BEST_CANDIDATE_EXCELLENT_RSSI) + normalised_rssi = BEST_CANDIDATE_EXCELLENT_RSSI_WEIGHT; + else if (modified_rssi >= BEST_CANDIDATE_GOOD_RSSI) + normalised_rssi = BEST_CANDIDATE_GOOD_RSSI_WEIGHT; + else if (modified_rssi >= BEST_CANDIDATE_POOR_RSSI) + normalised_rssi = BEST_CANDIDATE_BAD_RSSI_WEIGHT; + else + normalised_rssi = modified_rssi - MIN_RSSI; + + /* Calculate score part for rssi */ + score += (normalised_rssi * RSSI_WEIGHTAGE); + } + /* If BSS is in PCL list extra pcl Weight is added n % */ + if (pcl_chan_weight) { + temp_pcl_chan_weight = + (MAX_WEIGHT_OF_PCL_CHANNELS - pcl_chan_weight); + do_div(temp_pcl_chan_weight, + PCL_GROUPS_WEIGHT_DIFFERENCE); + pcl_score = PCL_WEIGHT - temp_pcl_chan_weight; + + if (pcl_score < 0) + pcl_score = 0; + + score += pcl_score * BEST_CANDIDATE_MAX_WEIGHT; + } + /* If AP supports HT caps, extra 10% score will be added */ + if (bss_info->ht_caps_present) + score += BEST_CANDIDATE_MAX_WEIGHT * HT_CAPABILITY_WEIGHTAGE; + + /* If AP supports VHT caps, Extra 6% score will be added to score */ + if (bss_info->vht_caps_present) + score += BEST_CANDIDATE_MAX_WEIGHT * VHT_CAP_WEIGHTAGE; + + /* If AP supports beam forming, extra 2% score will be added to score.*/ + if (bss_info->beacomforming_capable) + score += BEST_CANDIDATE_MAX_WEIGHT * BEAMFORMING_CAP_WEIGHTAGE; + + /* + * Channel width is again calculated on basis of 100. + * Where if AP is + * 80MHZ = 100 + * 40MHZ = 70 + * 20MHZ = 30 weightage is given out of 100. + * Channel width weightage is given as CHAN_WIDTH_WEIGHTAGE (10%). + */ + if (bss_info->chan_width == eHT_CHANNEL_WIDTH_80MHZ) + normalised_width = BEST_CANDIDATE_80MHZ; + else if (bss_info->chan_width == eHT_CHANNEL_WIDTH_40MHZ) + normalised_width = BEST_CANDIDATE_40MHZ; + else + normalised_width = BEST_CANDIDATE_20MHZ; + score += normalised_width * CHAN_WIDTH_WEIGHTAGE; + + /* If AP is on 5Ghz channel , extra score of 5% is added to BSS score.*/ + if (get_rf_band(bss_info->channelId) == SIR_BAND_5_GHZ && + bss_info->rssi > RSSI_THRESHOLD_5GHZ) + score += BEST_CANDIDATE_MAX_WEIGHT * CHAN_BAND_WEIGHTAGE; + + /* + * If QBSS load is present, extra CCA weightage is given on based of AP + * load as 10%. + */ + if (bss_info->QBSSLoad_present) { + /* calculate value in % */ + ap_load = (bss_info->qbss_chan_load * + BEST_CANDIDATE_MAX_WEIGHT); + do_div(ap_load, MAX_AP_LOAD); + } + /* + * If doesn't announce its ap load, driver will take it as 50% of + * CCA_WEIGHTAGE + */ + if (ap_load) + score += (MAX_CHANNEL_UTILIZATION - ap_load) * CCA_WEIGHTAGE; + else + score += DEFAULT_CHANNEL_UTILIZATION * CCA_WEIGHTAGE; + + if (ap_cnt == 0) + channel_weight = ROAM_MAX_CHANNEL_WEIGHT; + else + channel_weight = csr_calc_other_rssi_count_weight( + best_rssi, ap_cnt); + + score += channel_weight * OTHER_AP_WEIGHT; + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL("BSSID:"MAC_ADDRESS_STR" rssi=%d normalized_rssi=%d htcaps=%d vht=%d bw=%d channel=%d beamforming=%d ap_load=%d channel_weight=%d pcl_score %d Final Score %d "), + MAC_ADDR_ARRAY(bss_info->bssId), + bss_info->rssi, normalised_rssi, bss_info->ht_caps_present, + bss_info->vht_caps_present, bss_info->chan_width, + bss_info->channelId, + bss_info->beacomforming_capable, ap_load, channel_weight, + pcl_score, + score); + return score; +} +/** + * csr_calculate_bss_score() - Calculate candidate AP score for Best + * candidate selection for connection + * @mac_ctx: Pointer to mac context + * @bss: BSSID + * @pcl_chan_weight: pcl weight for bss channel + * + * Return: int + * + * Calculate candidate AP score for Best candidate selection for connection. + */ +static int32_t csr_calculate_bss_score(tpAniSirGlobal pMac, + struct tag_csrscan_result *pBss, + int pcl_chan_weight) +{ + int32_t score = 0; + int channel_id; + tSirBssDescription *bss_info = &(pBss->Result.BssDescriptor); + + channel_id = cds_get_channel_enum(pBss->Result.BssDescriptor.channelId); + + score = _csr_calculate_bss_score(bss_info, + pMac->candidate_channel_info[channel_id]. + max_rssi_on_channel, + pMac->candidate_channel_info[channel_id]. + other_ap_count, pcl_chan_weight); + + pBss->bss_score = score; + return 0; +} + static QDF_STATUS csr_save_scan_entry(tpAniSirGlobal pMac, - tCsrScanResultFilter *pFilter, - bool fMatch, - struct tag_csrscan_result *pBssDesc, - tDot11fBeaconIEs *pNewIes, - struct scan_result_list *pRetList, - uint32_t *count, - eCsrEncryptionType uc, - eCsrEncryptionType mc, - eCsrAuthType *auth) + tCsrScanResultFilter *pFilter, + bool fMatch, + struct tag_csrscan_result *pBssDesc, + tDot11fBeaconIEs *pNewIes, + struct scan_result_list *pRetList, + uint32_t *count, + eCsrEncryptionType uc, + eCsrEncryptionType mc, + eCsrAuthType *auth, + uint8_t *weight_list) { QDF_STATUS status = QDF_STATUS_SUCCESS; struct tag_csrscan_result *pResult; @@ -1903,6 +1943,7 @@ csr_save_scan_entry(tpAniSirGlobal pMac, /* To sort the list */ tListElem *pTmpEntry; struct tag_csrscan_result *pTmpResult; + int pcl_chan_weight = 0; if (!(NULL == pFilter || fMatch)) return status; @@ -1929,11 +1970,29 @@ csr_save_scan_entry(tpAniSirGlobal pMac, pResult->Result.timer = pBssDesc->Result.timer; /* save the pIes for later use */ pResult->Result.pvIes = pNewIes; + pResult->bss_score = 0; /* save bss description */ qdf_mem_copy(&pResult->Result.BssDescriptor, &pBssDesc->Result.BssDescriptor, bssLen); /* + * calculate pcl_chan_weight from weight list to honor PCL list + */ + if (pFilter && pFilter->pcl_channels.numChannels > 0 && + (pBssDesc->Result.BssDescriptor.rssi > PCL_RSSI_THRESHOLD)) { + if (csr_get_pcl_weight_of_channel(pMac, + pBssDesc->Result.BssDescriptor.channelId, + pFilter, &pcl_chan_weight, weight_list)) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL(" pcl channel %d pcl_chan_weight %d"), + pBssDesc->Result.BssDescriptor.channelId, + pcl_chan_weight); + } + } + if (pFilter) + csr_calculate_bss_score(pMac, pResult, pcl_chan_weight); + + /* * No need to lock pRetList because it is locally allocated and no * outside can access it at this time */ @@ -1945,27 +2004,20 @@ csr_save_scan_entry(tpAniSirGlobal pMac, } if (pFilter && !qdf_mem_cmp(pResult->Result.BssDescriptor.bssId, - pFilter->bssid_hint.bytes, QDF_MAC_ADDR_SIZE)) { + pFilter->bssid_hint.bytes, QDF_MAC_ADDR_SIZE) && + pMac->roam.configParam.is_bssid_hint_priority) { /* bssid hint AP should be on head */ csr_ll_insert_head(&pRetList->List, &pResult->Link, LL_ACCESS_NOLOCK); (*count)++; + pResult->bss_score = BEST_CANDIDATE_MAX_BSS_SCORE; return status; } - pTmpEntry = csr_ll_peek_head(&pRetList->List, LL_ACCESS_NOLOCK); while (pTmpEntry) { pTmpResult = GET_BASE_ADDR(pTmpEntry, struct tag_csrscan_result, Link); - /* Skip the bssid hint AP, as it should be on head */ - if (pFilter && - !qdf_mem_cmp(pTmpResult->Result.BssDescriptor.bssId, - pFilter->bssid_hint.bytes, QDF_MAC_ADDR_SIZE)) { - pTmpEntry = csr_ll_next(&pRetList->List, - pTmpEntry, LL_ACCESS_NOLOCK); - continue; - } if (csr_is_better_bss(pMac, pResult, pTmpResult)) { csr_ll_insert_entry(&pRetList->List, pTmpEntry, &pResult->Link, LL_ACCESS_NOLOCK); @@ -1984,60 +2036,80 @@ csr_save_scan_entry(tpAniSirGlobal pMac, (*count)++; return status; } - /** - * csr_calc_pref_val_by_pcl() - to calculate preferred value - * @mac_ctx: mac context - * @filter: filter to find match from scan result - * @bss_descr: pointer to bss descriptor - * - * this routine calculates the new preferred value to be given to - * provided bss if its channel falls under preferred channel list. - * Thump rule is higer the RSSI better the boost. + * csr_calculate_other_ap_count_n_rssi() - calculate channel load on matching + * profile's channel + * @mac_ctx: Global MAC Context pointer. + * @pFilter: Filter to select candidate. * - * Return: success or failure + * This function processes scan list and match scan results + * with candidate profile. If some scan result doesn't match + * with candidate profile, this function calculates no of + * those AP and best RSSI on that candidate's channel. */ -static QDF_STATUS csr_calc_pref_val_by_pcl(tpAniSirGlobal mac_ctx, - tCsrScanResultFilter *filter, - struct tag_csrscan_result *bss_descr) +static QDF_STATUS csr_calculate_other_ap_count_n_rssi(tpAniSirGlobal pMac, + tCsrScanResultFilter *pFilter) { - int temp_rssi = 0, new_pref_val = 0; - int orig_pref_val = 0; - - if (NULL == mac_ctx || NULL == bss_descr) - return QDF_STATUS_E_FAILURE; - if (filter && (0 != filter->BSSIDs.numOfBSSIDs)) { - sme_warn("filter has specific bssid, no point of boosting"); - return QDF_STATUS_SUCCESS; - } - - if (is_channel_found_in_pcl(mac_ctx, - bss_descr->Result.BssDescriptor.channelId, filter) && - (bss_descr->Result.BssDescriptor.rssi > PCL_RSSI_THRESHOLD)) { - orig_pref_val = csr_derive_prefer_value_from_rssi(mac_ctx, - bss_descr->Result.BssDescriptor.rssi); - temp_rssi = bss_descr->Result.BssDescriptor.rssi + - (PCL_ADVANTAGE/(CSR_NUM_RSSI_CAT - - orig_pref_val)); - if (temp_rssi > 0) - temp_rssi = 0; - new_pref_val = csr_derive_prefer_value_from_rssi(mac_ctx, - temp_rssi); + QDF_STATUS status = QDF_STATUS_SUCCESS; + tListElem *entry; + bool match = false; + struct tag_csrscan_result *bss = NULL; + tDot11fBeaconIEs *ies, *new_ies = NULL; + int channel_id; - sme_debug( - "%pM: rssi:%d org pref=%d temp rssi:%d new pref=%d pref=%d updated pref=%d", - bss_descr->Result.BssDescriptor.bssId, - bss_descr->Result.BssDescriptor.rssi, - orig_pref_val, temp_rssi, new_pref_val, - bss_descr->preferValue, - CSR_MAX(new_pref_val, bss_descr->preferValue)); + csr_ll_lock(&pMac->scan.scanResultList); + entry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK); + while (entry) { + bss = GET_BASE_ADDR(entry, struct tag_csrscan_result, Link); + ies = (tDot11fBeaconIEs *) (bss->Result.pvIes); + match = false; + new_ies = NULL; + + status = csr_save_ies(pMac, pFilter, bss, &new_ies, + &match, NULL, NULL, NULL); + if (new_ies) + qdf_mem_free(new_ies); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_info("save ies fail"); + break; + } + /* + * Calculate Count of APs and Best Rssi on matching profile's + * channel. This information will be used to calculate + * total congestion on that channel. + */ + if (!match) { + channel_id = cds_get_channel_enum( + bss->Result.BssDescriptor.channelId); + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL("channel_id %d ssid %s rssi %d mac address "MAC_ADDRESS_STR), + bss->Result.BssDescriptor.channelId, + bss->Result.ssId.ssId, + bss->Result.BssDescriptor.rssi, + MAC_ADDR_ARRAY( + bss->Result.BssDescriptor.bssId)); + pMac->candidate_channel_info[channel_id]. + other_ap_count++; + if (pMac->candidate_channel_info[channel_id]. + max_rssi_on_channel >= 0) + pMac->candidate_channel_info[channel_id]. + max_rssi_on_channel = -127; + if ((bss->Result.BssDescriptor.rssi > + pMac->candidate_channel_info[channel_id]. + max_rssi_on_channel)) + pMac->candidate_channel_info[channel_id]. + max_rssi_on_channel = + bss->Result.BssDescriptor.rssi; + } + entry = csr_ll_next(&pMac->scan.scanResultList, entry, + LL_ACCESS_NOLOCK); - bss_descr->preferValue = - CSR_MAX(new_pref_val, bss_descr->preferValue); } - return QDF_STATUS_SUCCESS; + csr_ll_unlock(&pMac->scan.scanResultList); + return status; } + static QDF_STATUS csr_parse_scan_results(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter, @@ -2089,14 +2161,9 @@ csr_parse_scan_results(tpAniSirGlobal pMac, sme_debug("save ies fail %d", status); break; } - /* - * Modify the prefer value to honor PCL list - */ - if (pFilter && pFilter->pcl_channels.numChannels > 0) - csr_calc_pref_val_by_pcl(pMac, pFilter, pBssDesc); status = csr_save_scan_entry(pMac, pFilter, fMatch, pBssDesc, pNewIes, pRetList, count, uc, mc, - &auth); + &auth, weight_list); if (!QDF_IS_STATUS_SUCCESS(status)) { sme_debug("save entry fail %d", status); break; @@ -2119,7 +2186,10 @@ QDF_STATUS csr_scan_get_result(tpAniSirGlobal pMac, if (phResult) *phResult = CSR_INVALID_SCANRESULT_HANDLE; - csr_prefer_5ghz(pMac, pFilter); + qdf_mem_set(&pMac->candidate_channel_info, + sizeof(struct candidate_chan_info), 0); + if (pFilter) + csr_calculate_other_ap_count_n_rssi(pMac, pFilter); pRetList = qdf_mem_malloc(sizeof(struct scan_result_list)); if (NULL == pRetList) { diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index ab26aa64d27a..e2bcdb193ffa 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -110,6 +110,44 @@ extern uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE]; bool csr_is_supported_channel(tpAniSirGlobal pMac, uint8_t channelId); +#define RSSI_THRESHOLD_5GHZ -70 +#define BEST_CANDIDATE_RSSI_WEIGHT 50 +#define MIN_RSSI (-100) +#define MAX_RSSI 0 +#define BEST_CANDIDATE_AP_COUNT_WEIGHT 50 +#define BEST_CANDIDATE_MAX_COUNT 30 +#define BEST_CANDIDATE_MIN_COUNT 0 +#define ROAM_MAX_CHANNEL_WEIGHT 100 +#define DEFAULT_CHANNEL_UTILIZATION 50 +#define MAX_CHANNEL_UTILIZATION 100 + +#define RSSI_WEIGHTAGE 25 +#define HT_CAPABILITY_WEIGHTAGE 7 +#define VHT_CAP_WEIGHTAGE 5 +#define BEAMFORMING_CAP_WEIGHTAGE 2 +#define CHAN_WIDTH_WEIGHTAGE 10 +#define CHAN_BAND_WEIGHTAGE 5 +#define WMM_WEIGHTAGE 0 +#define CCA_WEIGHTAGE 8 +#define OTHER_AP_WEIGHT 28 +#define PCL_WEIGHT 10 + +#define MAX_AP_LOAD 255 +#define BEST_CANDIDATE_EXCELLENT_RSSI -40 +#define BEST_CANDIDATE_GOOD_RSSI -55 +#define BEST_CANDIDATE_POOR_RSSI -65 +#define BAD_RSSI -80 +#define BEST_CANDIDATE_EXCELLENT_RSSI_WEIGHT 100 +#define BEST_CANDIDATE_GOOD_RSSI_WEIGHT 80 +#define BEST_CANDIDATE_BAD_RSSI_WEIGHT 60 +#define BEST_CANDIDATE_MAX_WEIGHT 100 +#define BEST_CANDIDATE_80MHZ 100 +#define BEST_CANDIDATE_40MHZ 70 +#define BEST_CANDIDATE_20MHZ 30 +#define BEST_CANDIDATE_PENALTY (3/10) +#define BEST_CANDIDATE_MAX_BSS_SCORE 10000 + + enum csr_scancomplete_nextcommand { eCsrNextScanNothing, eCsrNextLostLinkScan1Success, @@ -175,6 +213,7 @@ struct tag_csrscan_result { eCsrAuthType authType; tCsrScanResultInfo Result; + int bss_score; }; struct scan_result_list { |
