Browse Source

qcacld-3.0: Send no force cmd before setting hybrid mode in FW

Once Host sends force link bitmap command to FW, subsequent
force link num command can’t take effect as force link bitmap
command has the highest priority.

Fix is to send no force cmd before setting hybrid mode in FW.

Change-Id: Iac3e1fe66c9b808b82f6b4feb66f90e169e4897b
CRs-Fixed: 3596656
Abhinav Kumar 1 year ago
parent
commit
bbe12b80ad

+ 38 - 6
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -4180,17 +4180,24 @@ policy_mgr_enable_disable_link_from_vdev_bitmask(struct wlan_objmgr_psoc *psoc,
 
 static void
 policy_mgr_set_link_in_progress(struct policy_mgr_psoc_priv_obj *pm_ctx,
-				bool value)
+				bool set_link_in_progress)
 {
 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
-	pm_ctx->set_link_in_progress = value;
+	if (set_link_in_progress)
+		qdf_atomic_inc(&pm_ctx->link_in_progress);
+	else {
+		if (qdf_atomic_read(&pm_ctx->link_in_progress) > 0)
+			qdf_atomic_dec(&pm_ctx->link_in_progress);
+	}
+
 	/* if set link has started reset the event, else complete the event */
-	if (pm_ctx->set_link_in_progress)
+	if (qdf_atomic_read(&pm_ctx->link_in_progress))
 		qdf_event_reset(&pm_ctx->set_link_update_done_evt);
 	else
 		qdf_event_set(&pm_ctx->set_link_update_done_evt);
-	policy_mgr_debug("set_link_in_progress %d",
-			 pm_ctx->set_link_in_progress);
+
+	policy_mgr_debug("link_in_progress %d",
+			 qdf_atomic_read(&pm_ctx->link_in_progress));
 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
 }
 
@@ -4200,7 +4207,7 @@ policy_mgr_get_link_in_progress(struct policy_mgr_psoc_priv_obj *pm_ctx)
 	bool value;
 
 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
-	value = pm_ctx->set_link_in_progress;
+	value = qdf_atomic_read(&pm_ctx->link_in_progress);
 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
 	if (value)
 		policy_mgr_debug("set_link_in_progress %d", value);
@@ -8786,6 +8793,31 @@ QDF_STATUS policy_mgr_update_active_mlo_num_links(struct wlan_objmgr_psoc *psoc,
 	}
 
 set_link:
+	/*
+	 * TODO: In all scenarios wherever host sends
+	 * MLO_LINK_FORCE_MODE_ACTIVE_NUM/MLO_LINK_FORCE_MODE_INACTIVE_NUM to
+	 * FW, Host need to send MLO_LINK_FORCE_MODE_NO_FORCE to FW.
+	 * So instead of two commands for serialization, take care of this in
+	 * single serialization active command.
+	 */
+
+	/*
+	 * send MLO_LINK_FORCE_MODE_NO_FORCE to FW to clear user mode setting
+	 * configured via QCA_WLAN_VENDOR_ATTR_LINK_STATE_CONTROL_MODE in FW
+	 */
+	status = policy_mgr_mlo_sta_set_link(psoc,
+				    MLO_LINK_FORCE_REASON_CONNECT,
+				    MLO_LINK_FORCE_MODE_NO_FORCE,
+				    num_ml_sta, ml_sta_vdev_lst);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_debug("fail to send no force cmd for num_links:%d",
+				 num_ml_sta);
+		goto release_vdev_ref;
+	} else {
+		policy_mgr_debug("clear force mode setting for num_links:%d",
+				 num_ml_sta);
+	}
+
 	status = policy_mgr_process_mlo_sta_dynamic_force_num_link(psoc,
 					     MLO_LINK_FORCE_REASON_CONNECT,
 					     MLO_LINK_FORCE_MODE_ACTIVE_NUM,

+ 2 - 2
components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -377,7 +377,7 @@ struct policy_mgr_cfg {
  * @valid_ch_freq_list_count: number of valid frequencies
  * @dynamic_mcc_adaptive_sched: disable/enable mcc adaptive scheduler feature
  * @dynamic_dfs_master_disabled: current state of dynamic dfs master
- * @set_link_in_progress: To track if set link is in progress
+ * @link_in_progress: To track if set link is in progress
  * @set_link_update_done_evt: qdf event to synchronize set link
  * @active_vdev_bitmap: Active vdev id bitmap
  * @inactive_vdev_bitmap: Inactive vdev id bitmap
@@ -426,7 +426,7 @@ struct policy_mgr_psoc_priv_obj {
 	bool dynamic_mcc_adaptive_sched;
 	bool dynamic_dfs_master_disabled;
 #ifdef WLAN_FEATURE_11BE_MLO
-	bool set_link_in_progress;
+	qdf_atomic_t link_in_progress;
 	qdf_event_t set_link_update_done_evt;
 #endif
 	uint32_t active_vdev_bitmap;

+ 2 - 2
components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -492,7 +492,7 @@ policy_mgr_init_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
 {
 	QDF_STATUS qdf_status;
 
-	pm_ctx->set_link_in_progress = false;
+	qdf_atomic_init(&pm_ctx->link_in_progress);
 	qdf_status = qdf_event_create(&pm_ctx->set_link_update_done_evt);
 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
 		policy_mgr_err("init event failed for for set_link_update_done_evt");
@@ -507,7 +507,7 @@ policy_mgr_deinit_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
 {
 	QDF_STATUS qdf_status;
 
-	pm_ctx->set_link_in_progress = false;
+	qdf_atomic_set(&pm_ctx->link_in_progress, 0);
 	qdf_status = qdf_event_destroy(&pm_ctx->set_link_update_done_evt);
 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
 		policy_mgr_err("deinit event failed for set_link_update_done_evt");

+ 6 - 0
core/hdd/src/wlan_hdd_mlo.c

@@ -896,6 +896,12 @@ int wlan_handle_mlo_link_state_operation(struct wiphy *wiphy,
 	case QCA_WLAN_VENDOR_LINK_STATE_OP_GET:
 		return wlan_hdd_link_state_request(wiphy, hdd_ctx->psoc, vdev);
 	case QCA_WLAN_VENDOR_LINK_STATE_OP_SET:
+		if (policy_mgr_is_set_link_in_progress(hdd_ctx->psoc)) {
+			hdd_debug("vdev %d: change link already in progress",
+				  vdev_id);
+			return -EBUSY;
+		}
+
 		break;
 	default:
 		hdd_debug("vdev %d: Invalid op type:%d", vdev_id, ml_link_op);