diff --git a/umac/cmn_services/serialization/src/wlan_serialization_api.c b/umac/cmn_services/serialization/src/wlan_serialization_api.c index 9b7d2d02098f..20e202a526da 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_api.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_api.c @@ -203,9 +203,12 @@ wlan_serialization_request(struct wlan_serialization_command *cmd) { bool is_active_cmd_allowed; QDF_STATUS status; + enum wlan_serialization_status serialization_status; uint8_t comp_id; struct wlan_serialization_psoc_priv_obj *ser_soc_obj; union wlan_serialization_rules_info info; + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj = NULL; + struct wlan_objmgr_pdev *pdev = NULL; serialization_enter(); if (!cmd) { @@ -224,6 +227,18 @@ wlan_serialization_request(struct wlan_serialization_command *cmd) return WLAN_SER_CMD_DENIED_UNSPECIFIED; } + pdev = wlan_serialization_get_pdev_from_cmd(cmd); + if (!pdev) { + serialization_err("pdev is invalid"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + + 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 WLAN_SER_CMD_DENIED_UNSPECIFIED; + } /* * Get Component Info callback by calling * each registered module @@ -240,7 +255,11 @@ wlan_serialization_request(struct wlan_serialization_command *cmd) } is_active_cmd_allowed = wlan_serialization_is_active_cmd_allowed(cmd); - return wlan_serialization_enqueue_cmd(cmd, is_active_cmd_allowed); + serialization_status = wlan_serialization_enqueue_cmd( + cmd, is_active_cmd_allowed); + if (WLAN_SER_CMD_ACTIVE == serialization_status) + wlan_serialization_activate_cmd(cmd->cmd_type, ser_pdev_obj); + return serialization_status; } enum wlan_serialization_cmd_status diff --git a/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c b/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c index 94c361a1e2ef..e0a9e5153506 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c @@ -73,9 +73,11 @@ void wlan_serialization_move_pending_to_active( serialization_err("Can't move cmd to activeQ id-%d type-%d", cmd_list->cmd.cmd_id, cmd_list->cmd.cmd_type); return; - } - wlan_serialization_put_back_to_global_list(pending_queue, + } else { + wlan_serialization_put_back_to_global_list(pending_queue, ser_pdev_obj, cmd_list); + wlan_serialization_activate_cmd(cmd_type, ser_pdev_obj); + } return; } diff --git a/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c b/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c index 1cff45d25bb9..fcc1725fdc10 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c @@ -77,43 +77,80 @@ wlan_serialization_add_cmd_to_given_queue(qdf_list_t *queue, return WLAN_SER_CMD_DENIED_UNSPECIFIED; } - if (is_cmd_for_active_queue) { - /* - * command is already pushed to active queue above - * now start the timer and notify requestor - */ - wlan_serialization_find_and_start_timer(psoc, - &cmd_list->cmd); - if (cmd_list->cmd.cmd_cb) { - /* - * Remember that serialization module may send - * this callback in same context through which it - * received the serialization request. Due to which - * it is caller's responsibility to ensure acquiring - * and releasing its own lock appropriately. - */ - qdf_status = cmd_list->cmd.cmd_cb(&cmd_list->cmd, - WLAN_SER_CB_ACTIVATE_CMD); - if (qdf_status != QDF_STATUS_SUCCESS) { - wlan_serialization_find_and_stop_timer(psoc, - &cmd_list->cmd); - cmd_list->cmd.cmd_cb(&cmd_list->cmd, - WLAN_SER_CB_RELEASE_MEM_CMD); - wlan_serialization_put_back_to_global_list( - queue, ser_pdev_obj, cmd_list); - wlan_serialization_move_pending_to_active( - cmd_list->cmd.cmd_type, - ser_pdev_obj); - } - } + if (is_cmd_for_active_queue) status = WLAN_SER_CMD_ACTIVE; - } else { + else status = WLAN_SER_CMD_PENDING; - } return status; } +void wlan_serialization_activate_cmd(enum wlan_serialization_cmd_type cmd_type, + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj) +{ + QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; + qdf_list_t *queue = NULL; + qdf_list_node_t *nnode = NULL; + struct wlan_serialization_command_list *cmd_list = NULL; + struct wlan_objmgr_psoc *psoc = NULL; + + if (cmd_type < WLAN_SER_CMD_NONSCAN) + queue = &ser_pdev_obj->active_scan_list; + else + queue = &ser_pdev_obj->active_list; + if (qdf_list_empty(queue)) { + serialization_err("nothing in active queue"); + QDF_ASSERT(0); + return; + } + if (QDF_STATUS_SUCCESS != qdf_list_peek_front(queue, &nnode)) { + serialization_err("can't read from active queue"); + serialization_debug("cmd_type - %d", cmd_type); + return; + } + cmd_list = qdf_container_of(nnode, + struct wlan_serialization_command_list, node); + + /* + * command is already pushed to active queue above + * now start the timer and notify requestor + */ + wlan_serialization_find_and_start_timer(psoc, + &cmd_list->cmd); + if (cmd_list && cmd_list->cmd.cmd_cb) { + if (cmd_list->cmd.vdev) { + psoc = wlan_vdev_get_psoc(cmd_list->cmd.vdev); + if (psoc == NULL) { + serialization_err("invalid psoc"); + return; + } + } else { + serialization_err("invalid cmd.vdev"); + return; + } + /* + * Remember that serialization module may send + * this callback in same context through which it + * received the serialization request. Due to which + * it is caller's responsibility to ensure acquiring + * and releasing its own lock appropriately. + */ + qdf_status = cmd_list->cmd.cmd_cb(&cmd_list->cmd, + WLAN_SER_CB_ACTIVATE_CMD); + if (qdf_status != QDF_STATUS_SUCCESS) { + wlan_serialization_find_and_stop_timer(psoc, + &cmd_list->cmd); + cmd_list->cmd.cmd_cb(&cmd_list->cmd, + WLAN_SER_CB_RELEASE_MEM_CMD); + wlan_serialization_put_back_to_global_list( + queue, ser_pdev_obj, cmd_list); + wlan_serialization_move_pending_to_active( + cmd_list->cmd.cmd_type, + ser_pdev_obj); + } + } +} + enum wlan_serialization_status wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd, uint8_t is_cmd_for_active_queue) 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 7dad59512609..c0fdf2b6a128 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h @@ -398,4 +398,14 @@ wlan_serialization_remove_all_cmd_from_queue(qdf_list_t *queue, bool wlan_serialization_is_cmd_present_queue( struct wlan_serialization_command *cmd, uint8_t is_active_queue); + +/** + * wlan_serialization_activate_cmd() - activate first cmd in active queue + * @cmd_type: Command Type + * @ser_pdev_obj: Serialization private pdev object + * + * Return: None + */ +void wlan_serialization_activate_cmd(enum wlan_serialization_cmd_type cmd_type, + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj); #endif