Răsfoiți Sursa

qcacmn: Implement serialization command rules and processing logic

Initialize rules callback handlers for different components,
Add serialization command processing logic, which calls
component info callback handler to get information about component
state. Component info then is passed to apply rules logic callback
to either deny or enqueue the serialization command

Change-Id: I59be9c5ee71e57fb5737558654222346bea4f1f8
CRs-Fixed: 2000032
Anish Nataraj 8 ani în urmă
părinte
comite
a60ad827cf

+ 2 - 1
umac/cmn_services/serialization/inc/wlan_serialization_api.h

@@ -115,7 +115,8 @@ typedef void (*wlan_serialization_comp_info_cb)(
  *         false, if rules failed and cmd should not be queued
  */
 typedef bool (*wlan_serialization_apply_rules_cb)(
-		union wlan_serialization_rules_info *comp_info);
+		union wlan_serialization_rules_info *comp_info,
+		uint8_t comp_id);
 
 /**
  * enum wlan_umac_cmd_id - Command Type

+ 59 - 17
umac/cmn_services/serialization/src/wlan_serialization_api.c

@@ -15,7 +15,6 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
-
 /**
  * DOC: wlan_serialization_api.c
  * This file provides an interface for the external components
@@ -25,6 +24,8 @@
 
 /* Include files */
 #include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
 #include "wlan_serialization_main_i.h"
 #include "wlan_serialization_utils_i.h"
 
@@ -71,22 +72,6 @@ wlan_serialization_deregister_comp_info_cb(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
-enum wlan_serialization_cmd_status
-wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev)
-{
-	serialization_info("vdev scan status entry");
-
-	return WLAN_SER_CMD_NOT_FOUND;
-}
-
-enum wlan_serialization_cmd_status
-wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev)
-{
-	serialization_info("pdev scan status entry");
-
-	return WLAN_SER_CMD_NOT_FOUND;
-}
-
 enum wlan_serialization_cmd_status
 wlan_serialization_non_scan_cmd_status(struct wlan_objmgr_pdev *pdev,
 		enum wlan_serialization_cmd_type cmd_id)
@@ -143,6 +128,9 @@ wlan_serialization_request(struct wlan_serialization_command *cmd)
 {
 	bool is_active_cmd_allowed;
 	QDF_STATUS status;
+	uint8_t comp_id;
+	struct wlan_serialization_psoc_priv_obj *ser_soc_obj;
+	union wlan_serialization_rules_info info;
 
 	serialization_info("serialization queue cmd entry");
 	if (!cmd) {
@@ -155,10 +143,46 @@ wlan_serialization_request(struct wlan_serialization_command *cmd)
 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
 	}
 
+	ser_soc_obj = wlan_serialization_get_obj(cmd);
+
+	/*
+	 * Get Component Info callback by calling
+	 * each registered module
+	 */
+	for (comp_id = 0; comp_id < WLAN_UMAC_COMP_ID_MAX; comp_id++) {
+		if (!ser_soc_obj->comp_info_cb[cmd->cmd_type][comp_id])
+			continue;
+		(ser_soc_obj->comp_info_cb[cmd->cmd_type][comp_id])(&info);
+		if (!ser_soc_obj->apply_rules_cb[cmd->cmd_type])
+			continue;
+		if (!ser_soc_obj->apply_rules_cb[cmd->cmd_type](&info, comp_id))
+			return WLAN_SER_CMD_DENIED_RULES_FAILED;
+	}
+
 	is_active_cmd_allowed = wlan_serialization_is_active_cmd_allowed(cmd);
 	return wlan_serialization_enqueue_cmd(cmd, is_active_cmd_allowed);
 }
 
