From f8ed4b9824d22796b5fff6f77abb4ae6d167ba6a Mon Sep 17 00:00:00 2001 From: Santosh Anbu Date: Mon, 24 Jun 2019 15:52:54 +0530 Subject: [PATCH] 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 --- .../inc/wlan_serialization_api.h | 15 +++++++ .../src/wlan_serialization_api.c | 9 ++-- .../src/wlan_serialization_internal.c | 41 ++++++++++++++----- .../src/wlan_serialization_internal_i.h | 4 +- .../src/wlan_serialization_non_scan.c | 14 ++++++- .../src/wlan_serialization_non_scan_i.h | 7 +++- .../src/wlan_serialization_utils.c | 24 +++++++++++ .../src/wlan_serialization_utils_i.h | 13 ++++++ 8 files changed, 109 insertions(+), 18 deletions(-) diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index 8002aec5db61..3f4f71bf4e83 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 @@ 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 diff --git a/umac/cmn_services/serialization/src/wlan_serialization_api.c b/umac/cmn_services/serialization/src/wlan_serialization_api.c index 6c3e72ee741c..d2ad0ca126a4 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 @@ 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); } diff --git a/umac/cmn_services/serialization/src/wlan_serialization_internal.c b/umac/cmn_services/serialization/src/wlan_serialization_internal.c index 56509fbdb6d4..8319347d812e 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 @@ 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"); 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 2e2e724fe38f..1dfd8b793547 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 @@ 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 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 4aabd72c03cf..e451edae4464 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 @@ 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 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 5426ae4c5ee1..d52402bf8efb 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 @@ 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 diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils.c b/umac/cmn_services/serialization/src/wlan_serialization_utils.c index 1f636abd98ea..8395ec572220 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 @@ 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, 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 d0681226ba10..6b9c82f0bfbf 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h +++ b/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