Browse Source

qcacld-3.0: Enable/disable ML link based on SAP/P2P vdev traffic type

Add logic to enable and disable number of STA ML link, on vdev UP
and DOWN, if any link is causing MCC with exiting
SAP/P2P and SAP/P2P with traffic type as low latency or high tput.

Change-Id: Id599acf5a07042328917b5e15f077d2decc0ad5f
CRs-Fixed: 3189304
Sheenam Monga 2 years ago
parent
commit
86d1d71e70

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

@@ -4288,6 +4288,28 @@ void policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
 					       struct wlan_objmgr_vdev *vdev,
 					       bool is_connect);
 
+/*
+ * policy_mgr_handle_sap_cli_go_ml_sta_up_csa() - Handle enable/disable
+ * link on CLI/GO/SAP/ML_STA vdev UP and channel change
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev_id which went UP or changed channel
+ *
+ * Return: void
+ */
+void
+policy_mgr_handle_sap_cli_go_ml_sta_up_csa(struct wlan_objmgr_psoc *psoc,
+					   uint8_t vdev_id);
+
+/*
+ * policy_mgr_re_enable_ml_sta_on_p2p_sap_down() - Handle enable
+ * link on CLI/GO/SAP/ML_STA down
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev_id which went down
+ *
+ * Return: void
+ */
+void policy_mgr_re_enable_ml_sta_on_p2p_sap_down(struct wlan_objmgr_psoc *psoc,
+						 uint8_t vdev_id);
 #else
 
 static inline bool policy_mgr_is_mlo_sap_concurrency_allowed(
@@ -4329,6 +4351,18 @@ void policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
 					       bool is_connect)
 {
 }
+
+static inline void
+policy_mgr_handle_sap_cli_go_ml_sta_up_csa(struct wlan_objmgr_psoc *psoc,
+					   uint8_t vdev_id)
+{
+}
+
+static inline
+void policy_mgr_re_enable_ml_sta_on_p2p_sap_down(struct wlan_objmgr_psoc *psoc,
+						 uint8_t vdev_id)
+{
+}
 #endif
 
 /**

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

@@ -69,6 +69,10 @@
 #define MAX_NUMBER_OF_DISABLE_LINK WLAN_UMAC_MLO_MAX_VDEVS - 1
 #endif
 
+/* BIT 0 for low latency and BIT 1 for HIGH TPUT */
+#define PM_VDEV_TRAFFIC_LOW_LATENCY 0x1
+#define PM_VDEV_TRAFFIC_HIGH_TPUT 0x2
+
 /* Policy manager default request id */
 #define POLICY_MGR_DEF_REQ_ID 0
 

+ 364 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -4893,6 +4893,370 @@ policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
 						       vdev_id_list);
 }
 
