summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 {