Bladeren bron

qcacld-3.0: Add disable ml link infra in policy manager

Add disabled links table and APIs to move and remove
vdevs from disabled links table.

Change-Id: I610bbd10e387a4bcd3a5d5c88c3dba5698878441
CRs-Fixed: 3181474
Abhishek Singh 3 jaren geleden
bovenliggende
commit
f0ccd97d61

+ 68 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -994,6 +994,74 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc,
 void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc,
 		enum QDF_OPMODE mode, uint8_t session_id);
 
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * policy_mgr_is_mlo_vdev_id() - check if vdev id is part of ML
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id to check
+ *
+ * Return: true if vdev is part of ml
+ */
+bool policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_disabled_ml_links_count() - provides the count of
+ * disabled ml links
+ * @psoc: PSOC object information
+ *
+ * This function provides the count of disabled ml links
+ *
+ * Return: disabled ml links count
+ */
+uint32_t policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_move_vdev_from_disabled_to_connection_tbl() - re-enable a ml link
+ * and move it from disabled link table to pm_conc_connection_list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void policy_mgr_move_vdev_from_disabled_to_connection_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+
+/**
+ * policy_mgr_move_vdev_from_connection_to_disabled_tbl() - Add/move the link
+ * vdev to disable a ml link table
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void policy_mgr_move_vdev_from_connection_to_disabled_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+#else
+static inline bool
+policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	return false;
+}
+
+static inline uint32_t
+policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline void
+policy_mgr_move_vdev_from_disabled_to_connection_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id) {}
+
+static inline void
+policy_mgr_move_vdev_from_connection_to_disabled_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id) {}
+#endif
+
 /**
  * policy_mgr_skip_dfs_ch() - skip dfs channel or not
  * @psoc: pointer to soc

+ 22 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h

@@ -64,6 +64,11 @@
 #define MAX_NUMBER_OF_CONC_CONNECTIONS 3
 #endif
 
+#ifdef WLAN_FEATURE_11BE_MLO
+/* Max MLO VDEVS - 1 as all vdevs cannot be disabled */
+#define MAX_NUMBER_OF_DISABLE_LINK WLAN_UMAC_MLO_MAX_VDEVS - 1
+#endif
+
 /* Policy manager default request id */
 #define POLICY_MGR_DEF_REQ_ID 0
 