+static bool
+policy_mgr_is_mode_p2p_sap(enum policy_mgr_con_mode mode)
+{
+	return (mode == PM_SAP_MODE) || (mode == PM_P2P_CLIENT_MODE) ||
+	       (mode == PM_P2P_GO_MODE);
+}
+
+static bool
+policy_mgr_is_vdev_high_tput_or_low_latency(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	bool is_vdev_ll_ht;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d", vdev_id);
+		return false;
+	}
+	is_vdev_ll_ht = wlan_is_vdev_traffic_ll_ht(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return is_vdev_ll_ht;
+}
+
+/*
+ * policy_mgr_get_affected_links_for_go_sap_cli() - Check if any of the P2P OR
+ * SAP is causing MCC with a ML link and also is configured high tput or low
+ * latency
+ * @psoc: psoc ctx
+ * @num_ml_sta: Number of ML STA present
+ * @ml_vdev_lst: ML STA vdev id list
+ * @ml_freq_lst: ML STA freq list
+ * @num_p2p_sap: Number of P2P and SAP present
+ * @p2p_sap_vdev_lst: P2P and SAP vdev id list
+ * @p2p_sap_freq_lst: P2P and SAP freq list
+ *
+ * Return: Number of links causing MCC with any of the P2P or SAP which is
+ * configured high tput or low latency
+ */
+static uint8_t
+policy_mgr_get_affected_links_for_go_sap_cli(struct wlan_objmgr_psoc *psoc,
+					     uint8_t num_ml_sta,
+					     uint8_t *ml_vdev_lst,
+					     qdf_freq_t *ml_freq_lst,
+					     uint8_t num_p2p_sap,
+					     uint8_t *p2p_sap_vdev_lst,
+					     qdf_freq_t *p2p_sap_freq_lst)
+{
+	uint8_t i = 0, k = 0, num_affected_links = 0;
+
+	if (!num_p2p_sap || num_ml_sta < 2)
+		return num_affected_links;
+
+	while (i < num_ml_sta) {
+		/* if any link is causing MCC with GO/GC/AP, set mcc as true.*/
+		for (k = 0; k < num_p2p_sap; k++) {
+			/* Continue if SCC */
+			if (ml_freq_lst[i] == p2p_sap_freq_lst[k])
+				continue;
+			/* Continue if high tput ot low latency is not set */
+			if (!policy_mgr_is_vdev_high_tput_or_low_latency(psoc,
+			    p2p_sap_vdev_lst[k]))
+				continue;
+			/* If both freq are on same mac then its MCC */
+			if (policy_mgr_are_2_freq_on_same_mac(psoc,
+							ml_freq_lst[i],
+							p2p_sap_freq_lst[k])) {
+				policy_mgr_debug("ml sta vdev %d (freq %d) and p2p/sap vdev %d (freq %d) are MCC",
+						 ml_vdev_lst[i], ml_freq_lst[i],
+						 p2p_sap_vdev_lst[k],
+						 p2p_sap_freq_lst[k]);
+				num_affected_links++;
+			}
+		}
+		i++;
+	}
+
+	return num_affected_links;
+}
+
+/*
+ * policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info() - Get number of ML STA,
+ * P2P and SAP interfaces and their vdev ids and freq list
+ * @pm_ctx: pm_ctx ctx
+ * @num_ml_sta: Return number of ML STA present
+ * @num_disabled_ml_sta: Return number of disabled ML STA links
+ * @ml_vdev_lst: Return ML STA vdev id list
+ * @ml_freq_lst: Return ML STA freq list
+ * @num_p2p_sap: Return number of P2P and SAP present
+ * @p2p_sap_vdev_lst: Return P2P and SAP vdev id list
+ * @p2p_sap_freq_lst: Return P2P and SAP freq list
+ *
+ * Return: void
+ */
+static void
+policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(
+					struct policy_mgr_psoc_priv_obj *pm_ctx,
+					uint8_t *num_ml_sta,
+					uint8_t *num_disabled_ml_sta,
+					uint8_t *ml_vdev_lst,
+					qdf_freq_t *ml_freq_lst,
+					uint8_t *num_p2p_sap,
+					uint8_t *p2p_sap_vdev_lst,
+					qdf_freq_t *p2p_sap_freq_lst)
+{
+	enum policy_mgr_con_mode mode;
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t vdev_id, conn_index;
+	qdf_freq_t freq;
+
+	*num_ml_sta = 0;
+	*num_p2p_sap = 0;
+	*num_disabled_ml_sta = 0;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		if (!pm_conc_connection_list[conn_index].in_use)
+			continue;
+		mode = pm_conc_connection_list[conn_index].mode;
+		if (!policy_mgr_is_mode_p2p_sap(mode) && mode != PM_STA_MODE)
+			continue;
+		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+		freq = pm_conc_connection_list[conn_index].freq;
+
+		if (policy_mgr_is_mode_p2p_sap(mode)) {
+			/* add p2p and sap vdev and freq list */
+			p2p_sap_vdev_lst[*num_p2p_sap] = vdev_id;
+			p2p_sap_freq_lst[(*num_p2p_sap)++] = freq;
+			continue;
+		}
+
+		/* add ml sta vdev and freq list */
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc,
+							    vdev_id,
+							    WLAN_POLICY_MGR_ID);
+		if (!vdev) {
+			policy_mgr_err("invalid vdev for id %d", vdev_id);
+			continue;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+			ml_vdev_lst[*num_ml_sta] = vdev_id;
+			ml_freq_lst[(*num_ml_sta)++] = freq;
+		}
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+	/* Get disabled link info as well and keep it at last */
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK;
+	     conn_index++) {
+		if (!pm_disabled_ml_links[conn_index].in_use)
+			continue;
+		if (pm_disabled_ml_links[conn_index].mode != PM_STA_MODE)
+			continue;
+		ml_vdev_lst[*num_ml_sta] =
+				pm_disabled_ml_links[conn_index].vdev_id;
+		ml_freq_lst[(*num_ml_sta)++] =
+			pm_disabled_ml_links[conn_index].freq;
+		(*num_disabled_ml_sta)++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+/*
+ * policy_mgr_sta_ml_link_enable_allowed() - Check with given ML links and
+ * existing concurrencies, a disabled ml link can be enabled back.
+ * @psoc: psoc ctx
+ * @num_disabled_ml_sta: Number of existing disabled links
+ * @num_ml_sta: Number of total ML STA links
+ * @ml_freq_lst: ML STA freq list
+ * @ml_vdev_lst: ML STA vdev id list
+ *
+ * Return: if link can be enabled or not
+ */
+static bool
+policy_mgr_sta_ml_link_enable_allowed(struct wlan_objmgr_psoc *psoc,
+				      uint8_t num_disabled_ml_sta,
+				      uint8_t num_ml_sta,
+				      qdf_freq_t *ml_freq_lst,
+				      uint8_t *ml_vdev_lst)
+{
+	union conc_ext_flag conc_ext_flags;
+	uint8_t disabled_link_vdev_id;
+	qdf_freq_t disabled_link_freq;
+	struct wlan_objmgr_vdev *vdev;
+
+	/* If no link is disabled nothing to do */
+	if (!num_disabled_ml_sta || num_ml_sta < 2)
+		return false;
+
+	/* Disabled link is at the last index */
+	disabled_link_vdev_id = ml_vdev_lst[num_ml_sta - 1];
+	disabled_link_freq = ml_freq_lst[num_ml_sta - 1];
+	policy_mgr_debug("disabled_link_vdev_id %d disabled_link_freq %d",
+			 disabled_link_vdev_id, disabled_link_freq);
+	if (!disabled_link_freq)
+		return false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, disabled_link_vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d", disabled_link_vdev_id);
+		return false;
+	}
+	conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return policy_mgr_allow_concurrency(psoc, PM_STA_MODE,
+					    disabled_link_freq, HW_MODE_20_MHZ,
+					    conc_ext_flags.value);
+}
+
+void
+policy_mgr_handle_sap_cli_go_ml_sta_up_csa(struct wlan_objmgr_psoc *psoc,
+					   uint8_t vdev_id)
+{
+	uint8_t num_ml_sta = 0, num_p2p_sap = 0, num_disabled_ml_sta = 0;
+	uint8_t num_affected_link;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t p2p_sap_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t p2p_sap_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	struct wlan_objmgr_vdev *vdev;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(pm_ctx, &num_ml_sta,
+						      &num_disabled_ml_sta,
+						      ml_sta_vdev_lst,
+						      ml_freq_lst, &num_p2p_sap,
+						      p2p_sap_vdev_lst,
+						      p2p_sap_freq_lst);
+
+	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_p2p_sap %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_p2p_sap);
+	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_p2p_sap > MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		policy_mgr_err("vdev %d: invalid num_ml_sta %d disabled %d num_p2p_sap %d",
+			       vdev_id, num_ml_sta, num_disabled_ml_sta,
+			       num_p2p_sap);
+		return;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d: invalid vdev", vdev_id);
+		return;
+	}
+
+	num_affected_link = policy_mgr_get_affected_links_for_go_sap_cli(psoc,
+						num_ml_sta, ml_sta_vdev_lst,
+						ml_freq_lst, num_p2p_sap,
+						p2p_sap_vdev_lst,
+						p2p_sap_freq_lst);
+
+	if (!num_affected_link) {
+		policy_mgr_debug("vdev %d: no affected link found", vdev_id);
+		goto enable_link;
+	}
+
+	wlan_mlo_sta_mlo_concurency_set_link(vdev,
+					     MLO_LINK_FORCE_REASON_CONNECT,
+					     MLO_LINK_FORCE_MODE_ACTIVE_NUM,
+					     num_ml_sta, ml_sta_vdev_lst);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return;
+enable_link:
+
+	/*
+	 * if no affected link and link can be allowed to enable then renable
+	 * the disabled link.
+	 */
+	if (policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
+						  num_ml_sta, ml_freq_lst,
+						  ml_sta_vdev_lst))
+		wlan_mlo_sta_mlo_concurency_set_link(vdev,
+					MLO_LINK_FORCE_REASON_DISCONNECT,
+					MLO_LINK_FORCE_MODE_NO_FORCE,
+					num_ml_sta, ml_sta_vdev_lst);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
+void policy_mgr_re_enable_ml_sta_on_p2p_sap_down(struct wlan_objmgr_psoc *psoc,
+						 uint8_t vdev_id)
+{
+	uint8_t num_ml_sta = 0, num_p2p_sap = 0, num_disabled_ml_sta = 0;
+	uint8_t num_affected_link = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t p2p_sap_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t p2p_sap_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	struct wlan_objmgr_vdev *vdev;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(pm_ctx, &num_ml_sta,
+						      &num_disabled_ml_sta,
+						      ml_sta_vdev_lst,
+						      ml_freq_lst, &num_p2p_sap,
+						      p2p_sap_vdev_lst,
+						      p2p_sap_freq_lst);
+
+	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_p2p_sap %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_p2p_sap);
+
+	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_p2p_sap > MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		policy_mgr_err("vdev %d: invalid num_ml_sta %d disabled %d num_p2p_sap %d",
+			       vdev_id, num_ml_sta, num_disabled_ml_sta,
+			       num_p2p_sap);
+		return;
+	}
+
+	/* If link can not be allowed to enable then skip checking further. */
+	if (!policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
+						   num_ml_sta, ml_freq_lst,
+						   ml_sta_vdev_lst))
+		return;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d: invalid vdev", vdev_id);
+		return;
+	}
+	/*
+	 * If num_p2p_sap is non zero, ie p2p or sap still present check if
+	 * disable link is still required, if not enable the link.
+	 *
+	 * If num_p2p_sap is 0, ie only ml sta is present, enable the link.
+	 */
+	if (num_p2p_sap)
+		num_affected_link =
+			policy_mgr_get_affected_links_for_go_sap_cli(psoc,
+						num_ml_sta, ml_sta_vdev_lst,
+						ml_freq_lst, num_p2p_sap,
+						p2p_sap_vdev_lst,
+						p2p_sap_freq_lst);
+
+	if (num_affected_link)
+		policy_mgr_debug("vdev %d: Affected link present, dont reanabe ML link",
+				 vdev_id);
+	else
+		wlan_mlo_sta_mlo_concurency_set_link(vdev,
+					MLO_LINK_FORCE_REASON_DISCONNECT,
+					MLO_LINK_FORCE_MODE_NO_FORCE,
+					num_ml_sta, ml_sta_vdev_lst);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
 #else
 static bool
 policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc,

