summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAgrawal Ashish <ashishka@codeaurora.org>2017-03-17 19:30:26 +0530
committerspuligil <spuligil@codeaurora.org>2017-04-15 12:49:35 -0700
commita5f9e2801821c60189c29c1cdbcd53c75ddb85fa (patch)
tree1405c1f35e93a93f8660b8cbcbd0755d609c61de
parent137e84a459d812662e1b61583e88bf486f9240ab (diff)
qcacld-3.0: Best candidate at first connection
Best candidate at first connection is a mechanism to select best possible candidate for making Wi-Fi connection based on the scan results provided. Driver use Scan results to calculates score for each BSS and select the best candidate to connect. This enhances the user experience by connection to better AP, based on certain parameters. Change-Id: I3f88fa8c67f4cf830f05faf2c1d3f3491eee9a72 CRs-Fixed: 2018585
-rw-r--r--core/cds/inc/cds_reg_service.h10
-rw-r--r--core/cds/src/cds_reg_service.c8
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h25
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c14
-rw-r--r--core/mac/inc/ani_global.h1
-rw-r--r--core/mac/inc/sir_api.h23
-rw-r--r--core/mac/src/pe/lim/lim_scan_result_utils.c21
-rw-r--r--core/sme/inc/csr_api.h1
-rw-r--r--core/sme/inc/csr_internal.h1
-rw-r--r--core/sme/src/csr/csr_api_roam.c37
-rw-r--r--core/sme/src/csr/csr_api_scan.c652
-rw-r--r--core/sme/src/csr/csr_inside_api.h39
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 {