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
diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h
index 8002aec..3f4f71b 100644
--- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h
+++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h
@@ -237,6 +237,8 @@
* @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 @@
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,
};
@@ -287,6 +290,18 @@
};
/**
+ * 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
* @cmd_id: Command Identifier
diff --git a/umac/cmn_services/serialization/src/wlan_serialization_api.c b/umac/cmn_services/serialization/src/wlan_serialization_api.c
index 6c3e72e..d2ad0ca 100644
--- a/umac/cmn_services/serialization/src/wlan_serialization_api.c
+++ b/umac/cmn_services/serialization/src/wlan_serialization_api.c
@@ -821,9 +821,11 @@
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 @@
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);
}
diff --git a/umac/cmn_services/serialization/src/wlan_serialization_internal.c b/umac/cmn_services/serialization/src/wlan_serialization_internal.c
index 56509fb..8319347 100644
--- a/umac/cmn_services/serialization/src/wlan_serialization_internal.c
+++ b/umac/cmn_services/serialization/src/wlan_serialization_internal.c
@@ -371,7 +371,8 @@
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 @@
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 @@
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 @@
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 @@
/* 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 @@
*/
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");
diff --git a/umac/cmn_services/serialization/src/wlan_serialization_internal_i.h b/umac/cmn_services/serialization/src/wlan_serialization_internal_i.h
index 2e2e724..1dfd8b7 100644
--- a/umac/cmn_services/serialization/src/wlan_serialization_internal_i.h
+++ b/umac/cmn_services/serialization/src/wlan_serialization_internal_i.h
@@ -205,6 +205,7 @@
* @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 @@
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
diff --git a/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c b/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c
index 4aabd72..e451eda 100644
--- a/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c
+++ b/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c
@@ -461,7 +461,7 @@
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;
@@ -541,6 +541,18 @@
}
/*
+ * 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
* active command separately
diff --git a/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h b/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h
index 5426ae4..d52402b 100644
--- a/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h
+++ b/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 @@
* @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 @@
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
diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils.c b/umac/cmn_services/serialization/src/wlan_serialization_utils.c
index 1f636ab..8395ec5 100644
--- a/umac/cmn_services/serialization/src/wlan_serialization_utils.c
+++ b/umac/cmn_services/serialization/src/wlan_serialization_utils.c
@@ -775,6 +775,30 @@
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,
diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h
index d068122..6b9c82f 100644
--- a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h
+++ b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h
@@ -547,6 +547,19 @@
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
* @cmd_type: Command type to be matched