From 3020842b6d808442f2d1f2fae634350fb1b01fc8 Mon Sep 17 00:00:00 2001 From: Balaganapathy Palanisamy Date: Tue, 26 Nov 2019 11:56:47 +0530 Subject: [PATCH] qcacmn: Serialize PDEV CSA channel switch CSA channel switch call directly interacts with VDEV state machine, move CSA restart to go through serialization service. CRs-Fixed: 2598123 Change-Id: Ic0bea64b56f54eed354e11d0873ae4423e365cca --- .../inc/wlan_serialization_api.h | 4 +- umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c | 92 ++++++++++++++++++- umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h | 12 ++- 3 files changed, 105 insertions(+), 3 deletions(-) diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index ddc3493291..96dc23a005 100644 --- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 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 @@ -191,6 +191,7 @@ typedef QDF_STATUS (*wlan_ser_umac_cmd_cb)(void *umac_cmd); * @WLAN_SER_CMD_VDEV_DISCONNECT: Cmd to stop a STA VDEV * @WLAN_SER_CMD_VDEV_RESTART: Cmd to restart a VDEV * @WLAN_SER_CMD_PDEV_RESTART: Cmd to restart all VDEVs of a PDEV + * @WLAN_SER_CMD_PDEV_CSA_RESTART: Cmd to CSA restart all AP VDEVs of a PDEV */ enum wlan_serialization_cmd_type { /* all scan command before non-scan */ @@ -227,6 +228,7 @@ enum wlan_serialization_cmd_type { WLAN_SER_CMD_VDEV_DISCONNECT, WLAN_SER_CMD_VDEV_RESTART, WLAN_SER_CMD_PDEV_RESTART, + WLAN_SER_CMD_PDEV_CSA_RESTART, WLAN_SER_CMD_MAX }; diff --git a/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c b/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c index ef58d56f4b..80ea23bc43 100644 --- a/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c +++ b/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 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 above @@ -268,6 +268,96 @@ wlan_vdev_mlme_ser_disconnect(struct wlan_serialization_command *cmd) return wlan_serialization_request(cmd); } +static void +wlan_mlme_cancel_pending_csa_restart(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = object; + bool *csa_restart_pending = arg; + struct wlan_serialization_command cmd = {0}; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + + cmd.vdev = vdev; + cmd.cmd_id = vdev_id; + cmd.cmd_type = WLAN_SER_CMD_PDEV_CSA_RESTART; + if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &cmd)) { + mlme_debug("Cmd already exist in the pending queue vdev:%u", + vdev_id); + *csa_restart_pending = true; + } + + wlan_vdev_mlme_ser_cancel_request( + vdev, + WLAN_SER_CMD_PDEV_CSA_RESTART, + WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE); +} + +static void +wlan_mlme_check_pdev_restart(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = object; + bool *pdev_restart_pending = arg; + struct wlan_serialization_command cmd = {0}; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + + cmd.vdev = vdev; + cmd.cmd_id = vdev_id; + cmd.cmd_type = WLAN_SER_CMD_PDEV_RESTART; + if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) { + mlme_debug("Pdev restart already in the active queue vdev:%u", + vdev_id); + *pdev_restart_pending = true; + } +} + +enum wlan_serialization_status +wlan_vdev_mlme_ser_pdev_csa_restart(struct wlan_serialization_command *cmd) +{ + struct wlan_objmgr_pdev *pdev; + bool csa_restart_pending = false; + bool pdev_restart_pending = false; + enum wlan_serialization_status ret; + + if (!cmd || !cmd->vdev) { + mlme_err("Null input"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + + if (!wlan_ser_is_vdev_queue_enabled(cmd->vdev)) + return WLAN_SER_CMD_QUEUE_DISABLED; + + /* + * Serialization command filtering logic + * a. Cancel any existing PDEV CSA restart cmd in the pending queue + * b. If there exists PDEV RESTART command in the active queue + * then deny this request + * c. If PDEV CSA RESTART cmd already existed in pending queue + * then enqueue and return already exists + * d. Else enqueue this PDEV CSA RESTART cmd + */ + pdev = wlan_vdev_get_pdev(cmd->vdev); + wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + wlan_mlme_cancel_pending_csa_restart, + &csa_restart_pending, 0, + WLAN_MLME_SER_IF_ID); + + wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + wlan_mlme_check_pdev_restart, + &pdev_restart_pending, 0, + WLAN_MLME_SER_IF_ID); + + if (pdev_restart_pending) + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + + ret = wlan_serialization_request(cmd); + + if (csa_restart_pending && ret == WLAN_SER_CMD_PENDING) + return WLAN_SER_CMD_ALREADY_EXISTS; + + return ret; +} + void wlan_vdev_mlme_ser_remove_request(struct wlan_objmgr_vdev *vdev, uint32_t cmd_id, diff --git a/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h b/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h index f4e7f48569..4f90e30806 100644 --- a/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h +++ b/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 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 @@ -119,4 +119,14 @@ wlan_vdev_mlme_ser_cancel_request(struct wlan_objmgr_vdev *vdev, */ void mlme_ser_inc_act_cmd_timeout(struct wlan_serialization_command *cmd); +/** + * wlan_vdev_mlme_ser_pdev_csa_restart - Add pdev CSA restart cmd to + * serialization + * @cmd: Serialization command + * + * Return: Status of enqueue in the serialization module + */ +enum wlan_serialization_status +wlan_vdev_mlme_ser_pdev_csa_restart(struct wlan_serialization_command *cmd); + #endif /* _WLAN_VDEV_MLME_SER_IF_H_ */