Преглед на файлове

qcacmn: Reset scan chan info if no scan entries are present

Scenario: Turn on and off XPAN multiple times and in between
of this, bring all interface down.

When XPAN gets turned on, it will run ACS algorithm either on
new scan results or previous scan results which are having
last_scan_ageout_time less than 30sec to select the best
channel. If multiple times ACS request comes then driver should
select the same previous channel if it's scan time is less than
30sec. But in this case, driver was selecting different channel
when all channels were recently scanned.

This is because, in some scenario, the number of scan entries
was becoming 0 which causes ACS to select new channel even the
previous selected channel were recently scanned.
Reason for becoming number of scan entries as 0 is when all
interface goes down, stop modules will get call which results
to flush out the psoc. As part of psoc flush out, it will remove
all scan entries as well. But driver is not resetting the
last_scan_ageout_time when no scan entries are present. Hence,
it will not for new scan again and later all channels were having
same score after applying ACS logic. This led to select first
from scanned list.

As part of fix, reset the last_scan_ageout_time when no scan
entries are present.

Change-Id: I8e021ecf22047661076e11302998a42c029f8b37
CRs-Fixed: 3625075
Jyoti Kumari преди 1 година
родител
ревизия
a1b2495738

+ 3 - 2
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -1505,8 +1505,9 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
 	}
 	opmode = wlan_vdev_mlme_get_opmode(vdev);
 
-	osif_debug("%s(vdev%d): mode %d", request->wdev->netdev->name,
-		   wlan_vdev_get_id(vdev), opmode);
+	osif_debug("%s(vdev%d): mode %d flags 0x%x",
+		   request->wdev->netdev->name,
+		   wlan_vdev_get_id(vdev), opmode, request->flags);
 
 	if (!wlan_is_scan_allowed(vdev))
 		return -EBUSY;

+ 22 - 4
umac/scan/core/src/wlan_scan_cache_db.c

@@ -1679,12 +1679,12 @@ scm_scan_apply_filter_flush_entry(struct wlan_objmgr_psoc *psoc,
  * @psoc: psoc ptr
  * @scan_db: scan db
  * @filter: filter
+ * @pdev_id: pdev id of the scan db
  *
  * Return: void
  */
 static void scm_flush_scan_entries(struct wlan_objmgr_psoc *psoc,
-	struct scan_dbs *scan_db,
-	struct scan_filter *filter)
+	struct scan_dbs *scan_db, struct scan_filter *filter, uint8_t pdev_id)
 {
 	int i;
 	struct scan_cache_node *cur_node;
@@ -1701,6 +1701,9 @@ static void scm_flush_scan_entries(struct wlan_objmgr_psoc *psoc,
 			cur_node = next_node;
 		}
 	}
+	/* if all scan results are flushed reset scan channel info as well */
+	if (!filter)
+		scm_reset_scan_chan_info(psoc, pdev_id);
 }
 
 QDF_STATUS scm_flush_results(struct wlan_objmgr_pdev *pdev,
@@ -1727,7 +1730,8 @@ QDF_STATUS scm_flush_results(struct wlan_objmgr_pdev *pdev,
 		return QDF_STATUS_E_INVAL;
 	}
 
-	scm_flush_scan_entries(psoc, scan_db, filter);
+	scm_flush_scan_entries(psoc, scan_db, filter,
+			       wlan_objmgr_pdev_get_pdev_id(pdev));
 
 	return status;
 }
@@ -1849,6 +1853,19 @@ QDF_STATUS scm_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+void scm_reset_scan_chan_info(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
+{
+	struct wlan_scan_obj *scan_obj;
+
+	scan_obj = wlan_psoc_get_scan_obj(psoc);
+	if (!scan_obj)
+		return;
+
+	scm_debug("pdev %d, Reset all channel info", pdev_id);
+	qdf_mem_zero(&scan_obj->pdev_info[pdev_id].chan_scan_info,
+		     sizeof(scan_obj->pdev_info[pdev_id].chan_scan_info));
+}
+
 QDF_STATUS scm_db_init(struct wlan_objmgr_psoc *psoc)
 {
 	int i, j;
@@ -1871,6 +1888,7 @@ QDF_STATUS scm_db_init(struct wlan_objmgr_psoc *psoc)
 		for (j = 0; j < SCAN_HASH_SIZE; j++)
 			qdf_list_create(&scan_db->scan_hash_tbl[j],
 				MAX_SCAN_CACHE_SIZE);
+		scm_reset_scan_chan_info(psoc, i);
 	}
 	return QDF_STATUS_SUCCESS;
 }
@@ -1893,7 +1911,7 @@ QDF_STATUS scm_db_deinit(struct wlan_objmgr_psoc *psoc)
 			continue;
 		}
 
-		scm_flush_scan_entries(psoc, scan_db, NULL);
+		scm_flush_scan_entries(psoc, scan_db, NULL, i);
 		for (j = 0; j < SCAN_HASH_SIZE; j++)
 			qdf_list_destroy(&scan_db->scan_hash_tbl[j]);
 		qdf_spinlock_destroy(&scan_db->scan_db_lock);

+ 9 - 0
umac/scan/core/src/wlan_scan_cache_db.h

@@ -194,6 +194,15 @@ QDF_STATUS scm_scan_register_bcn_cb(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS scm_scan_register_mbssid_cb(struct wlan_objmgr_psoc *psoc,
 				       update_mbssid_bcn_prb_rsp cb);
 
+/**
+ * scm_reset_scan_chan_info() - API to reset the scan channel info
+ * @psoc: psoc object
+ * @pdev_id: pdev id of which info need to be reset
+ *
+ * Return: void
+ */
+void scm_reset_scan_chan_info(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id);
+
 /**
  * scm_db_init() - API to init scan db
  * @psoc: psoc

+ 0 - 3
umac/scan/core/src/wlan_scan_manager.c

@@ -1687,8 +1687,6 @@ void scm_update_last_scan_time_per_channel(struct wlan_objmgr_vdev *vdev,
 	for (i = 0; i < chan_info->num_chan ; i++) {
 		if (chan_info->ch_scan_info[i].freq == chan_freq) {
 			chan_info->ch_scan_info[i].last_scan_time = time;
-			scm_debug("chan freq %d scan time %u\n",
-				  chan_freq, time);
 			chan_found = true;
 			break;
 		}
@@ -1699,7 +1697,6 @@ void scm_update_last_scan_time_per_channel(struct wlan_objmgr_vdev *vdev,
 		chan_info->ch_scan_info[chan_info->num_chan].last_scan_time =
 									time;
 		chan_info->num_chan++;
-		scm_debug("chan freq %d scan time %u\n", chan_freq, time);
 	}
 }