Browse Source

qcacld-3.0: Address corner scenarios for dual sta roaming

Address below corner scenarios for dual sta roaming:

1. Initialize primary interface vdev id
with WLAN_UMAC_VDEV_ID_MAX.

2. Enable roaming while processing set primary interface
vendor command irrespective of dual sta roam policy.

3. Disable mcc_adaptive_scheduler before sending
WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID to FW and
enable it if host receives dual sta policy as unbiased.

Change-Id: I8e5254c6f9053bd5fe7f925af4b577e76c9b9a2e
CRs-Fixed: 2928870
abhinav kumar 4 years ago
parent
commit
9ca87d9490

+ 14 - 0
components/mlme/core/src/wlan_mlme_main.c

@@ -2463,6 +2463,19 @@ mlme_init_iot_cfg(struct wlan_objmgr_psoc *psoc,
 	mlme_iot_parse_aggr_info(psoc, iot);
 }
 
+/**
+ * mlme_init_primary_iface - Initialize primary iface
+ *
+ * @gen: Generic CFG config items
+ *
+ * Return: None
+ */
+static void
+mlme_init_primary_iface(struct wlan_mlme_generic *gen)
+{
+	gen->dual_sta_policy.primary_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+}
+
 QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
@@ -2517,6 +2530,7 @@ QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
 	mlme_init_roam_score_config(psoc, mlme_cfg);
 	mlme_init_ratemask_cfg(psoc, &mlme_cfg->ratemask_cfg);
 	mlme_init_iot_cfg(psoc, &mlme_cfg->iot);
+	mlme_init_primary_iface(&mlme_cfg->gen);
 
 	return status;
 }

+ 9 - 0
components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h

@@ -1198,6 +1198,15 @@ QDF_STATUS
 ucfg_mlme_get_roam_bmiss_final_bcnt(struct wlan_objmgr_psoc *psoc,
 				    uint8_t *val);
 
