Browse Source

qcacmn: Add API for cancellation of non-blocking cmd

Add API to support cancellation of a non-scan command to match with the
vdev and is a non-blocking serialization command.

Change-Id: I31556ea8f35b9caf314f10eba0f0f655e3fce806
CRs-Fixed: 2481935
Santosh Anbu 5 years ago
parent
commit
f8ed4b9824

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

@@ -237,6 +237,8 @@ enum wlan_serialization_cmd_type {
  * @WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD: Cancel all non scans on a given vdev
  * @WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE: Cancel all non scans on a given vdev
  * and matching cmd type
+ * @WLAN_SER_CANCEL_VDEV_NON_SCAN_NB_CMD: Cancel all non-blocking,
+ * non-scan commands of a given vdev
  * @WLAN_SER_CANCEL_NON_SCAN_CMD: Cancel the given non scan command
  */
 enum wlan_serialization_cancel_type {
@@ -246,6 +248,7 @@ enum wlan_serialization_cancel_type {
 	WLAN_SER_CANCEL_PDEV_NON_SCAN_CMD,
 	WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD,
 	WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE,
+	WLAN_SER_CANCEL_VDEV_NON_SCAN_NB_CMD,
 	WLAN_SER_CANCEL_NON_SCAN_CMD,
 	WLAN_SER_CANCEL_MAX,
 };
@@ -286,6 +289,18 @@ enum wlan_serialization_cmd_status {
 	WLAN_SER_CMD_NOT_FOUND,
 };
 
+/**
+ * enum wlan_ser_cmd_attr - Serialization cmd attribute
+ * @WLAN_SER_CMD_ATTR_NONE - No attribuate associated
+ * @WLAN_SER_CMD_ATTR_BLOCK - Blocking attribute
+ * @WLAN_SER_CMD_ATTR_NONBLOCK - Non-blocking attribute
+ */
+enum wlan_ser_cmd_attr {
+	WLAN_SER_CMD_ATTR_NONE,
+	WLAN_SER_CMD_ATTR_BLOCK,
+	WLAN_SER_CMD_ATTR_NONBLOCK,
+};
+
 /**
  * struct wlan_serialization_command - Command to be serialized
  * @wlan_serialization_cmd_type: Type of command

+ 6 - 3
umac/cmn_services/serialization/src/wlan_serialization_api.c

@@ -821,9 +821,11 @@ void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev)
 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL,
 				 WLAN_SER_CMD_SCAN, true);
 	wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL,
-				     WLAN_SER_CMD_NONSCAN, false);
+				     WLAN_SER_CMD_NONSCAN, false,
+				     WLAN_SER_CMD_ATTR_NONE);
 	wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL,
-				     WLAN_SER_CMD_NONSCAN, true);
+				     WLAN_SER_CMD_NONSCAN, true,
+				     WLAN_SER_CMD_ATTR_NONE);
 }
 
 static inline
@@ -870,7 +872,8 @@ void wlan_serialization_purge_all_pending_cmd_by_vdev_id(
 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
 				 WLAN_SER_CMD_SCAN, false);
 	wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
-				     WLAN_SER_CMD_NONSCAN, false);
+				     WLAN_SER_CMD_NONSCAN, false,
+				     WLAN_SER_CMD_ATTR_NONE);
 
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
 }

+ 30 - 11
umac/cmn_services/serialization/src/wlan_serialization_internal.c

@@ -371,7 +371,8 @@ timer_failed:
 		wlan_serialization_cmd_cancel_handler(
 				ser_pdev_obj, &cmd_list->cmd,
 				NULL, NULL, cmd_list->cmd.cmd_type,
-				WLAN_SERIALIZATION_ACTIVE_QUEUE);
+				WLAN_SERIALIZATION_ACTIVE_QUEUE,
+				WLAN_SER_CMD_ATTR_NONE);
 error:
 	return status;
 }
@@ -847,7 +848,8 @@ wlan_serialization_cmd_cancel_handler(
 		struct wlan_ser_pdev_obj *ser_obj,
 		struct wlan_serialization_command *cmd,
 		struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev,
-		enum wlan_serialization_cmd_type cmd_type, uint8_t queue_type)
+		enum wlan_serialization_cmd_type cmd_type, uint8_t queue_type,
+		enum wlan_ser_cmd_attr cmd_attr)
 {
 	enum wlan_serialization_cmd_status active_status =
 		WLAN_SER_CMD_NOT_FOUND;
@@ -871,7 +873,7 @@ wlan_serialization_cmd_cancel_handler(
 		else
 			active_status = wlan_ser_cancel_non_scan_cmd(
 					ser_obj, pdev, vdev, cmd,
-					cmd_type, true);
+					cmd_type, true, cmd_attr);
 	}
 
 	if (queue_type & WLAN_SERIALIZATION_PENDING_QUEUE) {
@@ -882,7 +884,7 @@ wlan_serialization_cmd_cancel_handler(
 		else
 			pending_status = wlan_ser_cancel_non_scan_cmd(
 					ser_obj, pdev, vdev, cmd,
-					cmd_type, false);
+					cmd_type, false, cmd_attr);
 	}
 
 	if (active_status == WLAN_SER_CMD_IN_ACTIVE_LIST &&
@@ -931,37 +933,43 @@ wlan_serialization_find_and_cancel_cmd(
 		/* remove scan cmd which matches the given cmd struct */
 		status = wlan_serialization_cmd_cancel_handler(
 				ser_obj, cmd, NULL, NULL,
-				WLAN_SER_CMD_SCAN, queue_type);
+				WLAN_SER_CMD_SCAN, queue_type,
+				WLAN_SER_CMD_ATTR_NONE);
 		break;
 	case WLAN_SER_CANCEL_PDEV_SCANS:
 		/* remove all scan cmds which matches the pdev object */
 		status = wlan_serialization_cmd_cancel_handler(
 				ser_obj, NULL, pdev, NULL,
-				WLAN_SER_CMD_SCAN, queue_type);
+				WLAN_SER_CMD_SCAN, queue_type,
+				WLAN_SER_CMD_ATTR_NONE);
 		break;
 	case WLAN_SER_CANCEL_VDEV_SCANS:
 		/* remove all scan cmds which matches the vdev object */
 		status = wlan_serialization_cmd_cancel_handler(
 				ser_obj, NULL, NULL, cmd->vdev,
-				WLAN_SER_CMD_SCAN, queue_type);
+				WLAN_SER_CMD_SCAN, queue_type,
+				WLAN_SER_CMD_ATTR_NONE);
 		break;
 	case WLAN_SER_CANCEL_NON_SCAN_CMD:
 		/* remove nonscan cmd which matches the given cmd */
 		status = wlan_serialization_cmd_cancel_handler(
 				ser_obj, cmd, NULL, NULL,
-				WLAN_SER_CMD_NONSCAN, queue_type);
+				WLAN_SER_CMD_NONSCAN, queue_type,
+				WLAN_SER_CMD_ATTR_NONE);
 		break;
 	case WLAN_SER_CANCEL_PDEV_NON_SCAN_CMD:
 		/* remove all non scan cmds which matches the pdev object */
 		status = wlan_serialization_cmd_cancel_handler(
 				ser_obj, NULL, pdev, NULL,
-				WLAN_SER_CMD_NONSCAN, queue_type);
+				WLAN_SER_CMD_NONSCAN, queue_type,
+				WLAN_SER_CMD_ATTR_NONE);
 		break;
 	case WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD:
 		/* remove all non scan cmds which matches the vdev object */
 		status = wlan_serialization_cmd_cancel_handler(
 				ser_obj, NULL, NULL, cmd->vdev,
-				WLAN_SER_CMD_NONSCAN, queue_type);
+				WLAN_SER_CMD_NONSCAN, queue_type,
+				WLAN_SER_CMD_ATTR_NONE);
 		break;
 	case WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE:
 		/*
@@ -970,7 +978,18 @@ wlan_serialization_find_and_cancel_cmd(
 		 */
 		status = wlan_serialization_cmd_cancel_handler(
 				ser_obj, NULL, NULL, cmd->vdev,
-				cmd->cmd_type, queue_type);
+				cmd->cmd_type, queue_type,
+				WLAN_SER_CMD_ATTR_NONE);
+		break;
+	case WLAN_SER_CANCEL_VDEV_NON_SCAN_NB_CMD:
+		/*
+		 * remove all non-blocking non-scan cmds which matches the given
+		 * vdev
+		 */
+		status = wlan_serialization_cmd_cancel_handler(
+				ser_obj, NULL, NULL, cmd->vdev,
+				WLAN_SER_CMD_NONSCAN, queue_type,
+				WLAN_SER_CMD_ATTR_NONBLOCK);
 		break;
 	default:
 		ser_err("Invalid request");