+ 2 - 1
components/mlme/core/inc/wlan_mlme_main.h

@@ -62,7 +62,6 @@
 #define QCN_IE_ATTR_ID_VHT_MCS11 2
 #define QCN_IE_ATTR_ID_ALL 0xFF
 
-
 #define mlme_legacy_fatal(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_MLME, params)
 #define mlme_legacy_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_MLME, params)
 #define mlme_legacy_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_MLME, params)
@@ -436,6 +435,7 @@ struct wait_for_key_timer {
  * @is_usr_ps_enabled: Is Power save enabled
  * @notify_co_located_ap_upt_rnr: Notify co located AP to update RNR or not
  * @max_mcs_index: Max supported mcs index of vdev
+ * @vdev_traffic_type: to set if vdev is LOW_LATENCY or HIGH_TPUT
  */
 struct mlme_legacy_priv {
 	bool chan_switch_in_progress;
@@ -483,6 +483,7 @@ struct mlme_legacy_priv {
 #ifdef WLAN_FEATURE_SON
 	uint8_t max_mcs_index;
 #endif
+	uint8_t vdev_traffic_type;
 };
 
 /**

+ 9 - 1
components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-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
@@ -433,6 +433,14 @@ bool mlme_is_notify_co_located_ap_update_rnr(struct wlan_objmgr_vdev *vdev);
 void mlme_set_notify_co_located_ap_update_rnr(struct wlan_objmgr_vdev *vdev,
 					      bool update_rnr);
 
+/**
+ * wlan_is_vdev_traffic_ll_ht() - if vdev traffic type is low latency or high TP
+ * @vdev: vdev pointer
+ *
+ * Return: true is LL or HT is set.
+ */
+bool wlan_is_vdev_traffic_ll_ht(struct wlan_objmgr_vdev *vdev);
+
 /**
  * mlme_get_assoc_type() - get associate type
  * @vdev: vdev pointer

+ 17 - 0
components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -1053,6 +1053,23 @@ bool mlme_is_notify_co_located_ap_update_rnr(struct wlan_objmgr_vdev *vdev)
 	return mlme_priv->notify_co_located_ap_upt_rnr;
 }
 
+bool wlan_is_vdev_traffic_ll_ht(struct wlan_objmgr_vdev *vdev)
+{
+	struct mlme_legacy_priv *mlme_priv;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		return false;
+	}
+
+	if (mlme_priv->vdev_traffic_type & PM_VDEV_TRAFFIC_LOW_LATENCY ||
+	    mlme_priv->vdev_traffic_type & PM_VDEV_TRAFFIC_HIGH_TPUT)
+		return true;
+
+	return false;
+}
+
 enum vdev_assoc_type  mlme_get_assoc_type(struct wlan_objmgr_vdev *vdev)
 {
 	struct mlme_legacy_priv *mlme_priv;