Browse Source

qcacmn: Add API for concurrency check to cover AP channel switch case

There is already existing SAP+GO combination but due to upper
layer notifying LTE-COEX event or sending command to move one of
the connections to different channel. In such cases before moving
existing connection to new channel, check if new channel can
co-exist with the other existing connection. For example, one
SAP1 is on channel-6 and second SAP2 is on channel-36 and lets
say they are doing DBS, and lets say upper layer sends LTE-COEX
to move SAP1 from channel-6 to channel-149. In this case, SAP1
and SAP2 will end up doing MCC which may not be desirable result.

When channel switch, need recheck whether concurrency is allowed,
Store the connection's parameter and temporarily delete it
from the concurrency table. This way the allow concurrency
check can be used as though a new connection is coming up,
after check, restore the connection to concurrency table.

Change-Id: I66e262774de8dfeba56f9b6f3d1d6721f1748881
CRs-Fixed: 2299105
Jianmin Zhu 6 years ago
parent
commit
2cb2181a4c

+ 25 - 0
umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -395,6 +395,31 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
 		enum policy_mgr_con_mode mode,
 		uint8_t channel, enum hw_mode_bandwidth bw);
 
+/**
+ * policy_mgr_allow_concurrency_csa() - Check for allowed concurrency
+ * combination when channel switch
+ * @psoc:	PSOC object information
+ * @mode:	connection mode
+ * @channel:	target channel to switch
+ * @vdev_id:	vdev id of channel switch interface
+ *
+ * There is already existing SAP+GO combination but due to upper layer
+ * notifying LTE-COEX event or sending command to move one of the connections
+ * to different channel. In such cases before moving existing connection to new
+ * channel, check if new channel can co-exist with the other existing
+ * connection. For example, one SAP1 is on channel-6 and second SAP2 is on
+ * channel-36 and lets say they are doing DBS, and lets say upper layer sends
+ * LTE-COEX to move SAP1 from channel-6 to channel-149. In this case, SAP1 and
+ * SAP2 will end up doing MCC which may not be desirable result. such cases
+ * will be prevented with this API.
+ *
+ * Return: True/False
+ */
+bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
+				      enum policy_mgr_con_mode mode,
+				      uint8_t channel,
+				      uint32_t vdev_id);
+
 /**
  * policy_mgr_get_first_connection_pcl_table_index() - provides the
  * row index to firstConnectionPclTable to get to the correct

+ 42 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -720,6 +720,48 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
 	 */
 }
 
+void policy_mgr_store_and_del_conn_info_by_vdev_id(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t vdev_id,
+			struct policy_mgr_conc_connection_info *info,
+			uint8_t *num_cxn_del)
+{
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (!info || !num_cxn_del) {
+		policy_mgr_err("Invalid parameters");
+		return;
+	}
+	*num_cxn_del = 0;
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	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].vdev_id == vdev_id) &&
+		    pm_conc_connection_list[conn_index].in_use) {
+			*num_cxn_del = 1;
+			break;
+		}
+	}
+	/*
+	 * Storing the connection entry which will be
+	 * temporarily deleted.
+	 */
+	if (*num_cxn_del == 1) {
+		*info = pm_conc_connection_list[conn_index];
+		/* Deleting the connection entry */
+		policy_mgr_decr_connection_count(
+			psoc,
+			pm_conc_connection_list[conn_index].vdev_id);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
 /**
  * policy_mgr_restore_deleted_conn_info() - Restore connection info
  * @info: An array saving connection info that is to be restored

+ 31 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -1862,6 +1862,37 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
 	return policy_mgr_is_concurrency_allowed(psoc, mode, channel, bw);
 }
 
+bool  policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
+				       enum policy_mgr_con_mode mode,
+				       uint8_t channel,
+				       uint32_t vdev_id)
+{
+	bool allow = false;
+	struct policy_mgr_conc_connection_info info;
+	uint8_t num_cxn_del = 0;
+
+	/*
+	 * Store the connection's parameter and temporarily delete it
+	 * from the concurrency table. This way the allow concurrency
+	 * check can be used as though a new connection is coming up,
+	 * after check, restore the connection to concurrency table.
+	 */
+	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
+						      &info, &num_cxn_del);
+	allow = policy_mgr_allow_concurrency(
+				psoc,
+				mode,
+				channel,
+				HW_MODE_20_MHZ);
+	if (!allow)
+		policy_mgr_err("CSA concurrency check failed");
+	/* Restore the connection entry */
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
+
+	return allow;
+}
+
 /**
  * policy_mgr_get_concurrency_mode() - return concurrency mode
  * @psoc: PSOC object information

+ 21 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -382,6 +382,27 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
 				bool all_matching_cxn_to_del,
 				struct policy_mgr_conc_connection_info *info,
 				uint8_t *num_cxn_del);
+
+/**
+ * policy_mgr_store_and_del_conn_info_by_vdev_id() - Store and del a
+ * connection info by vdev id
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id whose entry has to be deleted
+ * @info: struture array pointer where the connection info will be saved
+ * @num_cxn_del: number of connection which are going to be deleted
+ *
+ * Saves the connection info corresponding to the provided mode
+ * and deleted that corresponding entry based on vdev from the
+ * connection info structure
+ *
+ * Return: None
+ */
+void policy_mgr_store_and_del_conn_info_by_vdev_id(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t vdev_id,
+			struct policy_mgr_conc_connection_info *info,
+			uint8_t *num_cxn_del);
+
 void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc,
 				struct policy_mgr_conc_connection_info *info,
 				uint8_t num_cxn_del);