Jelajahi Sumber

qcacmn: Add support for scan and MLME synchronization

Reject scan request, if any VDEV is in START/DFS_CAC/SUSPEND states.

Change-Id: I1047ba510df5ae5debd1e3d5c8a064a57af65fbf
CRs-Fixed: 2384163
Srinivas Pitla 6 tahun lalu
induk
melakukan
1ff074ce30

+ 8 - 1
init_deinit/dispatcher/src/dispatcher_init_deinit.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019 The Linux Foundation. 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
@@ -945,8 +945,13 @@ QDF_STATUS dispatcher_psoc_enable(struct wlan_objmgr_psoc *psoc)
 	if (QDF_STATUS_SUCCESS != dispatcher_dbr_psoc_enable(psoc))
 		goto dbr_psoc_enable_fail;
 
+	if (QDF_STATUS_SUCCESS != wlan_mlme_psoc_enable(psoc))
+		goto mlme_psoc_enable_fail;
+
 	return QDF_STATUS_SUCCESS;
 
+mlme_psoc_enable_fail:
+	dispatcher_dbr_psoc_disable(psoc);
 dbr_psoc_enable_fail:
 	fd_psoc_disable(psoc);
 fd_psoc_enable_fail:
@@ -969,6 +974,8 @@ qdf_export_symbol(dispatcher_psoc_enable);
 
 QDF_STATUS dispatcher_psoc_disable(struct wlan_objmgr_psoc *psoc)
 {
+	QDF_BUG(QDF_STATUS_SUCCESS == wlan_mlme_psoc_disable(psoc));
+
 	QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_dbr_psoc_disable(psoc));
 
 	QDF_BUG(QDF_STATUS_SUCCESS == fd_psoc_disable(psoc));

+ 6 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h

@@ -230,6 +230,8 @@ typedef void (*wlan_objmgr_peer_status_handler)(
  * @WLAN_ACTION_OUI_ID:         action oui operations
  * @WLAN_LEGACY_SAP_ID:         legacy sap fsm
  * @WLAN_TGT_IF_DP_PEER_REF_ID: cp peer reference in dp (Target IF)
+ * @WLAN_MLME_SER_IF_ID:        mlme serialization interface layer
+ * @WLAN_SCHEDULER_ID:          mlme scheduler
  * @WLAN_REF_ID_MAX:            Max id used to generate ref count tracking array
  */
  /* New value added to the enum must also be reflected in function
@@ -282,6 +284,8 @@ typedef enum {
 	WLAN_ACTION_OUI_ID      = 43,
 	WLAN_LEGACY_SAP_ID      = 44,
 	WLAN_TGT_IF_DP_PEER_REF_ID = 45,
+	WLAN_MLME_SER_IF_ID        = 46,
+	WLAN_SCHEDULER_ID          = 47,
 	WLAN_REF_ID_MAX,
 } wlan_objmgr_ref_dbgid;
 
@@ -341,6 +345,8 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id)
 					"WLAN_ACTION_OUI_ID",
 					"WLAN_LEGACY_SAP_ID",
 					"WLAN_TGT_IF_DP_PEER_REF_ID",
+					"WLAN_MLME_SER_IF_ID",
+					"WLAN_SCHEDULER_ID",
 					"WLAN_REF_ID_MAX"};
 
 	return (char *)strings[id];

+ 4 - 0
umac/cmn_services/serialization/inc/wlan_serialization_api.h

@@ -61,6 +61,7 @@ enum wlan_serialization_cb_reason {
  * struct wlan_serialization_scan_info - Information needed for scan cmd
  * @is_cac_in_progress: boolean to check the cac status
  * @is_tdls_in_progress: boolean to check the tdls status
+ * @is_mlme_op_in_progress: boolean to check the mlme op status
  *
  * This information is needed for scan command from other components
  * to apply the rules and check whether the cmd is allowed or not
@@ -68,6 +69,7 @@ enum wlan_serialization_cb_reason {
 struct wlan_serialization_scan_info {
 	bool is_cac_in_progress;
 	bool is_tdls_in_progress;
+	bool is_mlme_op_in_progress;
 };
 
 /**
@@ -547,6 +549,7 @@ enum wlan_serialization_cb_reason {
  * struct wlan_serialization_scan_info - Information needed for scan cmd
  * @is_cac_in_progress: boolean to check the cac status
  * @is_tdls_in_progress: boolean to check the tdls status
+ * @is_mlme_op_in_progress: boolean to check the mlme op status
  *
  * This information is needed for scan command from other components
  * to apply the rules and check whether the cmd is allowed or not
@@ -554,6 +557,7 @@ enum wlan_serialization_cb_reason {
 struct wlan_serialization_scan_info {
 	bool is_cac_in_progress;
 	bool is_tdls_in_progress;
+	bool is_mlme_op_in_progress;
 };
 
 /**

+ 14 - 1
umac/cmn_services/utils/inc/wlan_utility.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. 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
@@ -285,4 +285,17 @@ void
 wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr,
 			 int8_t *rssi);
 
+/**
+ * wlan_util_is_pdev_scan_allowed() - Check for vdev is allowed to scan
+ * @pdev: pdev pointer
+ * @dbg_id: module id
+ *
+ * Iterates through all vdevs, checks if any VDEV is not either in S_INIT or in
+ * S_UP state
+ *
+ * Return: QDF_STATUS_SUCCESS,if scan is allowed, otherwise QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev,
+					  wlan_objmgr_ref_dbgid dbg_id);
+
 #endif /* _WLAN_UTILITY_H_ */

+ 38 - 1
umac/cmn_services/utils/src/wlan_utility.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. 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
@@ -462,6 +462,43 @@ QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev,
 
 	return QDF_STATUS_E_FAILURE;
 }
