Jelajahi Sumber

qcacld-3.0: Update roam scan freq list on connection failure

Host sends roam scan offload channel list via WMI_ROAM_CHAN_LIST
to FW after a successful connection.

The host creates a ROAM_SCAN_CHAN list with BSSID entries present
in the scan database. If the connection to an AP fails due to
Auth/Join/Assoc timeout, Host removes the AP entry from the Scan
database, assuming it’s not reachable (to avoid reconnecting to the
AP as it's not responding). Due to this, FW does not include the
frequency(s), for which the connection failed, in roam scan.

Fix is to store the frequency(s) of all the candidates to which the
driver tried connection in the rso config during connect resp failure
and use the same list to update the roam channel list on the top of
entries present in scan db.

Change-Id: I7a4bb3961a64fcf987cb6f2be87b6475363d500a
CRs-Fixed: 3486154
abhinav kumar 1 tahun lalu
induk
melakukan
6f8d32955c

+ 85 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -1913,6 +1913,60 @@ cm_populate_roam_chan_list(struct wlan_objmgr_vdev *vdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+void
+cm_update_tried_candidate_freq_list(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_objmgr_vdev *vdev,
+				    struct wlan_cm_connect_resp *connect_rsp)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+	struct rso_config *rso_cfg;
+	struct wlan_chan_list *tried_freq_list;
+	enum band_info band;
+	uint32_t band_cap;
+
+	if (!connect_rsp->freq || (connect_rsp->reason != CM_JOIN_TIMEOUT &&
+	    connect_rsp->reason != CM_AUTH_TIMEOUT &&
+	    connect_rsp->reason != CM_ASSOC_TIMEOUT))
+		return;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return;
+
+	band_cap = mlme_obj->cfg.gen.band_capability;
+	if (!band_cap) {
+		mlme_err("vdev: %d Invalid band_cap(%d)", connect_rsp->vdev_id,
+			 band_cap);
+		return;
+	}
+
+	band = wlan_reg_band_bitmap_to_band_info(band_cap);
+	if (cm_is_dfs_unsafe_extra_band_chan(vdev, mlme_obj,
+					     connect_rsp->freq, band))
+		return;
+
+	rso_cfg = wlan_cm_get_rso_config(vdev);
+	if (!rso_cfg)
+		return;
+
+	tried_freq_list = &rso_cfg->tried_candidate_freq_list;
+
+	if (tried_freq_list->num_chan >= CFG_VALID_CHANNEL_LIST_LEN)
+		return;
+
+	if (wlan_is_channel_present_in_list(tried_freq_list->freq_list,
+					    tried_freq_list->num_chan,
+					    connect_rsp->freq))
+		return;
+
+	tried_freq_list->freq_list[tried_freq_list->num_chan++] =
+						connect_rsp->freq;
+
+	mlme_debug("vdev: %d added freq:%d, total num freq %d",
+		   connect_rsp->vdev_id, connect_rsp->freq,
+		   tried_freq_list->num_chan);
+}
+
 static QDF_STATUS
 cm_fetch_ch_lst_from_ini(struct wlan_objmgr_vdev *vdev,
 			 struct wlan_mlme_psoc_ext_obj *mlme_obj,
@@ -2111,6 +2165,29 @@ cm_fetch_valid_ch_lst(struct wlan_objmgr_vdev *vdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+static void
+cm_update_rso_freq_list(struct rso_config *rso_cfg,
+			struct wlan_roam_scan_channel_list *chan_info)
+{
+	struct wlan_chan_list *tried_freq_list;
+	uint8_t i;
+
+	tried_freq_list = &rso_cfg->tried_candidate_freq_list;
+
+	if (!tried_freq_list->num_chan)
+		return;
+
+	for (i = 0; i < tried_freq_list->num_chan &&
+	     chan_info->chan_count < CFG_VALID_CHANNEL_LIST_LEN; i++) {
+		if (wlan_is_channel_present_in_list(chan_info->chan_freq_list,
+						chan_info->chan_count,
+						tried_freq_list->freq_list[i]))
+			continue;
+		chan_info->chan_freq_list[chan_info->chan_count++] =
+					tried_freq_list->freq_list[i];
+	}
+}
+
 static void
 cm_fill_rso_channel_list(struct wlan_objmgr_psoc *psoc,
 			 struct wlan_objmgr_vdev *vdev,
@@ -2160,6 +2237,14 @@ cm_fill_rso_channel_list(struct wlan_objmgr_psoc *psoc,
 			 */
 			cm_add_ch_lst_from_roam_scan_list(vdev, mlme_obj,
 							  chan_info, rso_cfg);
+
+			/*
+			 * update the roam channel list on the top of entries
+			 * present in the scan db which gets stored in the rso
+			 * config during connect resp failure in
+			 * wlan_cm_send_connect_rsp
+			 */
+			cm_update_rso_freq_list(rso_cfg, chan_info);
 		}
 	} else {
 		/*

+ 14 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h

@@ -295,6 +295,20 @@ cm_start_roam_invoke(struct wlan_objmgr_psoc *psoc,
 		     enum wlan_cm_source source);
 #endif
 
+/**
+ * cm_update_tried_candidate_freq_list() - on connection failure update
+ * tried_candidate_freq_list structure present in struct rso_config
+ * @psoc: psoc pointer
+ * @vdev: vdev pointer
+ * @connect_rsp: connect resp from VDEV mgr
+ *
+ * Return: void
+ */
+void
+cm_update_tried_candidate_freq_list(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_objmgr_vdev *vdev,
+				    struct wlan_cm_connect_resp *connect_rsp);
+
 #ifdef FEATURE_WLAN_ESE
 /**
  * cm_create_roam_scan_channel_list() - create roam scan channel list

+ 24 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -1062,6 +1062,12 @@ QDF_STATUS cm_connect_start_ind(struct wlan_objmgr_vdev *vdev,
 		rso_cfg->orig_sec_info.mcastcipherset =
 					req->crypto.group_cipher;
 		rso_cfg->orig_sec_info.key_mgmt = req->crypto.akm_suites;
+		/*
+		 * reset the roam channel list entries present in the rso
+		 * config which gets stored during connect resp failure in
+		 * wlan_cm_send_connect_rsp
+		 */
+		rso_cfg->tried_candidate_freq_list.num_chan = 0;
 	}
 
 	if (wlan_get_vendor_ie_ptr_from_oui(HS20_OUI_TYPE,
@@ -1267,6 +1273,24 @@ QDF_STATUS wlan_cm_send_connect_rsp(struct scheduler_msg *msg)
 			wlan_objmgr_peer_release_ref(peer, WLAN_MLME_CM_ID);
 		}
 	}
+
+	/*
+	 * Host creates a ROAM_SCAN_CHAN list with BSSID entries present
+	 * in the scan database. If the connection to an AP fails due to
+	 * Auth/Join/Assoc timeout, Host removes the AP entry from the
+	 * Scan database, assuming it’s not reachable (to avoid
+	 * reconnecting to the AP as it's not responding). Due to this,
+	 * FW does not include the frequency(s), for which the
+	 * connection failed, in roam scan.
+	 * To avoid this, store the frequency(s) of all the candidates
+	 * to which the driver tried connection in the rso config during
+	 * connect resp failure and use the same list to update the roam
+	 * channel list on the top of entries present in scan db.
+	 */
+	if (QDF_IS_STATUS_ERROR(rsp->connect_rsp.connect_status))
+		cm_update_tried_candidate_freq_list(rsp->psoc, vdev,
+						    &rsp->connect_rsp);
+
 	cm_csr_connect_rsp(vdev, rsp);
 	if (rsp->connect_rsp.is_reassoc)
 		status = wlan_cm_reassoc_rsp(vdev, &rsp->connect_rsp);

+ 2 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -572,6 +572,7 @@ struct sae_roam_auth_map {
  * @roam_invoke_source: roam invoke source
  * @roam_invoke_bssid: mac address used for roam invoke
  * @is_forced_roaming: bool value indicating if its forced roaming
+ * @tried_candidate_freq_list: freq list on which connection tried
  */
 struct rso_config {
 #ifdef WLAN_FEATURE_HOST_ROAM
@@ -624,6 +625,7 @@ struct rso_config {
 	enum wlan_cm_source roam_invoke_source;
 	struct qdf_mac_addr roam_invoke_bssid;
 	bool is_forced_roaming;
+	struct wlan_chan_list tried_candidate_freq_list;
 };
 
 /**