+/**
+ * ucfg_mlme_get_dual_sta_roaming_enabled() - Get dual sta roaming enable flag
+ * @psoc: pointer to psoc object
+ *
+ * Return: true if dual sta roaming allowed in fw
+ */
+bool
+ucfg_mlme_get_dual_sta_roaming_enabled(struct wlan_objmgr_psoc *psoc);
+
 /**
  * ucfg_mlme_get_roam_bmiss_first_bcnt() - Get roam bmiss final count
  * @psoc: pointer to psoc object

+ 5 - 0
components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c

@@ -816,6 +816,11 @@ ucfg_mlme_get_roam_bmiss_final_bcnt(struct wlan_objmgr_psoc *psoc,
 	return wlan_mlme_get_roam_bmiss_final_bcnt(psoc, val);
 }
 
+bool ucfg_mlme_get_dual_sta_roaming_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_mlme_get_dual_sta_roaming_enabled(psoc);
+}
+
 QDF_STATUS
 ucfg_mlme_get_roam_bmiss_first_bcnt(struct wlan_objmgr_psoc *psoc,
 				    uint8_t *val)

+ 16 - 6
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -3108,8 +3108,17 @@ cm_roam_switch_to_deinit(struct wlan_objmgr_pdev *pdev,
 	mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT);
 	mlme_clear_operations_bitmap(psoc, vdev_id);
 
-	if (reason != REASON_SUPPLICANT_INIT_ROAMING)
+	/* In case of roaming getting disabled due to
+	 * REASON_ROAM_SET_PRIMARY reason, don't enable roaming on
+	 * the other vdev as that is taken care by the caller once roaming
+	 * on this "vdev_id" is disabled.
+	 */
+	if (reason != REASON_SUPPLICANT_INIT_ROAMING &&
+	    reason != REASON_ROAM_SET_PRIMARY) {
+	    mlme_debug("enable roaming on connected sta vdev_id:%d, reason:%d",
+		       vdev_id, reason);
 		wlan_cm_enable_roaming_on_connected_sta(pdev, vdev_id);
+	}
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -3190,12 +3199,13 @@ cm_roam_switch_to_init(struct wlan_objmgr_pdev *pdev,
 			 * vdev id if it is not an explicit enable from
 			 * supplicant.
 			 */
-			if (vdev_id == dual_sta_policy->primary_vdev_id &&
-			    dual_sta_policy ==
-			    QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY)
+			mlme_debug("Interface vdev_id: %d, roaming enabled on vdev_id: %d, primary vdev_id:%d, reason:%d",
+				   vdev_id, temp_vdev_id,
+				   dual_sta_policy->primary_vdev_id, reason);
+
+			if (vdev_id == dual_sta_policy->primary_vdev_id)
 				is_vdev_primary = true;
-			mlme_debug("is_vdev_primary: %d, reason:%d",
-				   is_vdev_primary, reason);
+
 			if (is_vdev_primary ||
 			    reason == REASON_SUPPLICANT_INIT_ROAMING) {
 				cm_roam_state_change(pdev, temp_vdev_id,

+ 59 - 17
core/hdd/src/wlan_hdd_cfg80211.c

@@ -8636,6 +8636,7 @@ static int hdd_set_primary_interface(struct hdd_adapter *adapter,
 	uint8_t primary_vdev_id, dual_sta_policy;
 	int set_value;
 	uint32_t count;
+	bool enable_mcc_adaptive_sch = false;
 
 	/* ignore unless in STA mode */
 	if (adapter->device_mode != QDF_STA_MODE)
@@ -8643,8 +8644,8 @@ static int hdd_set_primary_interface(struct hdd_adapter *adapter,
 
 	is_set_primary_iface = nla_get_u8(attr);
 
-	primary_vdev_id = is_set_primary_iface ? adapter->vdev_id : WLAN_UMAC_VDEV_ID_MAX;
-	hdd_debug("Primary interface: %d", primary_vdev_id);
+	primary_vdev_id =
+		is_set_primary_iface ? adapter->vdev_id : WLAN_UMAC_VDEV_ID_MAX;
 
 	status = ucfg_mlme_set_primary_interface(hdd_ctx->psoc,
 						 primary_vdev_id);
@@ -8653,15 +8654,39 @@ static int hdd_set_primary_interface(struct hdd_adapter *adapter,
 		return -EINVAL;
 	}
 
+	count = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
+							  PM_STA_MODE, NULL);
+
+	if (count != 2) {
+		hdd_debug("STA + STA concurrency not present, count:%d", count);
+		return -EINVAL;
+	}
+
+	/* if dual sta roaming enabled and both sta in DBS then no need
+	 * to enable roaming on primary as both STA's have roaming enabled.
+	 * if dual sta roaming enabled and both sta in MCC then need to enable
+	 * roaming on primary vdev.
+	 * if dual sta roaming NOT enabled then need to enable roaming on
+	 * primary vdev for dual STA concurrency in MCC or DBS.
+	 */
+	if ((is_set_primary_iface &&
+	     ucfg_mlme_get_dual_sta_roaming_enabled(hdd_ctx->psoc) &&
+	     policy_mgr_current_concurrency_is_mcc(hdd_ctx->psoc)) ||
+	    (is_set_primary_iface &&
+	     !ucfg_mlme_get_dual_sta_roaming_enabled(hdd_ctx->psoc))){
+		hdd_debug("Enable roaming on requested interface: %d",
+			  adapter->vdev_id);
+		wlan_cm_roam_state_change(hdd_ctx->pdev, adapter->vdev_id,
+					  WLAN_ROAM_RSO_ENABLED,
+					  REASON_ROAM_SET_PRIMARY);
+	}
+
 	/*
 	 * send duty cycle percentage to FW only if STA + STA
 	 * concurrency is in MCC.
 	 */
-	count = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
-							  PM_STA_MODE, NULL);
-	if (count != 2 &&
-	    !policy_mgr_current_concurrency_is_mcc(hdd_ctx->psoc)) {
-		hdd_debug("STA + STA concurrency is in MCC not present");
+	if (!policy_mgr_current_concurrency_is_mcc(hdd_ctx->psoc)) {
+		hdd_debug("STA + STA concurrency not in MCC");
 		return -EINVAL;
 	}
 
@@ -8671,25 +8696,42 @@ static int hdd_set_primary_interface(struct hdd_adapter *adapter,
 		return -EINVAL;
 	}
 
+	hdd_debug("is_set_primary_iface: %d, primary vdev id: %d, dual_sta_policy:%d",
+		  is_set_primary_iface, primary_vdev_id, dual_sta_policy);
+
 	if (is_set_primary_iface && dual_sta_policy ==
 	    QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY) {
+		hdd_debug("Disable mcc_adaptive_scheduler");
+		ucfg_policy_mgr_get_mcc_adaptive_sch(hdd_ctx->psoc,
+						     &enable_mcc_adaptive_sch);
+		if (enable_mcc_adaptive_sch) {
+			ucfg_policy_mgr_set_dynamic_mcc_adaptive_sch(
+							hdd_ctx->psoc, false);
+			if (QDF_IS_STATUS_ERROR(sme_set_mas(false))) {
+				hdd_err("Fail to disable mcc adaptive sched.");
+					return -EINVAL;
+			}
+		}
+		/* Configure mcc duty cycle percentage */
 		set_value =
 		   ucfg_mlme_get_mcc_duty_cycle_percentage(hdd_ctx->pdev);
 		if (set_value < 0) {
 			hdd_err("Invalid mcc duty cycle");
 			return -EINVAL;
 		}
-
-		if (QDF_IS_STATUS_ERROR(sme_set_mas(false))) {
-			hdd_err("Failed to disable mcc_adaptive_scheduler");
-				return -EINVAL;
-		}
-
 		wlan_hdd_send_mcc_vdev_quota(adapter, set_value);
-		/* Enable roaming on requested interface */
-		wlan_cm_roam_state_change(hdd_ctx->pdev, adapter->vdev_id,
-					  WLAN_ROAM_RSO_ENABLED,
-					  REASON_ROAM_SET_PRIMARY);
+	} else {
+		hdd_debug("Enable mcc_adaptive_scheduler");
+		ucfg_policy_mgr_get_mcc_adaptive_sch(hdd_ctx->psoc,
+						     &enable_mcc_adaptive_sch);
+		if (enable_mcc_adaptive_sch) {
+			ucfg_policy_mgr_set_dynamic_mcc_adaptive_sch(
+							hdd_ctx->psoc, true);
+			if (QDF_STATUS_SUCCESS != sme_set_mas(true)) {
+				hdd_err("Fail to enable mcc_adaptive_sched.");
+				return -EAGAIN;
+			}
+		}
 	}
 
 	return 0;

+ 30 - 2
core/sme/src/csr/csr_api_roam.c

@@ -12694,6 +12694,7 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 	int32_t rsn_cap, set_value;
 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
 	struct dual_sta_policy *dual_sta_policy;
+	bool enable_mcc_adaptive_sch = false;
 
 	/*
 	 * This API is to update legacy struct and should be removed once
@@ -12725,16 +12726,43 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 	 * send duty cycle percentage to FW only if STA + STA
 	 * concurrency is in MCC.
 	 */
+	sme_debug("Current iface vdev_id:%d, Primary vdev_id:%d, Dual sta policy:%d, count:%d",
+		  vdev_id, dual_sta_policy->primary_vdev_id,
+		  dual_sta_policy->concurrent_sta_policy, count);
+
 	if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX &&
 	    dual_sta_policy->concurrent_sta_policy ==
 	    QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY && count == 2 &&
 	    policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) {
-		if (QDF_IS_STATUS_ERROR(sme_set_mas(false)))
-			sme_err("Failed to disable mcc_adaptive_scheduler");
+		policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc,
+						&enable_mcc_adaptive_sch);
+		if (enable_mcc_adaptive_sch) {
+			sme_debug("Disable mcc_adaptive_scheduler");
+			policy_mgr_set_dynamic_mcc_adaptive_sch(
+							mac_ctx->psoc, false);
+			if (QDF_STATUS_SUCCESS != sme_set_mas(false)) {
+				sme_err("Failed to disable mcc_adaptive_sched");
+				return -EAGAIN;
+			}
+		}
 		set_value =
 			wlan_mlme_get_mcc_duty_cycle_percentage(mac_ctx->pdev);
 		sme_cli_set_command(vdev_id, WMA_VDEV_MCC_SET_TIME_QUOTA,
 				    set_value, VDEV_CMD);
+	  } else if (dual_sta_policy->concurrent_sta_policy ==
+		     QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED && count == 2 &&
+		     policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) {
+		policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc,
+						&enable_mcc_adaptive_sch);
+		if (enable_mcc_adaptive_sch) {
+			sme_debug("Enable mcc_adaptive_scheduler");
+			policy_mgr_set_dynamic_mcc_adaptive_sch(
+						  mac_ctx->psoc, true);
+			if (QDF_STATUS_SUCCESS != sme_set_mas(true)) {
+				sme_err("Failed to enable mcc_adaptive_sched");
+				return -EAGAIN;
+			}
+		}
 	}
 
 	/*