diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index f84aefc240..f8430fe9c2 100644 --- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -638,6 +638,10 @@ enum wlan_serialization_cmd_type { * @WLAN_SER_CANCEL_SINGLE_SCAN: Cancel a single scan with a given ID * @WLAN_SER_CANCEL_PDEV_SCANS: Cancel all the scans on a given pdev * @WLAN_SER_CANCEL_VDEV_SCANS: Cancel all the scans on given vdev + * @WLAN_SER_CANCEL_PDEV_NON_SCAN_CMD: Cancel all non scans on a given pdev + * @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_NON_SCAN_CMD: Cancel the given non scan command */ enum wlan_serialization_cancel_type { @@ -646,6 +650,7 @@ enum wlan_serialization_cancel_type { WLAN_SER_CANCEL_VDEV_SCANS, 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_NON_SCAN_CMD, WLAN_SER_CANCEL_MAX, }; diff --git a/umac/cmn_services/serialization/src/wlan_serialization_internal.c b/umac/cmn_services/serialization/src/wlan_serialization_internal.c index 512884f8da..6b4f7615c7 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_internal.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_internal.c @@ -756,57 +756,48 @@ wlan_serialization_find_and_cancel_cmd( switch (req_type) { case WLAN_SER_CANCEL_SINGLE_SCAN: /* remove scan cmd which matches the given cmd struct */ - status = wlan_serialization_cmd_cancel_handler(ser_obj, - cmd, - NULL, - NULL, - cmd->cmd_type, - queue_type); + status = wlan_serialization_cmd_cancel_handler( + ser_obj, cmd, NULL, NULL, + WLAN_SER_CMD_SCAN, queue_type); 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, - wlan_vdev_get_pdev(cmd->vdev), - NULL, - cmd->cmd_type, - queue_type); + ser_obj, NULL, pdev, NULL, + WLAN_SER_CMD_SCAN, queue_type); 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, - cmd->cmd_type, - queue_type); + status = wlan_serialization_cmd_cancel_handler( + ser_obj, NULL, NULL, cmd->vdev, + WLAN_SER_CMD_SCAN, queue_type); 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, - cmd->cmd_type, - queue_type); + status = wlan_serialization_cmd_cancel_handler( + ser_obj, cmd, NULL, NULL, + WLAN_SER_CMD_NONSCAN, queue_type); 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, - wlan_vdev_get_pdev(cmd->vdev), - NULL, - cmd->cmd_type, - queue_type); + ser_obj, NULL, pdev, NULL, + WLAN_SER_CMD_NONSCAN, queue_type); 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, - cmd->cmd_type, - queue_type); + status = wlan_serialization_cmd_cancel_handler( + ser_obj, NULL, NULL, cmd->vdev, + WLAN_SER_CMD_NONSCAN, queue_type); + break; + case WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE: + /* + * remove all non scan cmds which matches the vdev + * and given cmd type + */ + status = wlan_serialization_cmd_cancel_handler( + ser_obj, NULL, NULL, cmd->vdev, + cmd->cmd_type, queue_type); break; default: ser_err("Invalid request"); 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 e18065fdb1..d22ebb20cf 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c @@ -486,6 +486,15 @@ wlan_ser_cancel_non_scan_cmd( continue; } + if (cmd_type > WLAN_SER_CMD_NONSCAN && vdev && + (!wlan_serialization_match_cmd_type(nnode, cmd_type, + WLAN_SER_PDEV_NODE) || + !wlan_serialization_match_cmd_vdev(nnode, vdev, + 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/mlme/include/wlan_vdev_mlme.h b/umac/mlme/include/wlan_vdev_mlme.h index 9fa37f7276..b20502d783 100644 --- a/umac/mlme/include/wlan_vdev_mlme.h +++ b/umac/mlme/include/wlan_vdev_mlme.h @@ -91,6 +91,8 @@ enum vdev_cmd_type { * of legacy vdev object * @mlme_vdev_ext_hdl_destroy: callback to invoke destroy of legacy * vdev object + * @mlme_vdev_enqueue_exp_cmd: callback to enqueue exception command + * required by serialization */ struct vdev_mlme_ops { QDF_STATUS (*mlme_vdev_validate_basic_params)( @@ -155,6 +157,9 @@ struct vdev_mlme_ops { struct vdev_mlme_obj *vdev_mlme); QDF_STATUS (*mlme_vdev_ext_hdl_destroy)( struct vdev_mlme_obj *vdev_mlme); + QDF_STATUS (*mlme_vdev_enqueue_exp_cmd)( + struct vdev_mlme_obj *vdev_mlme, + uint8_t cmd_type); }; @@ -677,4 +682,27 @@ static inline QDF_STATUS mlme_vdev_ext_hdl_destroy( return ret; } +/** + * mlme_vdev_enqueue_exp_ser_cmd - Enqueue exception serialization cmd + * @vdev_mlme_obj: VDEV MLME comp object + * @cmd_type: Serialization command type + * + * API to enqueue the exception serialization command, used by + * mlme-serialization wrapper layer + * + * Return: SUCCESS on successful enqueuing the command + * Else FAILURE + */ +static inline QDF_STATUS +mlme_vdev_enqueue_exp_ser_cmd(struct vdev_mlme_obj *vdev_mlme, + uint8_t cmd_type) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (vdev_mlme->ops && vdev_mlme->ops->mlme_vdev_enqueue_exp_cmd) + ret = vdev_mlme->ops->mlme_vdev_enqueue_exp_cmd(vdev_mlme, + cmd_type); + return ret; +} + #endif diff --git a/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c b/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c new file mode 100644 index 0000000000..1565a1aaf0 --- /dev/null +++ b/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2018 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 copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * @file wlan_vdev_mlme_ser.c + * This file contains the APIs to support interface between vdev_mlme and + * serialization module + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum wlan_serialization_status +wlan_vdev_mlme_ser_start_bss(struct wlan_serialization_command *cmd) +{ + struct vdev_mlme_obj *vdev_mlme; + + if (!cmd || !cmd->vdev) { + mlme_err("Null input"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + + /* + * Serialization command filtering logic + * a. Cancel any existing start bss cmd in the pending queue + * b. If there is an start bss cmd in active queue and + * there is no stop bss cmd in pending queue, + * then explicitly enqueue a stop bss cmd to avoid back to + * back execution of UP cmd. + * c. Enqueue the new start bss cmd with serialization + */ + wlan_vdev_mlme_ser_cancel_request( + cmd->vdev, + WLAN_SER_CMD_VDEV_START_BSS, + WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE); + + if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) { + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(cmd->vdev); + if (mlme_vdev_enqueue_exp_ser_cmd(vdev_mlme, + WLAN_SER_CMD_VDEV_STOP_BSS)) { + mlme_err("Unable to add the exception cmd request"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + } + + return wlan_serialization_request(cmd); +} + +enum wlan_serialization_status +wlan_vdev_mlme_ser_stop_bss(struct wlan_serialization_command *cmd) +{ + if (!cmd || !cmd->vdev) { + mlme_err("Null input"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + /* + * Serialization command filtering logic + * a.Cancel any existing start/stop/restart command in the pending + * queue. + * b.If there is a stop cmd in active queue then return + * c.Else enqueue the cmd + */ + wlan_vdev_mlme_ser_cancel_request(cmd->vdev, + WLAN_SER_CMD_NONSCAN, + WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD); + + if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) { + mlme_err("Cmd already exist in the active queue"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + + return wlan_serialization_request(cmd); +} + +enum wlan_serialization_status +wlan_vdev_mlme_ser_restart_bss(struct wlan_serialization_command *cmd) +{ + if (!cmd || !cmd->vdev) { + mlme_err("Null input"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + /* + * Serialization command filtering logic + * a. Cancel any existing RESTART cmd in the pending queue + * b. Enqueue the new RESTART cmd + */ + wlan_vdev_mlme_ser_cancel_request( + cmd->vdev, + WLAN_SER_CMD_VDEV_RESTART, + WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE); + return wlan_serialization_request(cmd); +} + +enum wlan_serialization_status +wlan_vdev_mlme_ser_connect(struct wlan_serialization_command *cmd) +{ + struct vdev_mlme_obj *vdev_mlme; + + if (!cmd || !cmd->vdev) { + mlme_err("Null input"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + /* + * Serialization command filtering logic + * a. Cancel any existing CONNECT cmd in the pending queue + * b. If there is an CONNECT cmd in active queue and there is no + * DISCONNECT cmd in pending queue, then explicitly enqueue a + * DISCONNECT cmd to avoid back to back execution of CONNECT cmd. + * c. Enqueue the new CONNECT cmd to the pending queue + */ + wlan_vdev_mlme_ser_cancel_request( + cmd->vdev, + WLAN_SER_CMD_VDEV_CONNECT, + WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE); + + if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) { + vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj( + cmd->vdev, WLAN_UMAC_COMP_MLME); + if (mlme_vdev_enqueue_exp_ser_cmd(vdev_mlme, + WLAN_SER_CMD_VDEV_DISCONNECT)) { + mlme_err("Unable to add the exception cmd request"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + } + + return wlan_serialization_request(cmd); +} + +enum wlan_serialization_status +wlan_vdev_mlme_ser_disconnect(struct wlan_serialization_command *cmd) +{ + if (!cmd || !cmd->vdev) { + mlme_err("Null input"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + /* + * Serialization command filtering logic + * a.Cancel any existing CONNECT/DISCONNECT/RESTART command in the + * pending queue + * b.If there is a DISCONNECT cmd in active queue then return + * c.Else enqueue the DISCONNECT cmd + */ + wlan_vdev_mlme_ser_cancel_request(cmd->vdev, + WLAN_SER_CMD_NONSCAN, + WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD); + + if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) { + mlme_err("Cmd already exist in the active queue"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + + return wlan_serialization_request(cmd); +} + +void +wlan_vdev_mlme_ser_remove_request(struct wlan_objmgr_vdev *vdev, + uint32_t cmd_id, + enum wlan_serialization_cmd_type cmd_type) +{ + struct wlan_serialization_queued_cmd_info cmd = {0}; + + mlme_debug("Remove the cmd type:%d", cmd_type); + + cmd.vdev = vdev; + cmd.cmd_id = cmd_id; + cmd.cmd_type = cmd_type; + cmd.requestor = WLAN_UMAC_COMP_MLME; + cmd.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD; + cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE; + + /* Inform serialization for command completion */ + wlan_serialization_remove_cmd(&cmd); +} + +void +wlan_vdev_mlme_ser_cancel_request(struct wlan_objmgr_vdev *vdev, + enum wlan_serialization_cmd_type cmd_type, + enum wlan_serialization_cancel_type req_type) +{ + struct wlan_serialization_queued_cmd_info cmd = {0}; + + cmd.vdev = vdev; + cmd.cmd_type = cmd_type; + cmd.req_type = req_type; + cmd.requestor = WLAN_UMAC_COMP_MLME; + cmd.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE; + + wlan_serialization_cancel_request(&cmd); +} + +void +mlme_ser_inc_act_cmd_timeout(struct wlan_serialization_command *cmd) +{ + mlme_debug("Increase timeout of cmd type:%d", cmd->cmd_type); + wlan_serialization_update_timer(cmd); +} diff --git a/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h b/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h new file mode 100644 index 0000000000..ba4cb3461f --- /dev/null +++ b/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018 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 copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * @file wlan_vdev_mlme_ser.h + * This file implements the APIs to support interface between vdev_mlme and + * serialization module + */ + +#ifndef _WLAN_VDEV_MLME_SER_IF_H_ +#define _WLAN_VDEV_MLME_SER_IF_H_ + +#include +#include +#include +#include + +/** + * wlan_vdev_mlme_ser_start_bss() - Add start_bss cmd to serialization + * @cmd: Serialization command + * + * Return: Status of enqueue in the serialization module + */ +enum wlan_serialization_status +wlan_vdev_mlme_ser_start_bss(struct wlan_serialization_command *cmd); + +/** + * wlan_vdev_mlme_ser_stop_bss() - Add stop_bss cmd to serialization + * @cmd: Serialization command + * + * Return: Status of enqueue in the serialization module + */ +enum wlan_serialization_status +wlan_vdev_mlme_ser_stop_bss(struct wlan_serialization_command *cmd); + +/** + * wlan_vdev_mlme_ser_restart_bss() - Add restart bss cmd to serialization + * @cmd: Serialization command + * + * Return: Status of enqueue in the serialization module + */ +enum wlan_serialization_status +wlan_vdev_mlme_ser_restart_bss(struct wlan_serialization_command *cmd); + +/** + * wlan_vdev_mlme_ser_connect() - Add connect cmd to serialization + * @cmd: Serialization command + * + * Return: Status of enqueue in the serialization module + */ +enum wlan_serialization_status +wlan_vdev_mlme_ser_connect(struct wlan_serialization_command *cmd); + +/** + * wlan_vdev_mlme_ser_disconnect() - Add disconnect cmd to serialization + * @cmd: Serialization command + * + * Return: Status of enqueue in the serialization module + */ +enum wlan_serialization_status +wlan_vdev_mlme_ser_disconnect(struct wlan_serialization_command *cmd); + +/** + * wlan_vdev_mlme_ser_remove_request() - Remove a request from to + * serialization + * @vdev: Object manager vdev object + * @cmd_id: Serialization command id + * @cmd_type: Serialization command type + * + * Return: void + */ +void +wlan_vdev_mlme_ser_remove_request(struct wlan_objmgr_vdev *vdev, + uint32_t cmd_id, + enum wlan_serialization_cmd_type cmd_type); + +/** + * wlan_vdev_mlme_ser_cancel_request() - Cancel a request from to + * serialization + * @vdev: Object manager vdev object + * @cmd_type: Serialization command type + * @req_type: Type of command cancellation. i.e single/vdev/pdev + * + * Return: void + */ +void +wlan_vdev_mlme_ser_cancel_request(struct wlan_objmgr_vdev *vdev, + enum wlan_serialization_cmd_type cmd_type, + enum wlan_serialization_cancel_type req_type); +/** + * mlme_ser_inc_act_cmd_timeout() - Increase timeout of active cmd + * @cmd: Serialization command + * + * Return: void + */ +void mlme_ser_inc_act_cmd_timeout(struct wlan_serialization_command *cmd); + +#endif /* _WLAN_VDEV_MLME_SER_IF_H_ */