Преглед изворни кода

qcacmn: Fix connection information deleting and restoring

Currently only one connection information corresponding to the
provided mode is deleted and restored, which causes channel
selecting failure in DFS testing with AP+AP concurrency mode.
When radar is found in AP+AP concurrency mode, a new valid channel
should be selected. Before selecting the channel, all existing
connection information of SAP mode should be deleted, otherwise
no valid channel can be selected.

All the connection information corresponding to the provided mode
should be deleted and restored.

Change-Id: Id363dbb2c31485fefcd6915696060923063079bb
CRs-Fixed: 2079597
bings пре 7 година
родитељ
комит
ff86e37d20

+ 3 - 1
umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -1241,6 +1241,7 @@ uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc,
  * @len: Pointer to the length of the PCL
  * @pcl_weight: Pointer to the weights of the PCL
  * @weight_len: Max length of the weights list
+ * @all_matching_cxn_to_del: Need remove all entries before getting pcl
  *
  * Get the PCL for an existing connection
  *
@@ -1249,7 +1250,8 @@ uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc,
 		enum policy_mgr_con_mode mode,
 		uint8_t *pcl_ch, uint32_t *len,
-		uint8_t *weight_list, uint32_t weight_len);
+		uint8_t *weight_list, uint32_t weight_len,
+		bool all_matching_cxn_to_del);
 
 /**
  * policy_mgr_get_valid_chan_weights() - Get the weightage for

+ 57 - 28
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -562,7 +562,9 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
 /**
  * policy_mgr_store_and_del_conn_info() - Store and del a connection info
  * @mode: Mode whose entry has to be deleted
- * @info: Struture pointer where the connection info will be saved
+ * @all_matching_cxn_to_del: All the specified mode entries should 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
@@ -571,18 +573,22 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
  * Return: None
  */
 void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
-				enum policy_mgr_con_mode mode,
-				struct policy_mgr_conc_connection_info *info)
+	enum policy_mgr_con_mode mode, bool all_matching_cxn_to_del,
+	struct policy_mgr_conc_connection_info *info, uint8_t *num_cxn_del)
 {
-	uint32_t conn_index = 0;
-	bool found = false;
+	int32_t conn_index = 0;
+	uint32_t found_index = 0;
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 
+	if (!num_cxn_del) {
+		policy_mgr_err("num_cxn_del is NULL");
+		return;
+	}
+	*num_cxn_del = 0;
 	if (!info) {
 		policy_mgr_err("Invalid connection info");
 		return;
 	}
-	qdf_mem_zero(info, sizeof(*info));
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
 		policy_mgr_err("Invalid Context");
@@ -592,34 +598,47 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
 		if (mode == pm_conc_connection_list[conn_index].mode) {
-			found = true;
-			break;
+			/*
+			 * Storing the connection entry which will be
+			 * temporarily deleted.
+			 */
+			info[found_index] = pm_conc_connection_list[conn_index];
+			/* Deleting the connection entry */
+			policy_mgr_decr_connection_count(psoc,
+					info[found_index].vdev_id);
+			policy_mgr_notice("Stored %d (%d), deleted STA entry with vdev id %d, index %d",
+				info[found_index].vdev_id,
+				info[found_index].mode,
+				info[found_index].vdev_id, conn_index);
+			found_index++;
+			if (all_matching_cxn_to_del)
+				continue;
+			else
+				break;
 		}
 		conn_index++;
 	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
 
-	if (!found) {
-		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (!found_index) {
+		*num_cxn_del = 0;
 		policy_mgr_err("Mode:%d not available in the conn info", mode);
-		return;
+	} else {
+		*num_cxn_del = found_index;
+		policy_mgr_err("Mode:%d number of conn %d temp del",
+				mode, *num_cxn_del);
 	}
 
-	/* Storing the STA entry which will be temporarily deleted */
-	*info = pm_conc_connection_list[conn_index];
-	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
-
-	/* Deleting the STA entry */
-	policy_mgr_decr_connection_count(psoc, info->vdev_id);
-
-	policy_mgr_notice("Stored %d (%d), deleted STA entry with vdev id %d, index %d",
-		info->vdev_id, info->mode, info->vdev_id, conn_index);
-
-	/* Caller should set the PCL and restore the STA entry in conn info */
+	/*
+	 * Caller should set the PCL and restore the connection entry
+	 * in conn info.
+	 */
 }
 
 /**
  * policy_mgr_restore_deleted_conn_info() - Restore connection info
- * @info: Saved connection info that is to be restored
+ * @info: An array saving connection info that is to be restored
+ * @num_cxn_del: Number of connection temporary deleted
  *
  * Restores the connection info of STA that was saved before
  * updating the PCL to the FW
@@ -627,11 +646,17 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
  * Return: None
  */
 void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc,
-		struct policy_mgr_conc_connection_info *info)
+		struct policy_mgr_conc_connection_info *info,
+		uint8_t num_cxn_del)
 {
 	uint32_t conn_index;
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 
+	if (MAX_NUMBER_OF_CONC_CONNECTIONS <= num_cxn_del || 0 == num_cxn_del) {
+		policy_mgr_err("Failed to restore %d/%d deleted information",
+				num_cxn_del, MAX_NUMBER_OF_CONC_CONNECTIONS);
+		return;
+	}
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
 		policy_mgr_err("Invalid Context");
@@ -646,7 +671,8 @@ void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc,
 	}
 
 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