+
+static void wlan_vdev_scan_allowed(struct wlan_objmgr_pdev *pdev, void *object,
+				   void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	uint8_t *flag = (uint8_t *)arg;
+
+	wlan_vdev_obj_lock(vdev);
+	if (wlan_vdev_mlme_is_scan_allowed(vdev) != QDF_STATUS_SUCCESS)
+		*flag = 1;
+
+	wlan_vdev_obj_unlock(vdev);
+}
+
+QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev,
+					  wlan_objmgr_ref_dbgid dbg_id)
+{
+	uint8_t flag = 0;
+
+	if (!pdev)
+		return QDF_STATUS_E_INVAL;
+
+	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
+					  wlan_vdev_scan_allowed,
+					  &flag, 0, dbg_id);
+
+	if (flag == 1)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev,
+					  wlan_objmgr_ref_dbgid dbg_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 
 void

+ 1 - 0
umac/mlme/include/wlan_vdev_mlme.h

@@ -167,6 +167,7 @@ struct vdev_mlme_ops {
  * struct vdev_mlme_obj - VDEV MLME component object
  * @vdev_proto:           VDEV MLME proto substructure
  * @sm_lock:              VDEV SM lock
+ * @vdev_cmd_lock:        VDEV MLME command atomicity
  * @sm_hdl:               VDEV SM handle
  * @ops:                  VDEV MLME callback table
  * @ext_vdev_ptr:         VDEV MLME legacy pointer

+ 47 - 1
umac/mlme/mlme_objmgr/dispatcher/inc/wlan_vdev_mlme_main.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019 The Linux Foundation. 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
@@ -183,6 +183,25 @@ QDF_STATUS wlan_vdev_mlme_init(void);
  */
 QDF_STATUS wlan_vdev_mlme_deinit(void);
 
+/**
+ * wlan_mlme_psoc_enable - MLME initializations on PSOC enable
+ *
+ * Initializes MLME params on PSOC eable
+ *
+ * Return: SUCCESS on successful initialization
+ *         FAILURE, if initialization fails
+ */
+QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_mlme_psoc_disable - MLME clean up on PSOC disable
+ *
+ * cleanup MLME params on PSOC eable
+ *
+ * Return: SUCCESS on successful cleanup
+ *         FAILURE, if cleanup fails
+ */
+QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc);
 #else
 
 /**
@@ -210,5 +229,32 @@ static inline QDF_STATUS wlan_vdev_mlme_deinit(void)
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+/**
+ * wlan_mlme_psoc_enable - MLME initializations on PSOC enable
+ *
+ * Initializes MLME params on PSOC eable
+ *
+ * Return: SUCCESS on successful initialization
+ *         FAILURE, if initialization fails
+ */
+static inline QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_mlme_psoc_disable - MLME clean up on PSOC disable
+ *
+ * cleanup MLME params on PSOC eable
+ *
+ * Return: SUCCESS on successful cleanup
+ *         FAILURE, if cleanup fails
+ */
+static inline QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 #endif
 #endif