+enum wlan_serialization_cmd_status
+wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev)
+{
+	bool cmd_in_active, cmd_in_pending;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj =
+		wlan_serialization_get_pdev_priv_obj(pdev);
+
+	cmd_in_active =
+	wlan_serialization_is_cmd_in_vdev_list(
+			vdev, &ser_pdev_obj->active_scan_list);
+
+	cmd_in_pending =
+	wlan_serialization_is_cmd_in_vdev_list(
+			vdev, &ser_pdev_obj->pending_scan_list);
+
+	return wlan_serialization_is_cmd_in_active_pending(
+			cmd_in_active, cmd_in_pending);
+}
+
 void wlan_serialization_flush_cmd(
 		struct wlan_serialization_queued_cmd_info *cmd)
 {
@@ -172,3 +196,21 @@ void wlan_serialization_flush_cmd(
 	return;
 }
 
+enum wlan_serialization_cmd_status
+wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev)
+{
+	bool cmd_in_active, cmd_in_pending;
+	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj =
+		wlan_serialization_get_pdev_priv_obj(pdev);
+
+	cmd_in_active =
+	wlan_serialization_is_cmd_in_pdev_list(
+			pdev, &ser_pdev_obj->active_scan_list);
+
+	cmd_in_pending =
+	wlan_serialization_is_cmd_in_pdev_list(
+			pdev, &ser_pdev_obj->pending_scan_list);
+
+	return wlan_serialization_is_cmd_in_active_pending(
+			cmd_in_active, cmd_in_pending);
+}

+ 2 - 1
umac/cmn_services/serialization/src/wlan_serialization_main.c

@@ -52,7 +52,8 @@ wlan_serialization_apply_rules_cb_init(struct wlan_objmgr_psoc *psoc)
 		serialization_err("invalid ser_soc_obj");
 		return QDF_STATUS_E_PERM;
 	}
-	ser_soc_obj->apply_rules_cb[WLAN_SER_CMD_SCAN] = wlan_apply_scan_rules;
+	ser_soc_obj->apply_rules_cb[WLAN_SER_CMD_SCAN] =
+			wlan_serialization_apply_scan_rules;
 
 	return QDF_STATUS_SUCCESS;
 }

+ 7 - 2
umac/cmn_services/serialization/src/wlan_serialization_rules.c

@@ -18,7 +18,12 @@
 
 #include "wlan_serialization_rules_i.h"
 
-bool wlan_apply_scan_rules(union wlan_serialization_rules_info *info)
+bool
+wlan_serialization_apply_scan_rules(
+		union wlan_serialization_rules_info *info, uint8_t comp_id)
 {
-	return true;
+	switch (comp_id) {
+	default:
+		return false;
+	}
 }

+ 16 - 7
umac/cmn_services/serialization/src/wlan_serialization_rules_i.h

@@ -22,14 +22,23 @@
  */
 #ifndef __WLAN_SERIALIZATION_RULES_I_H
 #define __WLAN_SERIALIZATION_RULES_I_H
-#include "wlan_serialization_api.h"
+
+#include <qdf_types.h>
+#include <wlan_serialization_api.h>
+
 /**
- * wlan_apply_scan_rules() - Apply scan rules
- * @status: return information status fetched from other components
- *          to determine if the scan command can be allowed for
- *          execution or should be denied
+ * wlan_serialization_apply_scan_rules() - apply scan rules callback
+ * @info: rules info structure
+ * @comp_id: component Identifier
  *
- * Return: None
+ * This callback is registered with object manager during initialization and
+ * when serialization request is called by component, this callback handler
+ * applies rules depending on component.
+ * There will be many apply rules callback handlers in future
+ *
+ * Return: boolean
  */
-bool wlan_apply_scan_rules(union wlan_serialization_rules_info *info);
+bool
+wlan_serialization_apply_scan_rules(
+		union wlan_serialization_rules_info *info, uint8_t comp_id);
 #endif

+ 81 - 0
umac/cmn_services/serialization/src/wlan_serialization_utils.c

@@ -496,3 +496,84 @@ struct wlan_serialization_pdev_priv_obj *wlan_serialization_get_pdev_priv_obj(
 	return obj;
 }
 