@@ -1229,6 +1234,23 @@ struct policy_mgr_conc_connection_info {
 	enum conn_6ghz_flag conn_6ghz_flag;
 };
 
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * struct policy_mgr_disabled_ml_link_info - information of all existing
+ * disabled ml link
+ * @in_use: if the table entry is active
+ * @mode: connection type
+ * @freq: Channel frequency
+ * @vdev_id: vdev id of the connection
+ */
+struct policy_mgr_disabled_ml_link_info {
+	bool in_use;
+	enum policy_mgr_con_mode mode;
+	qdf_freq_t freq;
+	uint8_t vdev_id;
+};
+#endif
+
 /**
  * struct policy_mgr_hw_mode_params - HW mode params
  * @mac0_tx_ss: MAC0 Tx spatial stream

+ 30 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -50,6 +50,11 @@ static const uint16_t sap_mand_5g_freq_list[] = {5745, 5765, 5785, 5805};
 struct policy_mgr_conc_connection_info
 	pm_conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
 
+#ifdef WLAN_FEATURE_11BE_MLO
+struct policy_mgr_disabled_ml_link_info
+	pm_disabled_ml_links[MAX_NUMBER_OF_DISABLE_LINK];
+#endif
+
 struct policy_mgr_psoc_priv_obj *policy_mgr_get_context(
 		struct wlan_objmgr_psoc *psoc)
 {
@@ -1462,6 +1467,30 @@ static void policy_mgr_dump_sbs_concurrency(struct wlan_objmgr_psoc *psoc,
 	policy_mgr_dump_dual_mac_concurrency(pm_ctx, cc_mode, length);
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+void
+policy_mgr_dump_disabled_ml_links(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	uint8_t buf[POLICY_MGR_MAX_CON_STRING_LEN] = {0};
+	uint32_t len = 0, count = 0, i;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (pm_disabled_ml_links[i].in_use) {
+			len += qdf_scnprintf(buf + len,
+					    POLICY_MGR_MAX_CON_STRING_LEN - len,
+					    "vdev %d :Mode %d freq %d, ",
+					    pm_disabled_ml_links[i].vdev_id,
+					    pm_disabled_ml_links[i].mode,
+					    pm_disabled_ml_links[i].freq);
+			count++;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_debug("Disabled links(%d): %s", count, buf);
+}
+#endif
+
 /**
  * policy_mgr_dump_current_concurrency() - To dump the current
  * concurrency combination
@@ -1542,6 +1571,7 @@ void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc)
 				 num_connections);
 		break;
 	}
+	policy_mgr_dump_disabled_ml_links(pm_ctx);
 
 	return;
 }

+ 194 - 1
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -3047,6 +3047,192 @@ policy_mgr_validate_conn_info(struct wlan_objmgr_psoc *psoc)
 	return panic;
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+bool policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	bool is_mlo = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev)
+		return is_mlo;
+
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
+		is_mlo = true;
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return is_mlo;
+}
+
+uint32_t policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t i, count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm_ctx");
+		return count;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (pm_disabled_ml_links[i].in_use)
+			count++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+static QDF_STATUS
+policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				      uint8_t vdev_id)
+{
+	int i;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (pm_disabled_ml_links[i].in_use &&
+		    pm_disabled_ml_links[i].vdev_id == vdev_id) {
+			pm_disabled_ml_links[i].in_use = false;
+			policy_mgr_debug("Disabled link removed for vdev %d",
+					 vdev_id);
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	/* Return failure if not found */
+	if (i >= MAX_NUMBER_OF_DISABLE_LINK)
+		return QDF_STATUS_E_EXISTS;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_move_vdev_from_disabled_to_connection_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status;
+	enum QDF_OPMODE mode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm_ctx");
+		return;
+	}
+	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+	if (mode != QDF_STA_MODE) {
+		policy_mgr_err("vdev %d opmode %d is not STA", vdev_id, mode);
+		return;
+	}
+
+	if (!policy_mgr_is_ml_vdev_id(psoc, vdev_id)) {
+		policy_mgr_err("vdev %d is not ML", vdev_id);
+		return;
+	}
+
+	status = policy_mgr_delete_from_disabled_links(pm_ctx, vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Disabled link not found for vdev %d", vdev_id);
+		return;
+	}
+
+	/*
+	 * Add entry to pm_conc_connection_list if remove from disabled links
+	 * was success
+	 */
+	policy_mgr_incr_active_session(psoc, mode, vdev_id);
+}
+
+static QDF_STATUS
+policy_mgr_add_to_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				 qdf_freq_t freq, enum QDF_OPMODE mode,
+				 uint8_t vdev_id)
+{
+	int i;
+	enum policy_mgr_con_mode pm_mode;
+
+	pm_mode = policy_mgr_convert_device_mode_to_qdf_type(mode);
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (pm_disabled_ml_links[i].in_use &&
+		    pm_disabled_ml_links[i].vdev_id == vdev_id)
+			break;
+	}
+
+	if (i < MAX_NUMBER_OF_DISABLE_LINK) {
+		pm_disabled_ml_links[i].freq = freq;
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		policy_mgr_info("Disabled link already present vdev_id %d, update freq %d",
+				vdev_id, freq);
+
+		return QDF_STATUS_E_EXISTS;
+	}
+
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (!pm_disabled_ml_links[i].in_use) {
+			/* add in empty place */
+			pm_disabled_ml_links[i].vdev_id = vdev_id;
+			pm_disabled_ml_links[i].mode = pm_mode;
+			pm_disabled_ml_links[i].in_use = true;
+			pm_disabled_ml_links[i].freq = freq;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (i >= MAX_NUMBER_OF_DISABLE_LINK) {
+		policy_mgr_err("No empty entry found to disable link for vdev %d",
+			       vdev_id);
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_move_vdev_from_connection_to_disabled_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	qdf_freq_t freq;
+	enum QDF_OPMODE mode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm_ctx");
+		return;
+	}
+
+	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+	if (mode != QDF_STA_MODE) {
+		policy_mgr_err("vdev %d opmode %d is not STA", vdev_id, mode);
+		return;
+	}
+
+	if (!policy_mgr_is_ml_vdev_id(psoc, vdev_id)) {
+		policy_mgr_err("vdev %d is not ML", vdev_id);
+		return;
+	}
+	freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id);
+	/* Remove entry if present in pm_conc_connection_list */
+	policy_mgr_decr_session_set_pcl(psoc, mode, vdev_id);
+
+	policy_mgr_add_to_disabled_links(pm_ctx, freq, mode, vdev_id);
+}
+#else
+static inline QDF_STATUS
+policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				      uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc,
 				enum QDF_OPMODE mode,
 				uint8_t session_id)