+ 61 - 1
umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019 The Linux Foundation. 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
@@ -26,6 +26,8 @@
 #include <wlan_mlme_dbg.h>
 #include "include/wlan_vdev_mlme.h"
 #include "vdev_mgr/core/src/vdev_mlme_sm.h"
+#include "wlan_serialization_api.h"
+#include "wlan_utility.h"
 
 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev,
 					       void *arg)
@@ -120,6 +122,64 @@ static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+static void mlme_scan_serialization_comp_info_cb(
+		struct wlan_objmgr_vdev *vdev,
+		union wlan_serialization_rules_info *comp_info)
+{
+	struct wlan_objmgr_pdev *pdev;
+	QDF_STATUS status;
+
+	if (!comp_info || !vdev) {
+		mlme_err("comp_info or vdev is NULL");
+		return;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		mlme_err("pdev is NULL");
+		return;
+	}
+
+	comp_info->scan_info.is_mlme_op_in_progress = false;
+
+	status = wlan_util_is_pdev_scan_allowed(pdev, WLAN_MLME_SER_IF_ID);
+	if (status != QDF_STATUS_SUCCESS)
+		comp_info->scan_info.is_mlme_op_in_progress = true;
+}
+
+QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+
+	status = wlan_serialization_register_comp_info_cb
+			(psoc,
+			 WLAN_UMAC_COMP_MLME,
+			 WLAN_SER_CMD_SCAN,
+			 mlme_scan_serialization_comp_info_cb);
+	if (status != QDF_STATUS_SUCCESS) {
+		mlme_err("Serialize scan cmd register failed");
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+
+	status = wlan_serialization_deregister_comp_info_cb
+						(psoc,
+						 WLAN_UMAC_COMP_MLME,
+						 WLAN_SER_CMD_SCAN);
+	if (status != QDF_STATUS_SUCCESS) {
+		mlme_err("Serialize scan cmd deregister failed");
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS wlan_vdev_mlme_init(void)
 {
 	if (wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_MLME,

+ 11 - 0
umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mlme_api.h

@@ -152,5 +152,16 @@ void wlan_vdev_mlme_cmd_lock(struct wlan_objmgr_vdev *vdev);
  * Return: void
  */
 void wlan_vdev_mlme_cmd_unlock(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * wlan_vdev_mlme_is_scan_allowed() - Checks whether scan is allowed
+ * @vdev: Object manager VDEV object
+ *
+ * API to checks the VDEV MLME SM state to check scan is allowed
+ *
+ * Return: SUCCESS: if scan is allowed
+ *         FAILURE: otherwise failure
+ */
+QDF_STATUS wlan_vdev_mlme_is_scan_allowed(struct wlan_objmgr_vdev *vdev);
 #endif
 #endif

+ 12 - 0
umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.c

@@ -204,4 +204,16 @@ void wlan_vdev_mlme_cmd_unlock(struct wlan_objmgr_vdev *vdev)
 	mlme_vdev_cmd_mutex_release(vdev_mlme);
 }
 
+QDF_STATUS wlan_vdev_mlme_is_scan_allowed(struct wlan_objmgr_vdev *vdev)
+{
+	enum wlan_vdev_state state;
+
+	state = wlan_vdev_mlme_get_state(vdev);
+	if ((state == WLAN_VDEV_S_INIT) ||  (state == WLAN_VDEV_S_UP) ||
+	    (state == WLAN_VDEV_S_STOP))
+		return QDF_STATUS_SUCCESS;
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 #endif

+ 6 - 0
umac/scan/dispatcher/src/wlan_scan_ucfg_api.c

@@ -2186,6 +2186,12 @@ static bool scm_serialization_scan_rules_cb(
 			return false;
 		}
 		break;
+	case WLAN_UMAC_COMP_MLME:
+		if (comp_info->scan_info.is_mlme_op_in_progress) {
+			scm_debug("Cancel scan. MLME operation in progress");
+			return false;
+		}
+		break;
 	default:
 		scm_debug("not handled comp_id %d", comp_id);
 		break;