+struct wlan_serialization_psoc_priv_obj *
+wlan_serialization_get_obj(struct wlan_serialization_command *cmd)
+{
+	struct wlan_serialization_psoc_priv_obj *ser_soc_obj;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_vdev_get_psoc(cmd->vdev);
+	ser_soc_obj = wlan_serialization_get_psoc_priv_obj(psoc);
+
+	return ser_soc_obj;
+}
+
+bool wlan_serialization_is_cmd_in_vdev_list(struct wlan_objmgr_vdev *vdev,
+					     qdf_list_t *queue)
+{
+	uint32_t queuelen;
+	qdf_list_node_t *nnode = NULL;
+	struct wlan_serialization_command_list *cmd_list = NULL;
+	QDF_STATUS status;
+
+	queuelen = qdf_list_size(queue);
+	if (!queuelen) {
+		serialization_err("invalid queue length");
+		return false;
+	}
+
+	while (queuelen--) {
+		status = wlan_serialization_get_cmd_from_queue(queue, &nnode);
+		if (status != QDF_STATUS_SUCCESS)
+			break;
+		cmd_list = qdf_container_of(nnode,
+				struct wlan_serialization_command_list, node);
+		if (cmd_list->cmd.vdev == vdev)
+			return true;
+	};
+
+	return false;
+}
+
+bool wlan_serialization_is_cmd_in_pdev_list(struct wlan_objmgr_pdev *pdev,
+					     qdf_list_t *queue)
+{
+	uint32_t queuelen;
+	qdf_list_node_t *nnode = NULL;
+	struct wlan_objmgr_pdev *node_pdev = NULL;
+	struct wlan_serialization_command_list *cmd_list = NULL;
+	QDF_STATUS status;
+
+	queuelen = qdf_list_size(queue);
+	if (!queuelen) {
+		serialization_err("invalid queue length");
+		return false;
+	}
+
+	while (queuelen--) {
+		status = wlan_serialization_get_cmd_from_queue(queue, &nnode);
+		if (status != QDF_STATUS_SUCCESS)
+			break;
+		cmd_list = qdf_container_of(nnode,
+				struct wlan_serialization_command_list, node);
+		node_pdev = wlan_vdev_get_pdev(cmd_list->cmd.vdev);
+		if (node_pdev == pdev)
+			return true;
+	}
+
+	return false;
+}
+
+enum wlan_serialization_cmd_status
+wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active,
+					    bool cmd_in_pending)
+{
+	if (cmd_in_active && cmd_in_pending)
+		return WLAN_SER_CMDS_IN_ALL_LISTS;
+	else if (cmd_in_active)
+		return WLAN_SER_CMD_IN_ACTIVE_LIST;
+	else if (cmd_in_pending)
+		return WLAN_SER_CMD_IN_PENDING_LIST;
+	else
+		return WLAN_SER_CMD_NOT_FOUND;
+}

+ 43 - 0
umac/cmn_services/serialization/src/wlan_serialization_utils_i.h

@@ -309,4 +309,47 @@ struct wlan_serialization_psoc_priv_obj *wlan_serialization_get_psoc_priv_obj(
 struct wlan_serialization_pdev_priv_obj *wlan_serialization_get_pdev_priv_obj(
 		struct wlan_objmgr_pdev *pdev);
 
+/**
+ * wlan_serialization_get_obj() - Return the component private obj
+ * @psoc: Pointer to the SERIALIZATION object
+ *
+ * Return: Serialization component's level private data object
+ */
+struct wlan_serialization_psoc_priv_obj *
+wlan_serialization_get_obj(struct wlan_serialization_command *cmd);
+
+/**
+ * wlan_serialization_is_cmd_in_vdev_list() - Check Node present in VDEV list
+ * @vdev: Pointer to the VDEV object
+ * @queue: Pointer to the qdf_list_t
+ *
+ * Return: Boolean true or false
+ */
+bool
+wlan_serialization_is_cmd_in_vdev_list(
+		struct wlan_objmgr_vdev *vdev, qdf_list_t *queue);
+
+/**
+ * wlan_serialization_is_cmd_in_pdev_list() - Check Node present in PDEV list
+ * @pdev: Pointer to the PDEV object
+ * @queue: Pointer to the qdf_list_t
+ *
+ * Return: Boolean true or false
+ */
+bool
+wlan_serialization_is_cmd_in_pdev_list(
+		struct wlan_objmgr_pdev *pdev, qdf_list_t *queue);
+
+/**
+ * wlan_serialization_is_cmd_in_active_pending() - return cmd status
+ *						active/pending queue
+ * @cmd_in_active: CMD in active list
+ * @cmd_in_pending: CMD in pending list
+ *
+ * Return: enum wlan_serialization_cmd_status
+ */
+enum wlan_serialization_cmd_status
+wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active,
+		bool cmd_in_pending);
+
 #endif