@@ -3240,10 +3426,16 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc,
 	qdf_status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc,
 			policy_mgr_convert_device_mode_to_qdf_type(mode),
 			session_id);
-	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
 		policy_mgr_debug("No connection with mode:%d vdev_id:%d",
 			policy_mgr_convert_device_mode_to_qdf_type(mode),
 			session_id);
+		/*
+		 * In case of disconnect try delete the link from disabled link
+		 * as well, if its not present in pm_conc_connection_list,
+		 * it can be present in pm_disabled_ml_links.
+		 */
+		policy_mgr_delete_from_disabled_links(pm_ctx, session_id);
 		return qdf_status;
 	}
 
@@ -5734,6 +5926,7 @@ void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc)
 				 pm_conc_connection_list[i].ch_flagext);
 	}
 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_dump_disabled_ml_links(pm_ctx);
 
 	policy_mgr_dump_freq_range(pm_ctx);
 	policy_mgr_validate_conn_info(psoc);

+ 14 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -193,6 +193,11 @@
 extern struct policy_mgr_conc_connection_info
 	pm_conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
 
+#ifdef WLAN_FEATURE_11BE_MLO
+extern struct policy_mgr_disabled_ml_link_info
+	pm_disabled_ml_links[MAX_NUMBER_OF_DISABLE_LINK];
+#endif
+
 extern const enum policy_mgr_pcl_type
 	first_connection_pcl_table[PM_MAX_NUM_OF_MODE]
 			[PM_MAX_CONC_PRIORITY_MODE];
@@ -579,6 +584,15 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status,
 				enum policy_mgr_conn_update_reason reason,
 				uint32_t session_id, void *context,
 				uint32_t request_id);
+
+#ifdef WLAN_FEATURE_11BE_MLO
+void
+policy_mgr_dump_disabled_ml_links(struct policy_mgr_psoc_priv_obj *pm_ctx);
+#else
+static inline void
+policy_mgr_dump_disabled_ml_links(struct policy_mgr_psoc_priv_obj *pm_ctx) {}
+#endif
+
 void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc);
 
 /**

+ 11 - 1
components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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
@@ -422,6 +422,15 @@ static void policy_mgr_init_non_dbs_pcl(struct wlan_objmgr_psoc *psoc)
 }
 #endif
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static inline void policy_mgr_memzero_disabled_ml_list(void)
+{
+	qdf_mem_zero(pm_disabled_ml_links, sizeof(pm_disabled_ml_links));
+}
+#else
+static inline void policy_mgr_memzero_disabled_ml_list(void) {}
+#endif
+
 QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc)
 {
 	QDF_STATUS status;
@@ -438,6 +447,7 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc)
 
 	/* init pm_conc_connection_list */
 	qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list));
+	policy_mgr_memzero_disabled_ml_list();
 	policy_mgr_clear_concurrent_session_count(psoc);
 	/* init dbs_opportunistic_timer */
 	status = qdf_mc_timer_init(&pm_ctx->dbs_opportunistic_timer,

+ 7 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c

@@ -836,6 +836,13 @@ cm_fw_roam_sync_propagation(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 	}
 
 	cm_process_roam_keys(vdev, rsp, cm_id);
+	/*
+	 * Re-enable the disabled link on roaming as desision
+	 * will be taken again to disable the link on roam sync completion.
+	 */
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
+		policy_mgr_move_vdev_from_disabled_to_connection_tbl(psoc,
+								     vdev_id);
 	mlme_cm_osif_connect_complete(vdev, connect_rsp);
 
 	/**