diff --git a/umac/scan/core/src/wlan_scan_cache_db.c b/umac/scan/core/src/wlan_scan_cache_db.c index 5b31e3404c4c..fced2b4b2286 100644 --- a/umac/scan/core/src/wlan_scan_cache_db.c +++ b/umac/scan/core/src/wlan_scan_cache_db.c @@ -477,10 +477,30 @@ static void scm_delete_duplicate_entry(struct scan_dbs *scan_db, scan_params->ssid.length); } } + /* - * Use old value for rssi if beacon - * was heard on adjacent channel. + * Due to Rx sensitivity issue, sometime beacons are seen on adjacent + * channel so workaround in software is needed. If DS params or HT info + * are present driver can get proper channel info from these IEs and set + * channel_mismatch so that the older RSSI values are used in new entry. + * + * For the cases where DS params and HT info is not present, driver + * needs to check below conditions to get proper channel and set + * channel_mismatch so that the older RSSI values are used in new entry: + * -- The old entry channel and new entry channel are not same + * -- RSSI is less than -80, this indicate that the signal has leaked + * in adjacent channel. */ + if ((scan_params->frm_subtype == MGMT_SUBTYPE_BEACON) && + !util_scan_entry_htinfo(scan_params) && + !util_scan_entry_ds_param(scan_params) && + (scan_params->channel.chan_idx != scan_entry->channel.chan_idx) && + (scan_params->rssi_raw < ADJACENT_CHANNEL_RSSI_THRESHOLD)) { + scan_params->channel.chan_idx = scan_entry->channel.chan_idx; + scan_params->channel_mismatch = true; + } + + /* Use old value for rssi if beacon was heard on adjacent channel. */ if (scan_params->channel_mismatch) { scan_params->rssi_raw = scan_entry->rssi_raw; scan_params->avg_rssi = scan_entry->avg_rssi; @@ -671,6 +691,14 @@ QDF_STATUS scm_handle_bcn_probe(struct scheduler_msg *msg) struct scan_cache_node, node); scan_entry = scan_node->entry; + + status = scm_add_update_entry(scan_db, scan_entry); + if (QDF_IS_STATUS_ERROR(status)) { + util_scan_free_cache_entry(scan_entry); + qdf_mem_free(scan_node); + scm_err("failed to add entry"); + continue; + } scm_info("Received %s from BSSID: %pM tsf_delta = %u Seq Num: %x " "ssid:%.*s, rssi: %d", (bcn->frm_type == MGMT_SUBTYPE_PROBE_RESP) ? @@ -684,12 +712,6 @@ QDF_STATUS scm_handle_bcn_probe(struct scheduler_msg *msg) if (scan_obj->cb.inform_beacon) scan_obj->cb.inform_beacon(pdev, scan_entry); - - status = scm_add_update_entry(scan_db, scan_entry); - if (QDF_IS_STATUS_ERROR(status)) { - util_scan_free_cache_entry(scan_entry); - scm_err("failed to add entry"); - } qdf_mem_free(scan_node); } diff --git a/umac/scan/core/src/wlan_scan_cache_db.h b/umac/scan/core/src/wlan_scan_cache_db.h index 931bd251829c..38f5ee417453 100644 --- a/umac/scan/core/src/wlan_scan_cache_db.h +++ b/umac/scan/core/src/wlan_scan_cache_db.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -36,6 +36,8 @@ #define SCM_PCL_RSSI_THRESHOLD -75 #define BEST_CANDIDATE_MAX_BSS_SCORE 10000 +#define ADJACENT_CHANNEL_RSSI_THRESHOLD -80 + /** * struct scan_dbs - scan cache data base definition * @num_entries: number of scan entries diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 43ded031589c..7bd27518eb2d 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -117,6 +117,7 @@ struct element_info { * @ssid: pointer to ssid ie * @rates: pointer to supported rates ie * @xrates: pointer to extended supported rate ie + * @ds_param: pointer to ds params * @csa: pointer to csa ie * @xcsa: pointer to extended csa ie * @wpa: pointer to wpa ie @@ -156,6 +157,7 @@ struct ie_list { uint8_t *ssid; uint8_t *rates; uint8_t *xrates; + uint8_t *ds_param; uint8_t *csa; uint8_t *xcsa; uint8_t *wpa; diff --git a/umac/scan/dispatcher/inc/wlan_scan_utils_api.h b/umac/scan/dispatcher/inc/wlan_scan_utils_api.h index fa8fd59dd4fa..020abcd1375e 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_utils_api.h +++ b/umac/scan/dispatcher/inc/wlan_scan_utils_api.h @@ -616,6 +616,7 @@ util_scan_copy_beacon_data(struct scan_cache_entry *new_entry, ie_lst->ssid = conv_ptr(ie_lst->ssid, old_ptr, new_ptr); ie_lst->rates = conv_ptr(ie_lst->rates, old_ptr, new_ptr); ie_lst->xrates = conv_ptr(ie_lst->xrates, old_ptr, new_ptr); + ie_lst->ds_param = conv_ptr(ie_lst->ds_param, old_ptr, new_ptr); ie_lst->csa = conv_ptr(ie_lst->csa, old_ptr, new_ptr); ie_lst->xcsa = conv_ptr(ie_lst->xcsa, old_ptr, new_ptr); ie_lst->secchanoff = conv_ptr(ie_lst->secchanoff, old_ptr, new_ptr); @@ -881,6 +882,23 @@ util_scan_entry_sfa(struct scan_cache_entry *scan_entry) return scan_entry->ie_list.sfa; } +/** + * util_scan_entry_ds_param() - function to read ds params + * @scan_entry: scan entry + * + * API, function to read ds params + * + * Return: ds params or NULL if ie is not present + */ +static inline uint8_t* +util_scan_entry_ds_param(struct scan_cache_entry *scan_entry) +{ + if (scan_entry) + return scan_entry->ie_list.ds_param; + else + return NULL; +} + /** * util_scan_entry_csa() - function to read csa IE * @scan_entry: scan entry diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index 237c42c9807f..4eb39ea7dbfe 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -455,6 +455,7 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params) scan_params->ie_list.rates = (uint8_t *)ie; break; case WLAN_ELEMID_DSPARMS: + scan_params->ie_list.ds_param = (uint8_t *)ie; scan_params->channel.chan_idx = ((struct ds_ie *)ie)->cur_chan; break;