+ 3 - 1
umac/cmn_services/serialization/src/wlan_serialization_internal_i.h

@@ -205,6 +205,7 @@ wlan_serialization_find_and_cancel_cmd(
  * @vdev: pointer to vdev
  * @cmd_type: pointer to cmd_type
  * @queue_type: If active queue or pending queue
+ * @cmd_attr: Attrbute to indicate a blocking or a non-blocking command
  *
  * This API will decide from which queue, command needs to be cancelled
  * and pass that queue and other parameter required to cancel the command
@@ -219,5 +220,6 @@ wlan_serialization_cmd_cancel_handler(
 				      struct wlan_objmgr_pdev *pdev,
 				      struct wlan_objmgr_vdev *vdev,
 				      enum wlan_serialization_cmd_type cmd_type,
-				      uint8_t queue_type);
+				      uint8_t queue_type,
+				      enum wlan_ser_cmd_attr cmd_attr);
 #endif

+ 13 - 1
umac/cmn_services/serialization/src/wlan_serialization_non_scan.c

@@ -461,7 +461,7 @@ wlan_ser_cancel_non_scan_cmd(
 		struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev,
 		struct wlan_serialization_command *cmd,
 		enum wlan_serialization_cmd_type cmd_type,
-		uint8_t is_active_queue)
+		uint8_t is_active_queue, enum wlan_ser_cmd_attr cmd_attr)
 {
 	qdf_list_t *pdev_queue;
 	qdf_list_t *vdev_queue;
@@ -540,6 +540,18 @@ wlan_ser_cancel_non_scan_cmd(
 			continue;
 		}
 
+		/*
+		 * If a non-blocking cmd is required to be cancelled, but
+		 * the nnode cmd is a blocking cmd then continue with the
+		 * next command in the list else proceed with cmd cancel.
+		 */
+		if ((cmd_attr == WLAN_SER_CMD_ATTR_NONBLOCK) &&
+		    wlan_serialization_match_cmd_blocking(nnode,
+							  WLAN_SER_PDEV_NODE)) {
+			pnode = nnode;
+			continue;
+		}
+
 		/*
 		 * active queue can't be removed directly, requester needs to
 		 * wait for active command response and send remove request for

+ 5 - 2
umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.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
@@ -115,6 +115,8 @@ wlan_ser_remove_non_scan_cmd(struct wlan_ser_pdev_obj *ser_pdev_obj,
  * @cmd_type: Serialization command type to be cancelled
  * @is_active_queue: If the cmd has to be removed from active queue or pending
  *			queue
+ * @cmd_attr: Indicate the attribute of the cmd to be cancelled
+ *      i.e blocking/non-blocking
  *
  * Return: Status specifying the cancel of a command from the given queue
  */
@@ -124,5 +126,6 @@ wlan_ser_cancel_non_scan_cmd(struct wlan_ser_pdev_obj *ser_obj,
 			     struct wlan_objmgr_vdev *vdev,
 			     struct wlan_serialization_command *cmd,
 			     enum wlan_serialization_cmd_type cmd_type,
-			     uint8_t is_active_queue);
+			     uint8_t is_active_queue,
+			     enum wlan_ser_cmd_attr cmd_attr);
 #endif

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

