فهرست منبع

qcacmn: Overide blacklist and connect to AP

Currently the connection manager queries the
blacklist manager about the action to be taken
and if all the candidates of a certain SSID are
blacklisted then the connection would be rejected.
There are various types of blacklisting, some
can be overridden and some have to be strictly
followed.

Fix is to overide the blacklist candidate and
connect to it if no other candidates are suitable
for connection.

Change-Id: I84358df5f94d4c82989bf81412355f312320dc0b
Crs-Fixed: 2825519
gaurank kathpalia 4 سال پیش
والد
کامیت
80cf078dab

+ 59 - 6
umac/mlme/connection_mgr/core/src/wlan_cm_bss_scoring.c

@@ -1665,6 +1665,8 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 	enum cm_blacklist_action blacklist_action;
 	struct wlan_objmgr_psoc *psoc;
 	bool assoc_allowed;
+	struct scan_cache_node *force_connect_candidate = NULL;
+	bool are_all_candidate_blacklisted = true;
 
 	psoc = wlan_pdev_get_psoc(pdev);
 
@@ -1710,7 +1712,11 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 			blacklist_action = wlan_blacklist_action_on_bssid(pdev,
 							scan_entry->entry);
 		else
-			blacklist_action = CM_BLM_REMOVE;
+			blacklist_action = CM_BLM_FORCE_REMOVE;
+
+		if (blacklist_action == CM_BLM_NO_ACTION ||
+		    blacklist_action == CM_BLM_AVOID)
+			are_all_candidate_blacklisted = false;
 
 		if (blacklist_action == CM_BLM_NO_ACTION &&
 		    pcl_lst && pcl_lst->num_of_pcl_channels &&
@@ -1725,7 +1731,8 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 			}
 		}
 
-		if (blacklist_action == CM_BLM_NO_ACTION) {
+		if (blacklist_action == CM_BLM_NO_ACTION ||
+		    (are_all_candidate_blacklisted && blacklist_action == CM_BLM_REMOVE)) {
 			cm_calculate_bss_score(psoc, scan_entry->entry,
 					       pcl_chan_weight, bssid_hint);
 		} else if (blacklist_action == CM_BLM_AVOID) {
@@ -1739,7 +1746,40 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 					scan_entry->entry->bss_score);
 		}
 
-		/* Remove node from current locaion to add node back shorted */
+		/*
+		 * The below logic is added to select the best candidate
+		 * amongst the blacklisted candidates. This is done to
+		 * handle a case where all the BSSIDs become blacklisted
+		 * and hence there are continuous connection failures.
+		 * With the below logic if the action on BSSID is to remove
+		 * then we keep a backup node and restore the candidate
+		 * list.
+		 */
+		if (blacklist_action == CM_BLM_REMOVE &&
+		    are_all_candidate_blacklisted) {
+			if (!force_connect_candidate) {
+				force_connect_candidate =
+					qdf_mem_malloc(
+					   sizeof(*force_connect_candidate));
+				if (!force_connect_candidate)
+					return;
+				force_connect_candidate->entry =
+					util_scan_copy_cache_entry(scan_entry->entry);
+				if (!force_connect_candidate->entry)
+					return;
+			} else if (cm_is_better_bss(
+				   scan_entry->entry,
+				   force_connect_candidate->entry)) {
+				util_scan_free_cache_entry(
+					force_connect_candidate->entry);
+				force_connect_candidate->entry =
+				  util_scan_copy_cache_entry(scan_entry->entry);
+				if (!force_connect_candidate->entry)
+					return;
+			}
+		}
+
+		/* Remove node from current location to add node back sorted */
 		status = qdf_list_remove_node(scan_list, cur_node);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			mlme_err("failed to remove node for BSS "QDF_MAC_ADDR_FMT" from scan list",
@@ -1751,12 +1791,14 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 		 * If CM_BLM_REMOVE ie blacklisted or assoc not allowed then
 		 * free the entry else add back to the list sorted
 		 */
-		if (blacklist_action == CM_BLM_REMOVE) {
+		if (blacklist_action == CM_BLM_REMOVE ||
+		    blacklist_action == CM_BLM_FORCE_REMOVE) {
 			if (assoc_allowed)
-				mlme_nofl_debug("Candidate("QDF_MAC_ADDR_FMT" freq %d): rssi %d, is in Blacklist, remove entry",
+				mlme_nofl_debug("Candidate("QDF_MAC_ADDR_FMT" freq %d): rssi %d, blm action %d is in Blacklist, remove entry",
 					QDF_MAC_ADDR_REF(scan_entry->entry->bssid.bytes),
 					scan_entry->entry->channel.chan_freq,
-					scan_entry->entry->rssi_raw);
+					scan_entry->entry->rssi_raw,
+					blacklist_action);
 			util_scan_free_cache_entry(scan_entry->entry);
 			qdf_mem_free(scan_entry);
 		} else {
@@ -1766,6 +1808,17 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 		cur_node = next_node;
 		next_node = NULL;
 	}
+
+	if (are_all_candidate_blacklisted && force_connect_candidate) {
+		mlme_nofl_debug("All candidates in blacklist, Candidate("QDF_MAC_ADDR_FMT" freq %d): rssi %d, selected for connection",
+			QDF_MAC_ADDR_REF(force_connect_candidate->entry->bssid.bytes),
+			force_connect_candidate->entry->channel.chan_freq,
+			force_connect_candidate->entry->rssi_raw);
+		cm_list_insert_sorted(scan_list, force_connect_candidate);
+	} else if (force_connect_candidate) {
+		util_scan_free_cache_entry(force_connect_candidate->entry);
+		qdf_mem_free(force_connect_candidate);
+	}
 }
 
 #ifdef CONFIG_BAND_6GHZ

+ 9 - 0
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_bss_score_param.h

@@ -162,11 +162,20 @@ struct pcl_freq_weight_list {
  * enum cm_blacklist_action - action taken by blacklist manager for the bssid
  * @CM_BLM_NO_ACTION: No operation to be taken for the BSSID in the scan list.
  * @CM_BLM_REMOVE: Remove the BSSID from the scan list (AP is blacklisted)
+ * This param is a way to inform the caller that this BSSID is blacklisted
+ * but it is a driver blacklist and we can connect to them if required.
+ * @CM_BLM_FORCE_REMOVE: Forcefully remove the BSSID from scan list.
+ * This param is introduced as we want to differentiate between optional
+ * mandatory blacklisting. Driver blacklisting is optional and won't
+ * fail any CERT or protocol violations as it is internal implementation.
+ * hence FORCE_REMOVE will mean that driver cannot connect to this BSSID
+ * in any situation.
  * @CM_BLM_AVOID: Add the Ap at last of the scan list (AP to Avoid)
  */
 enum cm_blacklist_action {
 	CM_BLM_NO_ACTION,
 	CM_BLM_REMOVE,
+	CM_BLM_FORCE_REMOVE,
 	CM_BLM_AVOID,
 };