Prechádzať zdrojové kódy

qcacmn: Fix RSSI for the beacon received in adjacent channnel

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

Change-Id: Ie9dc26f938b58b0c5d071ce4f2ba02b8e7fd4f60
CRs-Fixed: 2180012
Abhishek Singh 7 rokov pred
rodič
commit
c05285da8a

+ 30 - 8
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);
 	}
 

+ 3 - 1
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

+ 2 - 0
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;

+ 18 - 0
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

+ 1 - 0
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;