diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index 7abb44eeab90..8c9054f9e44c 100644 --- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -115,7 +115,8 @@ typedef void (*wlan_serialization_comp_info_cb)( * false, if rules failed and cmd should not be queued */ typedef bool (*wlan_serialization_apply_rules_cb)( - union wlan_serialization_rules_info *comp_info); + union wlan_serialization_rules_info *comp_info, + uint8_t comp_id); /** * enum wlan_umac_cmd_id - Command Type diff --git a/umac/cmn_services/serialization/src/wlan_serialization_api.c b/umac/cmn_services/serialization/src/wlan_serialization_api.c index dc3b490662a9..32b65347df21 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_api.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_api.c @@ -15,7 +15,6 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ - /** * DOC: wlan_serialization_api.c * This file provides an interface for the external components @@ -25,6 +24,8 @@ /* Include files */ #include "wlan_objmgr_psoc_obj.h" +#include "wlan_objmgr_pdev_obj.h" +#include "wlan_objmgr_vdev_obj.h" #include "wlan_serialization_main_i.h" #include "wlan_serialization_utils_i.h" @@ -71,22 +72,6 @@ wlan_serialization_deregister_comp_info_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -enum wlan_serialization_cmd_status -wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev) -{ - serialization_info("vdev scan status entry"); - - return WLAN_SER_CMD_NOT_FOUND; -} - -enum wlan_serialization_cmd_status -wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev) -{ - serialization_info("pdev scan status entry"); - - return WLAN_SER_CMD_NOT_FOUND; -} - enum wlan_serialization_cmd_status wlan_serialization_non_scan_cmd_status(struct wlan_objmgr_pdev *pdev, enum wlan_serialization_cmd_type cmd_id) @@ -143,6 +128,9 @@ wlan_serialization_request(struct wlan_serialization_command *cmd) { bool is_active_cmd_allowed; QDF_STATUS status; + uint8_t comp_id; + struct wlan_serialization_psoc_priv_obj *ser_soc_obj; + union wlan_serialization_rules_info info; serialization_info("serialization queue cmd entry"); if (!cmd) { @@ -155,10 +143,46 @@ wlan_serialization_request(struct wlan_serialization_command *cmd) return WLAN_SER_CMD_DENIED_UNSPECIFIED; } + ser_soc_obj = wlan_serialization_get_obj(cmd); + + /* + * Get Component Info callback by calling + * each registered module + */ + for (comp_id = 0; comp_id < WLAN_UMAC_COMP_ID_MAX; comp_id++) { + if (!ser_soc_obj->comp_info_cb[cmd->cmd_type][comp_id]) + continue; + (ser_soc_obj->comp_info_cb[cmd->cmd_type][comp_id])(&info); + if (!ser_soc_obj->apply_rules_cb[cmd->cmd_type]) + continue; + if (!ser_soc_obj->apply_rules_cb[cmd->cmd_type](&info, comp_id)) + return WLAN_SER_CMD_DENIED_RULES_FAILED; + } + is_active_cmd_allowed = wlan_serialization_is_active_cmd_allowed(cmd); return wlan_serialization_enqueue_cmd(cmd, is_active_cmd_allowed); } +enum wlan_serialization_cmd_status +wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev) +{ + bool cmd_in_active, cmd_in_pending; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj = + wlan_serialization_get_pdev_priv_obj(pdev); + + cmd_in_active = + wlan_serialization_is_cmd_in_vdev_list( + vdev, &ser_pdev_obj->active_scan_list); + + cmd_in_pending = + wlan_serialization_is_cmd_in_vdev_list( + vdev, &ser_pdev_obj->pending_scan_list); + + return wlan_serialization_is_cmd_in_active_pending( + cmd_in_active, cmd_in_pending); +} + void wlan_serialization_flush_cmd( struct wlan_serialization_queued_cmd_info *cmd) { @@ -172,3 +196,21 @@ void wlan_serialization_flush_cmd( return; } +enum wlan_serialization_cmd_status +wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev) +{ + bool cmd_in_active, cmd_in_pending; + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj = + wlan_serialization_get_pdev_priv_obj(pdev); + + cmd_in_active = + wlan_serialization_is_cmd_in_pdev_list( + pdev, &ser_pdev_obj->active_scan_list); + + cmd_in_pending = + wlan_serialization_is_cmd_in_pdev_list( + pdev, &ser_pdev_obj->pending_scan_list); + + return wlan_serialization_is_cmd_in_active_pending( + cmd_in_active, cmd_in_pending); +} diff --git a/umac/cmn_services/serialization/src/wlan_serialization_main.c b/umac/cmn_services/serialization/src/wlan_serialization_main.c index da998e47f269..6ac37b9af2b7 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_main.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_main.c @@ -52,7 +52,8 @@ wlan_serialization_apply_rules_cb_init(struct wlan_objmgr_psoc *psoc) serialization_err("invalid ser_soc_obj"); return QDF_STATUS_E_PERM; } - ser_soc_obj->apply_rules_cb[WLAN_SER_CMD_SCAN] = wlan_apply_scan_rules; + ser_soc_obj->apply_rules_cb[WLAN_SER_CMD_SCAN] = + wlan_serialization_apply_scan_rules; return QDF_STATUS_SUCCESS; } diff --git a/umac/cmn_services/serialization/src/wlan_serialization_rules.c b/umac/cmn_services/serialization/src/wlan_serialization_rules.c index d708da656718..97f3024ba8db 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_rules.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_rules.c @@ -18,7 +18,12 @@ #include "wlan_serialization_rules_i.h" -bool wlan_apply_scan_rules(union wlan_serialization_rules_info *info) +bool +wlan_serialization_apply_scan_rules( + union wlan_serialization_rules_info *info, uint8_t comp_id) { - return true; + switch (comp_id) { + default: + return false; + } } diff --git a/umac/cmn_services/serialization/src/wlan_serialization_rules_i.h b/umac/cmn_services/serialization/src/wlan_serialization_rules_i.h index ca3a287de14c..5035ef27eb04 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_rules_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_rules_i.h @@ -22,14 +22,23 @@ */ #ifndef __WLAN_SERIALIZATION_RULES_I_H #define __WLAN_SERIALIZATION_RULES_I_H -#include "wlan_serialization_api.h" + +#include +#include + /** - * wlan_apply_scan_rules() - Apply scan rules - * @status: return information status fetched from other components - * to determine if the scan command can be allowed for - * execution or should be denied + * wlan_serialization_apply_scan_rules() - apply scan rules callback + * @info: rules info structure + * @comp_id: component Identifier * - * Return: None + * This callback is registered with object manager during initialization and + * when serialization request is called by component, this callback handler + * applies rules depending on component. + * There will be many apply rules callback handlers in future + * + * Return: boolean */ -bool wlan_apply_scan_rules(union wlan_serialization_rules_info *info); +bool +wlan_serialization_apply_scan_rules( + union wlan_serialization_rules_info *info, uint8_t comp_id); #endif diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils.c b/umac/cmn_services/serialization/src/wlan_serialization_utils.c index 4b264857544f..8dd2c7b5025f 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils.c @@ -496,3 +496,84 @@ struct wlan_serialization_pdev_priv_obj *wlan_serialization_get_pdev_priv_obj( return obj; } +struct wlan_serialization_psoc_priv_obj * +wlan_serialization_get_obj(struct wlan_serialization_command *cmd) +{ + struct wlan_serialization_psoc_priv_obj *ser_soc_obj; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_vdev_get_psoc(cmd->vdev); + ser_soc_obj = wlan_serialization_get_psoc_priv_obj(psoc); + + return ser_soc_obj; +} + +bool wlan_serialization_is_cmd_in_vdev_list(struct wlan_objmgr_vdev *vdev, + qdf_list_t *queue) +{ + uint32_t queuelen; + qdf_list_node_t *nnode = NULL; + struct wlan_serialization_command_list *cmd_list = NULL; + QDF_STATUS status; + + queuelen = qdf_list_size(queue); + if (!queuelen) { + serialization_err("invalid queue length"); + return false; + } + + while (queuelen--) { + status = wlan_serialization_get_cmd_from_queue(queue, &nnode); + if (status != QDF_STATUS_SUCCESS) + break; + cmd_list = qdf_container_of(nnode, + struct wlan_serialization_command_list, node); + if (cmd_list->cmd.vdev == vdev) + return true; + }; + + return false; +} + +bool wlan_serialization_is_cmd_in_pdev_list(struct wlan_objmgr_pdev *pdev, + qdf_list_t *queue) +{ + uint32_t queuelen; + qdf_list_node_t *nnode = NULL; + struct wlan_objmgr_pdev *node_pdev = NULL; + struct wlan_serialization_command_list *cmd_list = NULL; + QDF_STATUS status; + + queuelen = qdf_list_size(queue); + if (!queuelen) { + serialization_err("invalid queue length"); + return false; + } + + while (queuelen--) { + status = wlan_serialization_get_cmd_from_queue(queue, &nnode); + if (status != QDF_STATUS_SUCCESS) + break; + cmd_list = qdf_container_of(nnode, + struct wlan_serialization_command_list, node); + node_pdev = wlan_vdev_get_pdev(cmd_list->cmd.vdev); + if (node_pdev == pdev) + return true; + } + + return false; +} + +enum wlan_serialization_cmd_status +wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active, + bool cmd_in_pending) +{ + if (cmd_in_active && cmd_in_pending) + return WLAN_SER_CMDS_IN_ALL_LISTS; + else if (cmd_in_active) + return WLAN_SER_CMD_IN_ACTIVE_LIST; + else if (cmd_in_pending) + return WLAN_SER_CMD_IN_PENDING_LIST; + else + return WLAN_SER_CMD_NOT_FOUND; +} 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 4482198eebcd..1de0670d2369 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h @@ -309,4 +309,47 @@ struct wlan_serialization_psoc_priv_obj *wlan_serialization_get_psoc_priv_obj( struct wlan_serialization_pdev_priv_obj *wlan_serialization_get_pdev_priv_obj( struct wlan_objmgr_pdev *pdev); +/** + * wlan_serialization_get_obj() - Return the component private obj + * @psoc: Pointer to the SERIALIZATION object + * + * Return: Serialization component's level private data object + */ +struct wlan_serialization_psoc_priv_obj * +wlan_serialization_get_obj(struct wlan_serialization_command *cmd); + +/** + * wlan_serialization_is_cmd_in_vdev_list() - Check Node present in VDEV list + * @vdev: Pointer to the VDEV object + * @queue: Pointer to the qdf_list_t + * + * Return: Boolean true or false + */ +bool +wlan_serialization_is_cmd_in_vdev_list( + struct wlan_objmgr_vdev *vdev, qdf_list_t *queue); + +/** + * wlan_serialization_is_cmd_in_pdev_list() - Check Node present in PDEV list + * @pdev: Pointer to the PDEV object + * @queue: Pointer to the qdf_list_t + * + * Return: Boolean true or false + */ +bool +wlan_serialization_is_cmd_in_pdev_list( + struct wlan_objmgr_pdev *pdev, qdf_list_t *queue); + +/** + * wlan_serialization_is_cmd_in_active_pending() - return cmd status + * active/pending queue + * @cmd_in_active: CMD in active list + * @cmd_in_pending: CMD in pending list + * + * Return: enum wlan_serialization_cmd_status + */ +enum wlan_serialization_cmd_status +wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active, + bool cmd_in_pending); + #endif