From c4e3592bbfee2a0350a16ca2050c7480276eb73b Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Wed, 1 Feb 2017 14:59:01 -0800 Subject: [PATCH] qcacmn: Serialization Init and DeInit Define folder and file structure for Serialization UMAC convergence component. Define the changes for initializing and de-initializing the serialization component Change-Id: I1074091a74bba8aa7426345f6fb1a5df127f1a59 CRs-Fixed: 2000032 --- qdf/inc/qdf_types.h | 8 + qdf/linux/src/qdf_trace.c | 1 + umac/cmn_services/inc/wlan_cmn.h | 10 +- .../obj_mgr/inc/wlan_objmgr_psoc_obj.h | 18 + .../src/wlan_serialization_dequeue.c | 23 + .../src/wlan_serialization_enqueue.c | 23 + .../src/wlan_serialization_main.c | 394 ++++++++++++++++++ .../src/wlan_serialization_main_i.h | 146 +++++++ .../src/wlan_serialization_rules.c | 23 + .../src/wlan_serialization_rules_i.h | 34 ++ .../src/wlan_serialization_utils.c | 88 ++++ .../src/wlan_serialization_utils_i.h | 134 ++++++ 12 files changed, 899 insertions(+), 3 deletions(-) create mode 100644 umac/cmn_services/serialization/src/wlan_serialization_dequeue.c create mode 100644 umac/cmn_services/serialization/src/wlan_serialization_enqueue.c create mode 100644 umac/cmn_services/serialization/src/wlan_serialization_main.c create mode 100644 umac/cmn_services/serialization/src/wlan_serialization_main_i.h create mode 100644 umac/cmn_services/serialization/src/wlan_serialization_rules.c create mode 100644 umac/cmn_services/serialization/src/wlan_serialization_rules_i.h create mode 100644 umac/cmn_services/serialization/src/wlan_serialization_utils.c create mode 100644 umac/cmn_services/serialization/src/wlan_serialization_utils_i.h diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h index b0db804d5c..55346a3475 100644 --- a/qdf/inc/qdf_types.h +++ b/qdf/inc/qdf_types.h @@ -278,6 +278,13 @@ typedef void (*qdf_timer_func_t)(void *); * @QDF_MODULE_ID_BMI : BMI module ID * @QDF_MODULE_ID_EPPING: EPPING module ID * @QDF_MODULE_ID_QVIT : QVIT module ID + * @QDF_MODULE_ID_DP : Data-path module ID + * @QDF_MODULE_ID_SOC : SOC module ID + * @QDF_MODULE_ID_OS_IF : OS-interface module ID + * @QDF_MODULE_ID_TARGET_IF : targer interface module ID + * @QDF_MODULE_ID_SCHEDULER : schduler module ID + * @QDF_MODULE_ID_MGMT_TXRX : management TX/RX module ID + * @QDF_MODULE_ID_SERIALIZATION : serialization module ID * @QDF_MODULE_ID_ANY : anything * @QDF_MODULE_ID_MAX : Max place holder module ID */ @@ -357,6 +364,7 @@ typedef enum { QDF_MODULE_ID_TARGET_IF, QDF_MODULE_ID_SCHEDULER, QDF_MODULE_ID_MGMT_TXRX, + QDF_MODULE_ID_SERIALIZATION, QDF_MODULE_ID_ANY, QDF_MODULE_ID_MAX, } QDF_MODULE_ID; diff --git a/qdf/linux/src/qdf_trace.c b/qdf/linux/src/qdf_trace.c index 7b234f38f8..75390229a0 100644 --- a/qdf/linux/src/qdf_trace.c +++ b/qdf/linux/src/qdf_trace.c @@ -87,6 +87,7 @@ module_trace_info g_qdf_trace_info[QDF_MODULE_ID_MAX] = { [QDF_MODULE_ID_HIF] = {QDF_DEFAULT_TRACE_LEVEL, "HIF"}, [QDF_MODULE_ID_TXRX] = {QDF_DEFAULT_TRACE_LEVEL, "TRX"}, [QDF_MODULE_ID_HTT] = {QDF_DEFAULT_TRACE_LEVEL, "HTT"}, + [QDF_MODULE_ID_SERIALIZATION] = {QDF_DEFAULT_TRACE_LEVEL, "SER"}, }; /* Static and Global variables */ diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h index bb77a9a4a4..b49d7092b4 100644 --- a/umac/cmn_services/inc/wlan_cmn.h +++ b/umac/cmn_services/inc/wlan_cmn.h @@ -77,14 +77,18 @@ * @WLAN_UMAC_COMP_MLME: MLME * @WLAN_UMAC_COMP_SCAN: SCAN MGR * @WLAN_UMAC_COMP_MGMT_TXRX: MGMT Tx/Rx + * @WLAN_UMAC_COMP_SERIALIZATION: Serialization + * @WLAN_UMAC_COMP_ID_MAX: Maximum components in UMAC * * This id is static. * On Adding new component, new id has to be assigned */ enum wlan_umac_comp_id { - WLAN_UMAC_COMP_MLME = 0, - WLAN_UMAC_COMP_SCAN = 1, - WLAN_UMAC_COMP_MGMT_TXRX = 2, + WLAN_UMAC_COMP_MLME = 0, + WLAN_UMAC_COMP_SCAN = 1, + WLAN_UMAC_COMP_MGMT_TXRX = 2, + WLAN_UMAC_COMP_SERIALIZATION = 3, + WLAN_UMAC_COMP_ID_MAX, }; /** diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h index 25a8c47d63..f5d6cc0d88 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h @@ -791,4 +791,22 @@ static inline uint8_t *wlan_psoc_get_hw_macaddr(struct wlan_objmgr_psoc *psoc) */ void *wlan_objmgr_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc, enum wlan_umac_comp_id id); +/** + * wlan_psoc_get_pdev_count() - get pdev count for psoc + * @psoc: PSOC object + * + * API to get number of pdev's attached to the psoc + * + * Caller need to acquire lock with wlan_psoc_obj_lock() + * + * Return: number of pdev's + */ +static inline uint8_t wlan_psoc_get_pdev_count(struct wlan_objmgr_psoc *psoc) +{ + /* This API is invoked with lock acquired, do not add log prints */ + if (psoc == NULL) + return 0; + + return psoc->soc_objmgr.wlan_pdev_count; +} #endif /* _WLAN_OBJMGR_PSOC_OBJ_H_*/ diff --git a/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c b/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c new file mode 100644 index 0000000000..c1b01471c8 --- /dev/null +++ b/umac/cmn_services/serialization/src/wlan_serialization_dequeue.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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. + */ +/** + * DOC: wlan_serialization_dequeue.c + * This file defines the routines which are pertinent + * to the dequeue of commands. + */ + diff --git a/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c b/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c new file mode 100644 index 0000000000..55ee365b0a --- /dev/null +++ b/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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. + */ +/** + * DOC: wlan_serialization_enqueue.c + * This file defines the routines which are pertinent + * to the queuing of commands. + */ + diff --git a/umac/cmn_services/serialization/src/wlan_serialization_main.c b/umac/cmn_services/serialization/src/wlan_serialization_main.c new file mode 100644 index 0000000000..e122f30394 --- /dev/null +++ b/umac/cmn_services/serialization/src/wlan_serialization_main.c @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2017 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. + */ + +/** + * DOC: wlan_serialization_main.c + * This file defines the important functions pertinent to + * serialization to initialize and de-initialize the + * component. + */ +#include "qdf_status.h" +#include "qdf_list.h" +#include "wlan_objmgr_cmn.h" +#include "wlan_objmgr_global_obj.h" +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_serialization_main_i.h" +#include "wlan_serialization_rules_i.h" + +/** + * wlan_serialization_apply_rules_cb_init() - Apply rule callback init + * @psoc: PSOC object + * + * Apply rules Command callback registration function is + * called from component during its initialization + * It initializes all cmd callback handler for given CMDIDX in + * 1-D Array + * + * Return: QDF Status + */ +static QDF_STATUS +wlan_serialization_apply_rules_cb_init(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_serialization_psoc_priv_obj *ser_soc_obj = + wlan_serialization_get_psoc_priv_obj(psoc); + + if (ser_soc_obj == NULL) { + serialization_alert("Serialization PSOC private obj is NULL"); + return QDF_STATUS_E_PERM; + } + ser_soc_obj->apply_rules_cb[WLAN_SER_CMD_SCAN] = wlan_apply_scan_rules; + + return QDF_STATUS_SUCCESS; +} + + +/** + * wlan_serialization_apply_rules_cb_deinit() - Apply rule callback deinit + * @psoc: PSOC object + * + * Apply rules Command callback De-registration function + * called from component during its initialization + * It initializes all cmd callback handler for given CMDIDX in + * 1-D Array + * + * Return: QDF Status + */ +static QDF_STATUS +wlan_serialization_apply_rules_cb_deinit(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_serialization_psoc_priv_obj *ser_soc_obj = + wlan_serialization_get_psoc_priv_obj(psoc); + uint8_t i; + + if (ser_soc_obj == NULL) { + serialization_alert("Serialization PSOC private obj is NULL"); + return QDF_STATUS_E_PERM; + } + for (i = 0; i < WLAN_SER_CMD_MAX; i++) + ser_soc_obj->apply_rules_cb[i] = NULL; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_serialization_psoc_close(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct wlan_serialization_psoc_priv_obj *ser_soc_obj = + wlan_serialization_get_psoc_priv_obj(psoc); + + qdf_mem_free(ser_soc_obj->timers); + ser_soc_obj->timers = NULL; + ser_soc_obj->max_active_cmds = 0; + status = wlan_serialization_apply_rules_cb_deinit(psoc); + + return status; +} + +QDF_STATUS wlan_serialization_psoc_open(struct wlan_objmgr_psoc *psoc) +{ + uint8_t pdev_count; + QDF_STATUS status; + struct wlan_serialization_psoc_priv_obj *ser_soc_obj = + wlan_serialization_get_psoc_priv_obj(psoc); + + /* TODO:Get WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS frm service ready */ + pdev_count = wlan_psoc_get_pdev_count(psoc); + ser_soc_obj->max_active_cmds = WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS + + pdev_count; + ser_soc_obj->timers = + qdf_mem_malloc(sizeof(struct wlan_serialization_timer) * + ser_soc_obj->max_active_cmds); + if (NULL == ser_soc_obj->timers) { + serialization_alert("Mem alloc failed for ser timers"); + return QDF_STATUS_E_NOMEM; + } + status = wlan_serialization_apply_rules_cb_init(psoc); + + return status; +} + +QDF_STATUS wlan_serialization_psoc_obj_create_notification( + struct wlan_objmgr_psoc *psoc, void *arg_list) +{ + struct wlan_serialization_psoc_priv_obj *soc_ser_obj; + + soc_ser_obj = + qdf_mem_malloc(sizeof(*soc_ser_obj)); + if (NULL == soc_ser_obj) { + serialization_alert("Mem alloc failed for ser psoc priv obj"); + return QDF_STATUS_E_NOMEM; + } + wlan_objmgr_psoc_component_obj_attach(psoc, + WLAN_UMAC_COMP_SERIALIZATION, (void *)soc_ser_obj, + QDF_STATUS_SUCCESS); + serialization_info("ser psoc obj created"); + + return QDF_STATUS_SUCCESS; +} + +/** + * wlan_serialization_destroy_cmd_pool() - Destroy the global cmd pool + * @ser_pdev_obj: Serialization private pdev object + * + * Return: None + */ +static void wlan_serialization_destroy_cmd_pool( + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj) +{ + + qdf_list_node_t *node = NULL; + struct wlan_serialization_command_list *cmd_list_node; + + while (!qdf_list_empty(&ser_pdev_obj->global_cmd_pool_list)) { + qdf_list_remove_front(&ser_pdev_obj->global_cmd_pool_list, + &node); + cmd_list_node = (struct wlan_serialization_command_list *)node; + serialization_info("Node being freed from global pool %p", + cmd_list_node); + qdf_mem_free(cmd_list_node); + + } + qdf_list_destroy(&ser_pdev_obj->global_cmd_pool_list); +} + +/** + * wlan_serialization_create_cmd_pool() - Create the global cmd pool + * @pdev: PDEV Object + * @ser_pdev_obj: Serialization private pdev object + * + * Global command pool of memory is created here. + * It is safe to allocate memory individually for each command rather than + * requesting for a huge chunk of memory at once. + * + * The individual command nodes allocated above will keep moving between + * the active, pending and global pool lists dynamically, but all the + * memory will be freed during driver unload only. + * + * Return: QDF Status + */ +static QDF_STATUS +wlan_serialization_create_cmd_pool(struct wlan_objmgr_pdev *pdev, + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj) +{ + struct wlan_serialization_command_list *cmd_list_ptr; + uint8_t i; + + for (i = 0; i < WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS; i++) { + cmd_list_ptr = qdf_mem_malloc(sizeof(*cmd_list_ptr)); + if (NULL == cmd_list_ptr) { + serialization_alert("Mem alloc failed for cmd node"); + wlan_serialization_destroy_cmd_pool(ser_pdev_obj); + return QDF_STATUS_E_NOMEM; + } + qdf_list_insert_back( + &ser_pdev_obj->global_cmd_pool_list, + &cmd_list_ptr->node); + serialization_info("Created node at %p and inserted to pool", + cmd_list_ptr); + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_serialization_pdev_obj_create_notification( + struct wlan_objmgr_pdev *pdev, void *arg_list) +{ + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj; + QDF_STATUS status; + + ser_pdev_obj = + qdf_mem_malloc(sizeof(*ser_pdev_obj)); + if (NULL == ser_pdev_obj) { + serialization_alert("Mem alloc failed for ser pdev obj"); + return QDF_STATUS_E_NOMEM; + } + qdf_list_create(&ser_pdev_obj->active_list, + WLAN_SERIALIZATION_MAX_ACTIVE_CMDS); + qdf_list_create(&ser_pdev_obj->pending_list, + WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS); + qdf_list_create(&ser_pdev_obj->active_scan_list, + WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS); + qdf_list_create(&ser_pdev_obj->pending_scan_list, + WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS); + qdf_list_create(&ser_pdev_obj->global_cmd_pool_list, + WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS); + status = wlan_serialization_create_cmd_pool(pdev, ser_pdev_obj); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("ser_pdev_obj failed status %d", status); + return status; + } + status = wlan_objmgr_pdev_component_obj_attach(pdev, + WLAN_UMAC_COMP_SERIALIZATION, (void *)ser_pdev_obj, + QDF_STATUS_SUCCESS); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("serialization pdev obj attach failed"); + return status; + } + + return status; +} + +QDF_STATUS wlan_serialization_psoc_obj_destroy_notification( + struct wlan_objmgr_psoc *psoc, void *arg_list) +{ + QDF_STATUS status; + struct wlan_serialization_psoc_priv_obj *ser_soc_obj = + wlan_serialization_get_psoc_priv_obj(psoc); + + if (NULL == ser_soc_obj) { + serialization_err("ser psoc private obj is NULL"); + return QDF_STATUS_E_FAULT; + } + status = wlan_objmgr_psoc_component_obj_detach(psoc, + WLAN_UMAC_COMP_SERIALIZATION, + ser_soc_obj); + if (status != QDF_STATUS_SUCCESS) + serialization_err("ser psoc private obj detach failed"); + serialization_info("ser psoc obj deleted with status %d", status); + qdf_mem_free(ser_soc_obj); + + return status; +} + +QDF_STATUS wlan_serialization_pdev_obj_destroy_notification( + struct wlan_objmgr_pdev *pdev, void *arg_list) +{ + QDF_STATUS status; + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj = + wlan_serialization_get_pdev_priv_obj(pdev); + + status = wlan_objmgr_pdev_component_obj_detach(pdev, + WLAN_UMAC_COMP_SERIALIZATION, + (void *)ser_pdev_obj); + wlan_serialization_destroy_list(ser_pdev_obj, + &ser_pdev_obj->active_list); + wlan_serialization_destroy_list(ser_pdev_obj, + &ser_pdev_obj->pending_list); + wlan_serialization_destroy_list(ser_pdev_obj, + &ser_pdev_obj->active_scan_list); + wlan_serialization_destroy_list(ser_pdev_obj, + &ser_pdev_obj->pending_scan_list); + wlan_serialization_destroy_cmd_pool(ser_pdev_obj); + serialization_info("ser pdev obj deleted with status %d", status); + qdf_mem_free(ser_pdev_obj); + + return status; +} + +QDF_STATUS wlan_serialization_init(void) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = wlan_objmgr_register_psoc_create_handler( + WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_psoc_obj_create_notification, NULL); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("Failed to reg soc ser obj create handler"); + goto err_psoc_create; + } + + status = wlan_objmgr_register_psoc_delete_handler( + WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_psoc_obj_destroy_notification, NULL); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("Failed to reg soc ser obj delete handler"); + goto err_psoc_delete; + } + + status = wlan_objmgr_register_pdev_create_handler( + WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_pdev_obj_create_notification, NULL); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("Failed to reg pdev ser obj create handler"); + goto err_pdev_create; + } + + status = wlan_objmgr_register_pdev_delete_handler( + WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_pdev_obj_destroy_notification, NULL); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("Failed to reg pdev ser obj delete handler"); + goto err_pdev_delete; + } + + serialization_info("serialization handlers registered with obj mgr"); + + return QDF_STATUS_SUCCESS; + +err_pdev_delete: + wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_pdev_obj_create_notification, NULL); +err_pdev_create: + wlan_objmgr_unregister_psoc_delete_handler(WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_psoc_obj_destroy_notification, NULL); +err_psoc_delete: + wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_psoc_obj_create_notification, NULL); +err_psoc_create: + return status; + +} + +QDF_STATUS wlan_serialization_deinit(void) +{ + QDF_STATUS status; + QDF_STATUS ret_status = QDF_STATUS_SUCCESS; + + status = wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_psoc_obj_create_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("unreg fail for psoc ser obj create notf:%d", + status); + ret_status = QDF_STATUS_E_FAILURE; + } + status = wlan_objmgr_unregister_psoc_delete_handler( + WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_psoc_obj_destroy_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("unreg fail for psoc ser obj destroy notf:%d", + status); + ret_status = QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_unregister_pdev_create_handler( + WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_pdev_obj_create_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("unreg fail for pdev ser obj create notf:%d", + status); + ret_status = QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_unregister_pdev_delete_handler( + WLAN_UMAC_COMP_SERIALIZATION, + wlan_serialization_pdev_obj_destroy_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + serialization_err("unreg fail for pdev ser destory notf:%d", + status); + ret_status = QDF_STATUS_E_FAILURE; + } + + serialization_alert("deregistered callbacks with obj mgr successfully"); + + return ret_status; +} diff --git a/umac/cmn_services/serialization/src/wlan_serialization_main_i.h b/umac/cmn_services/serialization/src/wlan_serialization_main_i.h new file mode 100644 index 0000000000..8cb199c219 --- /dev/null +++ b/umac/cmn_services/serialization/src/wlan_serialization_main_i.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2017 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. + */ +/** + * DOC: wlan_serialization_main.h + * This file contains all the prototype definitions necessary for the + * serialization component's internal functions + */ +#ifndef __WLAN_SERIALIZATION_MAIN_I_H +#define __WLAN_SERIALIZATION_MAIN_I_H +/* Include files */ +#include "wlan_objmgr_cmn.h" +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_objmgr_pdev_obj.h" +#include "wlan_serialization_api.h" +#include "wlan_serialization_rules_i.h" +#include "wlan_serialization_utils_i.h" +#include "qdf_mc_timer.h" + +#define WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS 24 +#define WLAN_SERIALIZATION_MAX_ACTIVE_CMDS 1 +#define WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS 8 + +#define serialization_log(level, args...) \ + QDF_TRACE(QDF_MODULE_ID_SERIALIZATION, level, ## args) +#define serialization_logfl(level, format, args...) \ + serialization_log(level, FL(format), ## args) + +#define serialization_alert(format, args...) \ + serialization_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) +#define serialization_err(format, args...) \ + serialization_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) +#define serialization_warn(format, args...) \ + serialization_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) +#define serialization_notice(format, args...) \ + serialization_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) +#define serialization_info(format, args...) \ + serialization_logfl(QDF_TRACE_LEVEL_INFO_HIGH, format, ## args) +#define serialization_debug(format, args...) \ + serialization_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) + + +/** + * struct wlan_serialization_timer - Timer used for serialization + * @cmd: Cmd to which the timer is linked + * @timer: Timer associated with the command + * + * Timers are allocated statically during init, one each for the + * maximum active commands permitted in the system. Once a cmd is + * moved from pending list to active list, the timer is activated + * and once the cmd is completed, the timer is cancelled. Timer is + * also cancelled if the command is aborted + * + * The timers are maintained per psoc. A timer is associated to + * unique combination of pdev, cmd_type and cmd_id. + */ +struct wlan_serialization_timer { + struct wlan_serialization_command *cmd; + qdf_mc_timer_t timer; +}; + +/** + * struct wlan_serialization_command_list - List of commands to be serialized + * @node: Node identifier in the list + * @cmd: Command to be serialized + */ +struct wlan_serialization_command_list { + qdf_list_node_t node; + struct wlan_serialization_command cmd; +}; + +/** + * wlan_serialization_psoc_obj_create_notification() - PSOC obj create callback + * @psoc: PSOC object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization and + * when obj manager gets its turn to create the object, it would notify each + * component with the corresponding callback registered to inform the + * completion of the creation of the respective object. + * + * Return: QDF Status + */ +QDF_STATUS wlan_serialization_psoc_obj_create_notification( + struct wlan_objmgr_psoc *psoc, void *arg_list); + +/** + * wlan_serialization_psoc_obj_destroy_notification() - PSOC obj delete callback + * @psoc: PSOC object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization and + * when obj manager gets its turn to delete the object, it would notify each + * component with the corresponding callback registered to inform the + * completion of the deletion of the respective object. + * + * Return: QDF Status + */ +QDF_STATUS wlan_serialization_psoc_obj_destroy_notification( + struct wlan_objmgr_psoc *psoc, void *arg_list); + +/** + * wlan_serialization_pdev_obj_create_notification() - PDEV obj create callback + * @psoc: PDEV object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization and + * when obj manager gets its turn to create the object, it would notify each + * component with the corresponding callback registered to inform the + * completion of the creation of the respective object. + * + * Return: QDF Status + */ +QDF_STATUS wlan_serialization_pdev_obj_create_notification( + struct wlan_objmgr_pdev *pdev, void *arg_list); + +/** + * wlan_serialization_pdev_obj_destroy_notification() - PSOC obj delete callback + * @pdev: PDEV object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization and + * when obj manager gets its turn to delete the object, it would notify each + * component with the corresponding callback registered to inform the + * completion of the deletion of the respective object. + * + * Return: QDF Status + */ +QDF_STATUS wlan_serialization_pdev_obj_destroy_notification( + struct wlan_objmgr_pdev *pdev, void *arg_list); + +#endif diff --git a/umac/cmn_services/serialization/src/wlan_serialization_rules.c b/umac/cmn_services/serialization/src/wlan_serialization_rules.c new file mode 100644 index 0000000000..67477e54b9 --- /dev/null +++ b/umac/cmn_services/serialization/src/wlan_serialization_rules.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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. + */ + +#include "wlan_serialization_main_i.h" +bool wlan_apply_scan_rules(union wlan_serialization_rules_info *info) +{ + return true; +} diff --git a/umac/cmn_services/serialization/src/wlan_serialization_rules_i.h b/umac/cmn_services/serialization/src/wlan_serialization_rules_i.h new file mode 100644 index 0000000000..c2ff058681 --- /dev/null +++ b/umac/cmn_services/serialization/src/wlan_serialization_rules_i.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017 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. + */ +/** + * DOC: wlan_serialization_rules_i.h + * This file defines the prototypes for the rules related data + * pertinent to the serialization component. + */ +#ifndef __WLAN_SERIALIZATION_RULES_I_H +#define __WLAN_SERIALIZATION_RULES_I_H +/** + * 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 + * + * Return: None + */ +bool wlan_apply_scan_rules(union wlan_serialization_rules_info *info); +#endif diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils.c b/umac/cmn_services/serialization/src/wlan_serialization_utils.c new file mode 100644 index 0000000000..2dbec9591e --- /dev/null +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017 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. + */ +/** + * DOC: wlan_serialization_utils.c + * This file defines the utility helper functions for serialization component. + */ + +#include "wlan_serialization_utils_i.h" + +QDF_STATUS wlan_serialization_validate_cmd( + enum wlan_umac_comp_id comp_id, + enum wlan_serialization_cmd_type cmd_type) +{ + serialization_info("validate cmd_type:%d, comp_id:%d", + cmd_type, comp_id); + if (cmd_type < 0 || comp_id < 0 || + cmd_type >= WLAN_SER_CMD_MAX || + comp_id >= WLAN_UMAC_COMP_ID_MAX) { + serialization_err("Invalid cmd or comp passed"); + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + +void wlan_serialization_release_list_cmds( + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, + qdf_list_t *list) +{ + qdf_list_node_t *node = NULL; + + while (!qdf_list_empty(list)) { + qdf_list_remove_front(list, &node); + qdf_list_insert_back(&ser_pdev_obj->global_cmd_pool_list, node); + } + + return; +} + +void wlan_serialization_destroy_list( + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, + qdf_list_t *list) +{ + wlan_serialization_release_list_cmds(ser_pdev_obj, list); + qdf_list_destroy(list); +} + +struct wlan_serialization_psoc_priv_obj *wlan_serialization_get_psoc_priv_obj( + struct wlan_objmgr_psoc *psoc) +{ + struct wlan_serialization_psoc_priv_obj *ser_soc_obj; + wlan_psoc_obj_lock(psoc); + ser_soc_obj = (struct wlan_serialization_psoc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_SERIALIZATION); + wlan_psoc_obj_unlock(psoc); + + return ser_soc_obj; +} + +struct wlan_serialization_pdev_priv_obj *wlan_serialization_get_pdev_priv_obj( + struct wlan_objmgr_pdev *pdev) +{ + struct wlan_serialization_pdev_priv_obj *obj; + wlan_pdev_obj_lock(pdev); + obj = (struct wlan_serialization_pdev_priv_obj *) + wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_SERIALIZATION); + wlan_pdev_obj_unlock(pdev); + + return obj; +} + diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h new file mode 100644 index 0000000000..eeae06956b --- /dev/null +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2017 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. + */ +/** + * DOC: wlan_serialization_utils_i.h + * This file defines the prototypes for the utility helper functions + * for the serialization component. + */ +#ifndef __WLAN_SERIALIZATION_UTILS_I_H +#define __WLAN_SERIALIZATION_UTILS_I_H +/* Include files */ +#include "qdf_status.h" +#include "qdf_list.h" +#include "wlan_objmgr_cmn.h" +#include "wlan_objmgr_global_obj.h" +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_serialization_main_i.h" +#include "wlan_serialization_rules_i.h" + +/** + * struct wlan_serialization_psoc_priv_obj - psoc obj data for serialization + * @wlan_serialization_module_state_cb - module level callback + * @wlan_serialization_apply_rules_cb - pointer to apply rules on the cmd + * @timers - Timers associated with the active commands + * @max_axtive_cmds - Maximum active commands allowed + * + * Serialization component takes a command as input and checks whether to + * allow/deny the command. It will use the module level callback registered + * by each component to fetch the information needed to apply the rules. + * Once the information is available, the rules callback registered for each + * command internally by serialization will be applied to determine the + * checkpoint for the command. If allowed, command will be put into active/ + * pending list and each active command is associated with a timer. + */ +struct wlan_serialization_psoc_priv_obj { + wlan_serialization_comp_info_cb comp_info_cb[ + WLAN_SER_CMD_MAX][WLAN_UMAC_COMP_ID_MAX]; + wlan_serialization_apply_rules_cb apply_rules_cb[WLAN_SER_CMD_MAX]; + struct wlan_serialization_timer *timers; + uint8_t max_active_cmds; +}; + +/** + * struct wlan_serialization_pdev_priv_obj - pdev obj data for serialization + * @active_list: list to hold the non-scan commands currently being executed + * @pending_list list: to hold the non-scan commands currently pending + * @active_scan_list: list to hold the scan commands currently active + * @pending_scan_list: list to hold the scan commands currently pending + * @global_cmd_pool_list: list to hold the global buffers + * @cmd_ptr: pointer to globally allocated cmd pool + * + * Serialization component maintains linked lists to store the commands + * sent by other components to get serialized. All the lists are per + * pdev. The maximum number of active scans is determined by the firmware. + * There is only one non-scan active command per pdev at a time as per the + * current software architecture. cmd_ptr holds the memory allocated for + * each of the global cmd pool nodes and it is useful in freeing up these + * nodes when needed. + */ +struct wlan_serialization_pdev_priv_obj { + qdf_list_t active_list; + qdf_list_t pending_list; + qdf_list_t active_scan_list; + qdf_list_t pending_scan_list; + qdf_list_t global_cmd_pool_list; +}; + +/** + * wlan_serialization_validate_cmd() - Validate the command + * @comp_id: Component ID + * @cmd_type: Command Type + * + * Return: QDF Status + */ +QDF_STATUS wlan_serialization_validate_cmd( + enum wlan_umac_comp_id comp_id, + enum wlan_serialization_cmd_type cmd_type); + + +/** + * wlan_serialization_release_list_cmds() - Release the list cmds to global pool + * @ser_pdev_obj: Serialization private pdev object + * @list: List for which the commands have to be returned to the global pool + * + * Return: None + */ +void wlan_serialization_release_list_cmds( + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, + qdf_list_t *list); + +/** + * wlan_serialization_destroy_list() - Release the cmds and destroy list + * @ser_pdev_obj: Serialization private pdev object + * @list: List to be destroyed + * + * Return: None + */ +void wlan_serialization_destroy_list( + struct wlan_serialization_pdev_priv_obj *ser_pdev_obj, + qdf_list_t *list); + +/** + * wlan_serialization_get_psoc_priv_obj() - Return the component private obj + * @psoc: Pointer to the PSOC object + * + * Return: Serialization component's PSOC level private data object + */ +struct wlan_serialization_psoc_priv_obj *wlan_serialization_get_psoc_priv_obj( + struct wlan_objmgr_psoc *psoc); + +/** + * wlan_serialization_get_pdev_priv_obj() - Return the component private obj + * @psoc: Pointer to the PDEV object + * + * Return: Serialization component's PDEV level private data object + */ +struct wlan_serialization_pdev_priv_obj *wlan_serialization_get_pdev_priv_obj( + struct wlan_objmgr_pdev *pdev); + +#endif