-	pm_conc_connection_list[conn_index] = *info;
+	qdf_mem_copy(&pm_conc_connection_list[conn_index], info,
+			num_cxn_del * sizeof(*info));
 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
 
 	policy_mgr_notice("Restored the deleleted conn info, vdev:%d, index:%d",
@@ -1157,8 +1183,10 @@ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc,
 void policy_mgr_set_pcl_for_existing_combo(
 		struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
 {
-	struct policy_mgr_conc_connection_info info;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
 	enum tQDF_ADAPTER_MODE pcl_mode;
+	uint8_t num_cxn_del = 0;
 
 	switch (mode) {
 	case PM_STA_MODE:
@@ -1183,12 +1211,13 @@ void policy_mgr_set_pcl_for_existing_combo(
 
 	if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) {
 		/* Check, store and temp delete the mode's parameter */
-		policy_mgr_store_and_del_conn_info(psoc, mode, &info);
+		policy_mgr_store_and_del_conn_info(psoc, mode, false,
+						info, &num_cxn_del);
 		/* Set the PCL to the FW since connection got updated */
 		policy_mgr_pdev_set_pcl(psoc, pcl_mode);
 		policy_mgr_notice("Set PCL to FW for mode:%d", mode);
 		/* Restore the connection info */
-		policy_mgr_restore_deleted_conn_info(psoc, &info);
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
 	}
 }
 

+ 5 - 2
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -334,9 +334,12 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
 		bool in_use);
 void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
 				enum policy_mgr_con_mode mode,
-				struct policy_mgr_conc_connection_info *info);
+				bool all_matching_cxn_to_del,
+				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);
+				struct policy_mgr_conc_connection_info *info,
+				uint8_t num_cxn_del);
 void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc,
 				uint32_t num_vdev_mac_entries,
 				struct policy_mgr_vdev_mac_map *vdev_mac_map,

+ 18 - 9
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -68,9 +68,12 @@ policy_mgr_next_action_three_connection_table_type
 QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc,
 		enum policy_mgr_con_mode mode,
 		uint8_t *pcl_ch, uint32_t *len,
-		uint8_t *pcl_weight, uint32_t weight_len)
+		uint8_t *pcl_weight, uint32_t weight_len,
+		bool all_matching_cxn_to_del)
 {
-	struct policy_mgr_conc_connection_info info;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	uint8_t num_cxn_del = 0;
 
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
@@ -78,13 +81,14 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc,
 
 	if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) {
 		/* Check, store and temp delete the mode's parameter */
-		policy_mgr_store_and_del_conn_info(psoc, mode, &info);
+		policy_mgr_store_and_del_conn_info(psoc, mode,
+				all_matching_cxn_to_del, info, &num_cxn_del);
 		/* Get the PCL */
 		status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
 					pcl_weight, weight_len);
 		policy_mgr_notice("Get PCL to FW for mode:%d", mode);
 		/* Restore the connection info */
-		policy_mgr_restore_deleted_conn_info(psoc, &info);
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
 	}
 
 	return status;
@@ -1283,7 +1287,8 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc,
 		if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl_for_existing_conn(
 					psoc, mode,
 					&pcl_channels[0], &pcl_len,
-					pcl_weight, QDF_ARRAY_SIZE(pcl_weight)))
+					pcl_weight, QDF_ARRAY_SIZE(pcl_weight),
+					false))
 			return channel;
 	} else {
 		if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl(psoc, mode,
@@ -1464,7 +1469,8 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
 
 	status = policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE,
 			pcl.pcl_list, &pcl.pcl_len,
-			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
+			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
+			false);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		policy_mgr_err("Unable to get PCL for SAP");
 		return status;
@@ -1504,7 +1510,9 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
 		struct policy_mgr_pcl_chan_weights *weight)
 {
 	uint32_t i, j;
-	struct policy_mgr_conc_connection_info info;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	uint8_t num_cxn_del = 0;
 
 	if (!weight->pcl_list) {
 		policy_mgr_err("Invalid pcl");
@@ -1532,7 +1540,8 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
 		 * check can be used as though a new connection is coming up,
 		 * allowing to detect the disallowed channels.
 		 */
-		policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, &info);
+		policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, false,
+						info, &num_cxn_del);
 		/*
 		 * There is a small window between releasing the above lock
 		 * and acquiring the same in policy_mgr_allow_concurrency,
@@ -1548,7 +1557,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
 		}
 
 		/* Restore the connection info */
-		policy_mgr_restore_deleted_conn_info(psoc, &info);
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
 	}
 
 	for (i = 0; i < weight->saved_num_chan; i++) {

+ 1 - 1
umac/dfs/dispatcher/src/wlan_dfs_utils_api.c

@@ -453,7 +453,7 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 				&len, weight_list, weight_len);
 	else
 		policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, pcl_ch,
-				&len, weight_list, weight_len);
+				&len, weight_list, weight_len, true);
 
 	if (*num_chan < len) {
 		DFS_PRINTK("%s: Invalid len src=%d, dst=%d\n",