Browse Source

qcacld-3.0: Send correct PCL to fw for STA+STA roaming

STA + STA DBS roaming rules are:
1. Roaming will be enabled on both interfaces.
2. Roaming bands are restricted to maintain only DBS.

While STA2 connection, the host sets VDEV level PCL for
vdev1 after association completion only and initializes
roam band mask after the 4-way handshake. So, when sending
PCL to FW value of roam band mask is 0, the host cannot
filter different band channels from STA2's PCL list.
This allows STA2 to roam to the different bands and violate
rule 2.

Fix is to make sure roaming bands are restricted to maintain
only DBS.

Change-Id: I1c9d2edb34f59e00c2fd14ea7894c324f9c64047
CRs-Fixed: 3075106
abhinav kumar 3 years ago
parent
commit
70d9da5b2c

+ 29 - 20
components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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
@@ -1646,7 +1647,7 @@ policy_mgr_get_connected_roaming_vdev_band_mask(struct wlan_objmgr_psoc *psoc,
 {
 	uint32_t band_mask;
 	struct wlan_objmgr_vdev *vdev;
-	bool dual_sta_roam_active;
+	bool dual_sta_roam_active, is_pcl_per_vdev;
 	struct wlan_channel *chan;
 	uint32_t roam_band_mask;
 
@@ -1658,38 +1659,49 @@ policy_mgr_get_connected_roaming_vdev_band_mask(struct wlan_objmgr_psoc *psoc,
 	}
 
 	chan = wlan_vdev_get_active_channel(vdev);
-
-	ucfg_reg_get_band(wlan_vdev_get_pdev(vdev), &band_mask);
-	roam_band_mask = wlan_cm_get_roam_band_value(psoc, vdev);
-
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
 	if (!chan) {
 		policy_mgr_err("no active channel");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
 		return 0;
 	}
 
+	is_pcl_per_vdev = wlan_cm_roam_is_pcl_per_vdev_active(psoc, vdev_id);
+	dual_sta_roam_active = wlan_mlme_get_dual_sta_roaming_enabled(psoc);
+
+	policy_mgr_debug("connected STA (vdev_id:%d, freq:%d), pcl_per_vdev:%d, dual_sta_roam_active:%d",
+			 vdev_id, chan->ch_freq, is_pcl_per_vdev,
+			 dual_sta_roam_active);
+
+	if (dual_sta_roam_active && is_pcl_per_vdev) {
+		band_mask = BIT(wlan_reg_freq_to_band(chan->ch_freq));
+		policy_mgr_debug("connected vdev band mask:%d", band_mask);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return band_mask;
+	}
+
 	/*
 	 * if vendor command to configure roam band is set , we will
 	 * take this as priority instead of drv cmd "SETROAMINTRABAND" or
 	 * active connection band.
 	 */
-	if (roam_band_mask != band_mask)
-		return roam_band_mask;
+	ucfg_reg_get_band(wlan_vdev_get_pdev(vdev), &band_mask);
+	roam_band_mask = wlan_cm_get_roam_band_value(psoc, vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
 
+	if (roam_band_mask != band_mask) {
+		policy_mgr_debug("roam_band_mask:%d", roam_band_mask);
+		return roam_band_mask;
+	}
 	/*
 	 * If PCL command is PDEV level, only one sta is active.
 	 * So fill the band mask if intra band roaming is enabled
 	 */
-	if (!wlan_cm_roam_is_pcl_per_vdev_active(psoc, vdev_id)) {
-		if (ucfg_mlme_is_roam_intra_band(psoc))
+	if (!is_pcl_per_vdev)
+		if (ucfg_mlme_is_roam_intra_band(psoc)) {
 			band_mask = BIT(wlan_reg_freq_to_band(chan->ch_freq));
-
-		return band_mask;
-	}
-
-	dual_sta_roam_active = wlan_mlme_get_dual_sta_roaming_enabled(psoc);
-	if (dual_sta_roam_active)
-		band_mask = BIT(wlan_reg_freq_to_band(chan->ch_freq));
+			policy_mgr_debug("connected STA band mask:%d",
+					 band_mask);
+		}
 
 	return band_mask;
 }
@@ -1720,9 +1732,6 @@ QDF_STATUS policy_mgr_set_pcl(struct wlan_objmgr_psoc *psoc,
 
 	req_msg->band_mask =
 		policy_mgr_get_connected_roaming_vdev_band_mask(psoc, vdev_id);
-	policy_mgr_debug("RSO_CFG: vdev:%d Connected STA band_mask:%d",
-			 vdev_id, req_msg->band_mask);
-
 	for (i = 0; i < msg->pcl_len; i++) {
 		req_msg->chan_weights.pcl_list[i] =  msg->pcl_list[i];
 		req_msg->chan_weights.weight_list[i] =  msg->weight_list[i];

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

@@ -4671,7 +4671,6 @@ static void cm_roam_start_init(struct wlan_objmgr_psoc *psoc,
 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
 	enum QDF_OPMODE opmode;
-	uint32_t current_band;
 
 	opmode = wlan_vdev_mlme_get_opmode(vdev);
 	if (opmode != QDF_STA_MODE) {
@@ -4699,8 +4698,6 @@ static void cm_roam_start_init(struct wlan_objmgr_psoc *psoc,
 					       DEFAULT_ROAM_SCAN_SCHEME_BITMAP);
 	wlan_cm_roam_cfg_get_value(psoc, vdev_id,
 				   MOBILITY_DOMAIN, &src_cfg);
-	ucfg_reg_get_band(pdev, &current_band);
-	wlan_cm_set_roam_band_bitmask(psoc, vdev_id, current_band);
 
 	mdie_present = src_cfg.bool_value;
 	/* Based on the auth scheme tell if we are 11r */

+ 4 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -1464,6 +1464,7 @@ QDF_STATUS wlan_cm_rso_config_init(struct wlan_objmgr_vdev *vdev,
 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
 	struct wlan_objmgr_pdev *pdev;
 	struct wlan_objmgr_psoc *psoc;
+	uint32_t current_band = REG_BAND_MASK_ALL;
 
 	pdev = wlan_vdev_get_pdev(vdev);
 	if (!pdev)
@@ -1559,6 +1560,9 @@ QDF_STATUS wlan_cm_rso_config_init(struct wlan_objmgr_vdev *vdev,
 	cfg_params->bg_rssi_threshold =
 		mlme_obj->cfg.lfr.bg_rssi_threshold;
 
+	ucfg_reg_get_band(wlan_vdev_get_pdev(vdev), &current_band);
+	rso_cfg->roam_band_bitmask = current_band;
+
 	return status;
 }