From a3d6f77c62acb6946fe09d1ed255acdda9025127 Mon Sep 17 00:00:00 2001 From: Santosh Anbu Date: Sun, 7 Apr 2019 00:07:48 +0530 Subject: [PATCH] qcacmn: Add API to validate umac_cmd in serialization command Since umac cmd is specific to the module adding cmd to serialization queue, an API is needed to validate the umac_cmd associated with that serialization context holding the serialization queue lock. Change-Id: Iadb4deb17ffabd780432a29e7cbd37024fd431fe CRs-Fixed: 2430764 --- .../inc/wlan_serialization_api.h | 30 +++++++++- .../src/wlan_serialization_api.c | 57 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index d70d9aac70..a22337c8b5 100644 --- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -145,6 +145,18 @@ typedef bool (*wlan_serialization_apply_rules_cb)( union wlan_serialization_rules_info *comp_info, uint8_t comp_id); +/** + * wlan_ser_umac_cmd_cb() - callback to validate umac_cmd + * @umac_cmd: umac data associated with the serialization cmd + * + * This callback can be called at run time for a command in active queue to + * fetch the required information from the umac cmd data stored in serialization + * command buffer. + * + * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE + */ +typedef QDF_STATUS (*wlan_ser_umac_cmd_cb)(void *umac_cmd); + /** * enum wlan_umac_cmd_id - Command Type * @WLAN_SER_CMD_SCAN: Scan command @@ -565,7 +577,7 @@ enum wlan_serialization_cmd_type wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev); /** - * wlan_ser_get_cmd_activation_status - Return active command status + * wlan_ser_get_cmd_activation_status() - Return active command status * @vdev: vdev object * * This API fetches active command state in the vdev active queue @@ -576,4 +588,20 @@ wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev); QDF_STATUS wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev); +/** + * wlan_ser_validate_umac_cmd() - validate umac cmd data + * @vdev: objmgr vdev pointer + * @cmd_type: cmd type to match + * @umac_cmd_cb: Callback to be called to validate the data + * + * This API returns the validation status of the umac cmd cb. + * The umac_cmd_cb callback is called with serialization lock held, and hence + * only atomic operations are allowed in the callback. + * + * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE + */ +QDF_STATUS +wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev, + enum wlan_serialization_cmd_type cmd_type, + wlan_ser_umac_cmd_cb umac_cmd_cb); #endif diff --git a/umac/cmn_services/serialization/src/wlan_serialization_api.c b/umac/cmn_services/serialization/src/wlan_serialization_api.c index a856d872c0..de9ae64ade 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_api.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_api.c @@ -724,3 +724,60 @@ wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev) return status; } + +QDF_STATUS +wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev, + enum wlan_serialization_cmd_type cmd_type, + wlan_ser_umac_cmd_cb umac_cmd_cb) +{ + struct wlan_objmgr_pdev *pdev; + struct wlan_ser_pdev_obj *ser_pdev_obj; + struct wlan_serialization_command_list *cmd_list = NULL; + void *umac_cmd = NULL; + qdf_list_node_t *node = NULL; + qdf_list_t *queue; + struct wlan_serialization_pdev_queue *pdev_q; + QDF_STATUS status = QDF_STATUS_E_INVAL; + + ser_enter(); + + if (!vdev) { + ser_err("invalid vdev"); + return QDF_STATUS_E_INVAL; + } + + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) { + ser_err("invalid pdev"); + return QDF_STATUS_E_INVAL; + } + + ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); + if (!ser_pdev_obj) { + ser_err("invalid ser_pdev_obj"); + return QDF_STATUS_E_INVAL; + } + + pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type); + + wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); + + queue = &pdev_q->active_list; + node = wlan_serialization_find_cmd( + queue, WLAN_SER_MATCH_CMD_TYPE_VDEV, + NULL, cmd_type, NULL, vdev, WLAN_SER_PDEV_NODE); + if (node) { + cmd_list = qdf_container_of( + node, + struct wlan_serialization_command_list, + pdev_node); + + umac_cmd = cmd_list->cmd.umac_cmd; + status = umac_cmd_cb(umac_cmd); + } + + wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); + ser_exit(); + + return status; +}