@@ -775,6 +775,30 @@ bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode,
 	return match_found;
 }
 
+bool wlan_serialization_match_cmd_blocking(
+		qdf_list_node_t *nnode,
+		enum wlan_serialization_node node_type)
+{
+	struct wlan_serialization_command_list *cmd_list = NULL;
+	bool match_found = false;
+
+	if (node_type == WLAN_SER_PDEV_NODE)
+		cmd_list =
+			qdf_container_of(nnode,
+					 struct wlan_serialization_command_list,
+					 pdev_node);
+	else
+		cmd_list =
+			qdf_container_of(nnode,
+					 struct wlan_serialization_command_list,
+					 vdev_node);
+
+	if (cmd_list->cmd.is_blocking)
+		match_found = true;
+
+	return match_found;
+}
+
 qdf_list_node_t *
 wlan_serialization_find_cmd(qdf_list_t *queue,
 			    enum wlan_serialization_match_type match_type,

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

@@ -546,6 +546,19 @@ bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode,
 				       struct wlan_objmgr_pdev *pdev,
 				       enum wlan_serialization_node node_type);
 
+/**
+ * wlan_serialization_match_cmd_blocking() - Check for a blocking cmd
+ * @nnode: The node on which the matching has to be done
+ * @node_type: Pdev node or vdev node
+ *
+ * This API will check if the give command of nnode is a blocking command.
+ *
+ * Return: True if blocking command, false otherwise.
+ */
+bool wlan_serialization_match_cmd_blocking(
+		qdf_list_node_t *nnode,
+		enum wlan_serialization_node node_type);
+
 /**
  * wlan_serialization_find_cmd() - Find the cmd matching the given criterias
  * @cmd: Serialization command information