diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h index 5f669ab4f6f5..63316d57f4ce 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h @@ -163,6 +163,7 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_LEGACY_WMA_ID: Legacy WMA operations * @WLAN_SERIALIZATION_ID: Serialization operations * @WLAN_PMO_ID: power manager offload (PMO) ID + * @WLAN_LEGACY_SME_ID: Legacy SME operations * @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array */ typedef enum { @@ -177,6 +178,7 @@ typedef enum { WLAN_LEGACY_WMA_ID = 8, WLAN_SERIALIZATION_ID = 9, WLAN_PMO_ID = 10, + WLAN_LEGACY_SME_ID = 11, WLAN_REF_ID_MAX, } wlan_objmgr_ref_dbgid; diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index 8c9054f9e44c..9f53664e0132 100644 --- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -123,8 +123,70 @@ typedef bool (*wlan_serialization_apply_rules_cb)( * @WLAN_SER_CMD_SCAN: Scan command */ enum wlan_serialization_cmd_type { + /* all scan command before non-scan */ WLAN_SER_CMD_SCAN, - WLAN_SER_CMD_MAX, + WLAN_SER_CMD_SCAN_OTHER, + WLAN_SER_CMD_SCAN_LOST_LINK1, + WLAN_SER_CMD_SCAN_LOST_LINK2, + WLAN_SER_CMD_SCAN_LOST_LINK3, + WLAN_SER_CMD_SCAN_11D_TYPE1, + WLAN_SER_CMD_SCAN_11D_TYPE2, + WLAN_SER_CMD_SCAN_11D_DONE, + WLAN_SER_CMD_SCAN_USER_REQ, + WLAN_SER_CMD_SCAN_FOR_SSID, + WLAN_SER_CMD_SCAN_IDLE_SCAN, + WLAN_SER_CMD_SCAN_PROBE_BSS, + WLAN_SER_CMD_SCAN_ABORT_NORMAL_SCAN, + WLAN_SER_CMD_SCAN_P2P_FIND_PEER, + WLAN_SER_CMD_SCAN_CANDIDATE_FOUND, + WLAN_SER_CMD_REMAIN_ON_CHANNEL, + /* all non-scan command below */ + WLAN_SER_CMD_NONSCAN, + WLAN_SER_CMD_FORCE_DISASSOC, + WLAN_SER_CMD_HDD_ISSUED, + WLAN_SER_CMD_LOST_LINK1, + WLAN_SER_CMD_LOST_LINK2, + WLAN_SER_CMD_LOST_LINK3, + WLAN_SER_CMD_FORCE_DISASSOC_MIC_FAIL, + WLAN_SER_CMD_HDD_ISSUE_REASSOC_SAME_AP, + WLAN_SER_CMD_SME_ISSUE_REASSOC_SAME_AP, + WLAN_SER_CMD_SME_ISSUE_REASSOC_DIFF_AP, + WLAN_SER_CMD_FORCE_DEAUTH, + WLAN_SER_CMD_SME_ISSUE_DISASSOC_FOR_HANDOFF, + WLAN_SER_CMD_SME_ISSUE_ASSOC_TO_SIMILAR_AP, + WLAN_SER_CMD_SME_ISSUE_IBSS_JOIN_FAIL, + WLAN_SER_CMD_FORCE_IBSS_LEAVE, + WLAN_SER_CMD_STOP_BSS, + WLAN_SER_CMD_SME_ISSUE_FT_REASSOC, + WLAN_SER_CMD_FORCE_DISASSOC_STA, + WLAN_SER_CMD_FORCE_DEAUTH_STA, + WLAN_SER_CMD_PERFORM_PRE_AUTH, + WLAN_SER_CMD_LOST_LINK1_ABORT, + WLAN_SER_CMD_LOST_LINK2_ABORT, + WLAN_SER_CMD_LOST_LINK3_ABORT, + WLAN_SER_CMD_WM_STATUS_CHANGE, + WLAN_SER_CMD_SET_KEY, + WLAN_SER_CMD_NDP_INIT_REQ, + WLAN_SER_CMD_NDP_RESP_REQ, + WLAN_SER_CMD_NDP_DATA_END_INIT_REQ, + WLAN_SER_CMD_ENTER_STANDBY, + WLAN_SER_CMD_ADDTS, + WLAN_SER_CMD_DELTS, + WLAN_SER_CMD_TDLS_SEND_MGMT, + WLAN_SER_CMD_TDLS_ADD_PEER, + WLAN_SER_CMD_TDLS_DEL_PEER, + WLAN_SER_CMD_TDLS_LINK_EST, + WLAN_SER_CMD_SET_HW_MODE, + WLAN_SER_CMD_NSS_UPDATE, + WLAN_SER_CMD_SET_DUAL_MAC_CONFIG, + WLAN_SER_CMD_SET_ANTENNA_MODE, + WLAN_SER_CMD_OEM_DATA_REQ, + WLAN_SER_CMD_ENTER_BMPS, + WLAN_SER_CMD_EXIT_BMPS, + WLAN_SER_CMD_ENTER_UAPSD, + WLAN_SER_CMD_EXIT_UAPSD, + WLAN_SER_CMD_EXIT_WOWL, + WLAN_SER_CMD_MAX }; /** @@ -191,7 +253,7 @@ enum wlan_serialization_cmd_status { */ struct wlan_serialization_command { enum wlan_serialization_cmd_type cmd_type; - uint16_t cmd_id; + uint32_t cmd_id; wlan_serialization_cmd_callback cmd_cb; enum wlan_umac_comp_id source; bool is_high_priority; @@ -214,7 +276,7 @@ struct wlan_serialization_command { struct wlan_serialization_queued_cmd_info { enum wlan_umac_comp_id requestor; enum wlan_serialization_cmd_type cmd_type; - uint16_t cmd_id; + uint32_t cmd_id; enum wlan_serialization_cancel_type req_type; union { struct wlan_objmgr_vdev *vdev; @@ -364,4 +426,31 @@ wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev); enum wlan_serialization_cmd_status wlan_serialization_non_scan_cmd_status(struct wlan_objmgr_pdev *pdev, enum wlan_serialization_cmd_type cmd_id); + +/** + * wlan_serialization_is_cmd_present_in_pending_queue() - Return if the command + * is already present in pending queue + * @cmd: pointer to serialization command to check + * + * This API will check if command is present in pending queue. If present + * then return true, so use know that it is duplicated command + * + * Return: true or false + */ +bool wlan_serialization_is_cmd_present_in_pending_queue( + struct wlan_objmgr_psoc *psoc, + struct wlan_serialization_command *cmd); +/** + * wlan_serialization_is_cmd_present_in_active_queue() - Return if the command + * is already present in active queue + * @cmd: pointer to serialization command to check + * + * This API will check if command is present in active queue. If present + * then return true, so use know that it is duplicated command + * + * Return: true or false + */ +bool wlan_serialization_is_cmd_present_in_active_queue( + struct wlan_objmgr_psoc *psoc, + struct wlan_serialization_command *cmd); #endif diff --git a/umac/cmn_services/serialization/src/wlan_serialization_api.c b/umac/cmn_services/serialization/src/wlan_serialization_api.c index 32b65347df21..a4f6c1228345 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_api.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_api.c @@ -29,6 +29,28 @@ #include "wlan_serialization_main_i.h" #include "wlan_serialization_utils_i.h" +bool wlan_serialization_is_cmd_present_in_pending_queue( + struct wlan_objmgr_psoc *psoc, + struct wlan_serialization_command *cmd) +{ + if (!cmd) { + serialization_err("invalid cmd"); + return false; + } + return wlan_serialization_is_cmd_present_queue(cmd, false); +} + +bool wlan_serialization_is_cmd_present_in_active_queue( + struct wlan_objmgr_psoc *psoc, + struct wlan_serialization_command *cmd) +{ + if (!cmd) { + serialization_err("invalid cmd"); + return false; + } + return wlan_serialization_is_cmd_present_queue(cmd, true); +} + QDF_STATUS wlan_serialization_register_comp_info_cb(struct wlan_objmgr_psoc *psoc, enum wlan_umac_comp_id comp_id, diff --git a/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c b/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c index 2303339ec1d2..d80eb7b60c2e 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c @@ -42,7 +42,7 @@ void wlan_serialization_move_pending_to_active( return; } - if (cmd_type == WLAN_SER_CMD_SCAN) + if (cmd_type < WLAN_SER_CMD_NONSCAN) pending_queue = &ser_pdev_obj->pending_scan_list; else pending_queue = &ser_pdev_obj->pending_list; @@ -81,23 +81,7 @@ void wlan_serialization_move_pending_to_active( } -/** - * wlan_serialization_remove_all_cmd_from_queue() - Remove cmd which matches - * @queue: queue from where command needs to be removed - * @ser_pdev_obj: pointer to serialization object - * @pdev: pointer to pdev - * @vdev: pointer to vdev - * @cmd: pointer to cmd - * @is_active_queue: to check if command matching is for active queue - * - * This API will remove one or more commands which match the given parameters - * interms of argument. For example, if user request all commands to removed - * which matches "vdev" then iterate through all commands, find out and remove - * command which matches vdev object. - * - * Return: enum wlan_serialization_cmd_status - */ -static enum wlan_serialization_cmd_status +enum wlan_serialization_cmd_status wlan_serialization_remove_all_cmd_from_queue(qdf_list_t *queue, struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, @@ -258,7 +242,7 @@ wlan_serialization_remove_cmd_from_active_queue(struct wlan_objmgr_psoc *psoc, return; } - if (cmd->cmd_type == WLAN_SER_CMD_SCAN) + if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) queue = &ser_pdev_obj->active_scan_list; else queue = &ser_pdev_obj->active_list; @@ -307,7 +291,7 @@ wlan_serialization_remove_cmd_from_pending_queue(struct wlan_objmgr_psoc *psoc, return; } - if (cmd->cmd_type == WLAN_SER_CMD_SCAN) + if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) queue = &ser_pdev_obj->pending_scan_list; else queue = &ser_pdev_obj->pending_list; @@ -345,11 +329,11 @@ wlan_serialization_is_cmd_removed(struct wlan_objmgr_psoc *psoc, if (check_active_queue) wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, wlan_serialization_remove_cmd_from_active_queue, - cmd, 0, WLAN_SERIALIZATION_ID); + cmd, 1, WLAN_SERIALIZATION_ID); else wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, wlan_serialization_remove_cmd_from_pending_queue, - cmd, 0, WLAN_SERIALIZATION_ID); + cmd, 1, WLAN_SERIALIZATION_ID); if (cmd->vdev == NULL) return true; @@ -402,6 +386,8 @@ wlan_serialization_dequeue_cmd(struct wlan_serialization_command *cmd, serialization_err("ser_pdev_obj is empty"); return status; } + serialization_info("command high_priority[%d] cmd_type[%d] cmd_id[%d]", + cmd->is_high_priority, cmd->cmd_type, cmd->cmd_id); /* * Pass the copy of command, instead of actual command because * wlan_serialization_is_cmd_removed() api cleans the command @@ -484,14 +470,14 @@ wlan_serialization_cmd_cancel_handler( return WLAN_SER_CMD_NOT_FOUND; } /* remove pending commands first */ - if (cmd_type == WLAN_SER_CMD_SCAN) + if (cmd_type < WLAN_SER_CMD_NONSCAN) queue = &ser_obj->pending_scan_list; else queue = &ser_obj->pending_list; /* try and remove first from pending list */ status = wlan_serialization_remove_all_cmd_from_queue(queue, ser_obj, pdev, vdev, cmd, false); - if (cmd_type == WLAN_SER_CMD_SCAN) + if (cmd_type < WLAN_SER_CMD_NONSCAN) queue = &ser_obj->active_scan_list; else queue = &ser_obj->active_list; diff --git a/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c b/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c index 79dd5c439db6..15e2d6e99112 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c @@ -173,9 +173,9 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd, return status; } - serialization_debug("command high_priority[%d] cmd_type[%d] cmd_id[%d]", + serialization_info("command high_priority[%d] cmd_type[%d] cmd_id[%d]", cmd->is_high_priority, cmd->cmd_type, cmd->cmd_id); - if (cmd->cmd_type == WLAN_SER_CMD_SCAN) { + if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) { if (is_cmd_for_active_queue) queue = &ser_pdev_obj->active_scan_list; else @@ -187,6 +187,12 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd, queue = &ser_pdev_obj->pending_list; } + if (wlan_serialization_is_cmd_present_queue(cmd, + is_cmd_for_active_queue)) { + serialization_err("duplicate command, can't enqueue"); + return status; + } + return wlan_serialization_add_cmd_to_given_queue(queue, cmd, psoc, ser_pdev_obj, is_cmd_for_active_queue); } diff --git a/umac/cmn_services/serialization/src/wlan_serialization_main_i.h b/umac/cmn_services/serialization/src/wlan_serialization_main_i.h index 853a65c572c7..c854e2bd983d 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_main_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_main_i.h @@ -33,7 +33,7 @@ #define WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS 8 #define serialization_log(level, args...) \ - QDF_TRACE(QDF_MODULE_ID_SERIALIZATION, level, ## args) + QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args) #define serialization_logfl(level, format, args...) \ serialization_log(level, FL(format), ## args) diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils.c b/umac/cmn_services/serialization/src/wlan_serialization_utils.c index b3a1ec3e70a8..5d438aa25047 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils.c @@ -153,12 +153,15 @@ static void wlan_serialization_generic_timer_callback(void *arg) QDF_ASSERT(0); return; } + + serialization_err("active command timeout for cmd_id[%d]", cmd->cmd_id); if (cmd->cmd_cb) { cmd->cmd_cb(cmd, WLAN_SER_CB_ACTIVE_CMD_TIMEOUT); cmd->cmd_cb(cmd, WLAN_SER_CB_RELEASE_MEM_CMD); } + serialization_err("active command timeout for cmd_id[%d]", cmd->cmd_id); - if (cmd->cmd_type != WLAN_SER_CMD_SCAN) + if (cmd->cmd_type >= WLAN_SER_CMD_NONSCAN) QDF_BUG(0); /* * dequeue cmd API will cleanup and destroy the timer. If it fails to @@ -376,7 +379,7 @@ wlan_serialization_is_active_scan_cmd_allowed(struct wlan_objmgr_pdev *pdev) wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, wlan_serialization_active_scan_cmd_count_handler, - &count, 0, WLAN_SERIALIZATION_ID); + &count, 1, WLAN_SERIALIZATION_ID); if (count < WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS) { serialization_notice("count is [%d]", count); return true; @@ -428,7 +431,7 @@ wlan_serialization_is_active_cmd_allowed(struct wlan_serialization_command *cmd) return false; } - if (cmd->cmd_type == WLAN_SER_CMD_SCAN) + if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) return wlan_serialization_is_active_scan_cmd_allowed(pdev); else return wlan_serialization_is_active_nonscan_cmd_allowed(pdev); @@ -577,3 +580,75 @@ wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active, else return WLAN_SER_CMD_NOT_FOUND; } + +static bool wlan_serialization_is_cmd_present_in_given_queue(qdf_list_t *queue, + struct wlan_serialization_command *cmd) +{ + uint32_t qsize; + QDF_STATUS status; + struct wlan_serialization_command_list *cmd_list = NULL; + qdf_list_node_t *nnode = NULL, *pnode = NULL; + bool found = false; + + qsize = qdf_list_size(queue); + while (qsize--) { + if (!cmd_list) + status = qdf_list_peek_front(queue, &nnode); + else + status = qdf_list_peek_next(queue, pnode, + &nnode); + + if (status != QDF_STATUS_SUCCESS) + break; + + pnode = nnode; + cmd_list = qdf_container_of(nnode, + struct wlan_serialization_command_list, node); + if ((cmd_list->cmd.cmd_id == cmd->cmd_id) && + (cmd_list->cmd.cmd_type == cmd->cmd_type) && + (cmd_list->cmd.vdev == cmd->vdev)) { + found = true; + break; + } + nnode = NULL; + } + return found; +} + +bool wlan_serialization_is_cmd_present_queue( + struct wlan_serialization_command *cmd, + uint8_t is_active_queue) +{ + qdf_list_t *queue; + struct wlan_objmgr_pdev *pdev; + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj; + + if (!cmd) { + serialization_err("invalid params"); + return false; + } + pdev = wlan_serialization_get_pdev_from_cmd(cmd); + if (!pdev) { + serialization_err("invalid pdev"); + return false; + } + ser_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_SERIALIZATION); + if (!ser_pdev_obj) { + serialization_err("invalid ser_pdev_obj"); + return false; + } + if (!is_active_queue) { + if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) + queue = &ser_pdev_obj->pending_scan_list; + else + queue = &ser_pdev_obj->pending_list; + } else { + if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) + queue = &ser_pdev_obj->active_scan_list; + else + queue = &ser_pdev_obj->active_list; + } + + return wlan_serialization_is_cmd_present_in_given_queue(queue, cmd); +} 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 1de0670d2369..3efec8b6e103 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h @@ -352,4 +352,41 @@ enum wlan_serialization_cmd_status wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active, bool cmd_in_pending); +/** + * wlan_serialization_remove_all_cmd_from_queue() - Remove cmd which matches + * @queue: queue from where command needs to be removed + * @ser_pdev_obj: pointer to serialization object + * @pdev: pointer to pdev + * @vdev: pointer to vdev + * @cmd: pointer to cmd + * @is_active_queue: to check if command matching is for active queue + * + * This API will remove one or more commands which match the given parameters + * interms of argument. For example, if user request all commands to removed + * which matches "vdev" then iterate through all commands, find out and remove + * command which matches vdev object. + * + * Return: enum wlan_serialization_cmd_status + */ +enum wlan_serialization_cmd_status +wlan_serialization_remove_all_cmd_from_queue(qdf_list_t *queue, + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, + struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, + struct wlan_serialization_command *cmd, + uint8_t is_active_queue); +/** + * wlan_serialization_is_cmd_present_queue() - Check if same command + * is already present active or pending queue + * @cmd: pointer to command which we need to find + * @is_active_queue: flag to find the command in active or pending queue + * + * This API will check the given command is already present in active or + * pending queue based on flag + * If present then return true otherwise false + * + * Return: true or false + */ +bool wlan_serialization_is_cmd_present_queue( + struct wlan_serialization_command *cmd, + uint8_t is_active_queue); #endif