From 107f639cce7232747067fb03e925eb93acc802e3 Mon Sep 17 00:00:00 2001 From: Nachiket Kukade Date: Fri, 25 May 2018 19:15:16 +0530 Subject: [PATCH] qcacld-3.0: Change wow event API's to accept wow event types Current ucfg API's that disables wow events accept a u32 bitmap variable. A pointer to that variable is passed to core API where it assumes it as a u32 array of 4 bytes. This will lead to out of bound memory access. Change wow enable/disable API's to accept wow event type as the parameter. Change-Id: I220aaddfea62ab96f121014d0d65a1406988c946 CRs-Fixed: 2233108 --- components/pmo/core/inc/wlan_pmo_wow.h | 10 ++-- .../pmo/core/src/wlan_pmo_static_config.c | 4 -- .../pmo/core/src/wlan_pmo_suspend_resume.c | 24 ++++----- components/pmo/core/src/wlan_pmo_wow.c | 49 ++++++++++--------- .../pmo/dispatcher/inc/wlan_pmo_ucfg_api.h | 10 ++-- .../pmo/dispatcher/src/wlan_pmo_tgt_wow.c | 12 +++++ .../pmo/dispatcher/src/wlan_pmo_ucfg_api.c | 8 +-- core/wma/src/wma_dev_if.c | 2 +- 8 files changed, 64 insertions(+), 55 deletions(-) diff --git a/components/pmo/core/inc/wlan_pmo_wow.h b/components/pmo/core/inc/wlan_pmo_wow.h index 158a8bbc36..55751d67eb 100644 --- a/components/pmo/core/inc/wlan_pmo_wow.h +++ b/components/pmo/core/inc/wlan_pmo_wow.h @@ -325,23 +325,25 @@ QDF_STATUS pmo_core_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev, * pmo_core_enable_wakeup_event() - enable wow wakeup events * @psoc: objmgr psoc * @vdev_id: vdev id - * @bitmap: Event bitmap + * @wow_event: wow event to enable * * Return: none */ void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t *bitmap); + uint32_t vdev_id, + WOW_WAKE_EVENT_TYPE wow_event); /** * pmo_core_disable_wakeup_event() - disable wow wakeup events * @psoc: objmgr psoc * @vdev_id: vdev id - * @bitmap: Event bitmap + * @wow_event: wow event to disable * * Return: none */ void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t *bitmap); + uint32_t vdev_id, + WOW_WAKE_EVENT_TYPE wow_event); /** * pmo_is_wow_applicable(): should enable wow diff --git a/components/pmo/core/src/wlan_pmo_static_config.c b/components/pmo/core/src/wlan_pmo_static_config.c index ae486ca0b5..bf85f4b656 100644 --- a/components/pmo/core/src/wlan_pmo_static_config.c +++ b/components/pmo/core/src/wlan_pmo_static_config.c @@ -102,10 +102,6 @@ void pmo_register_wow_wakeup_events(struct wlan_objmgr_vdev *vdev) return; } - pmo_info("Selected %s wake event mask 0x%x%x%x%x, vdev %d", - iface_type, event_bitmap[0], event_bitmap[1], - event_bitmap[2], event_bitmap[3], vdev_id); - pmo_tgt_enable_wow_wakeup_event(vdev, event_bitmap); } diff --git a/components/pmo/core/src/wlan_pmo_suspend_resume.c b/components/pmo/core/src/wlan_pmo_suspend_resume.c index 2da344c736..b67eae2913 100644 --- a/components/pmo/core/src/wlan_pmo_suspend_resume.c +++ b/components/pmo/core/src/wlan_pmo_suspend_resume.c @@ -250,7 +250,7 @@ void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc) BM_LEN, disable_mask); disable_configured = true; - } + } } adapter_type = pmo_get_vdev_opmode(vdev); @@ -258,26 +258,22 @@ void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc) psoc_ctx = pmo_psoc_get_priv(psoc); if (psoc_ctx->psoc_cfg.auto_power_save_fail_mode == - PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE && + PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE && (adapter_type == QDF_STA_MODE || - adapter_type == QDF_P2P_CLIENT_MODE) - ) { + adapter_type == QDF_P2P_CLIENT_MODE)) { if (psoc_ctx->is_device_in_low_pwr_mode && - psoc_ctx->is_device_in_low_pwr_mode(vdev_id)) + psoc_ctx->is_device_in_low_pwr_mode(vdev_id)) { pmo_set_wow_event_bitmap(EV_PWR, - BM_LEN, - enable_mask); - pmo_core_enable_wakeup_event(psoc, vdev_id, - enable_mask); + BM_LEN, + enable_mask); enable_configured = true; + } } - if (enable_configured) - pmo_core_enable_wakeup_event(psoc, vdev_id, - enable_mask); + if (enable_configured) + pmo_tgt_enable_wow_wakeup_event(vdev, enable_mask); if (disable_configured) - pmo_core_disable_wakeup_event(psoc, vdev_id, - disable_mask); + pmo_tgt_disable_wow_wakeup_event(vdev, disable_mask); } } diff --git a/components/pmo/core/src/wlan_pmo_wow.c b/components/pmo/core/src/wlan_pmo_wow.c index 7960334933..b783a61f4f 100644 --- a/components/pmo/core/src/wlan_pmo_wow.c +++ b/components/pmo/core/src/wlan_pmo_wow.c @@ -27,6 +27,21 @@ #include "wlan_pmo_static_config.h" #include "wlan_reg_services_api.h" +void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event, + uint32_t wow_bitmap_size, + uint32_t *bitmask) +{ + uint32_t bit_idx = 0, idx = 0; + + if (!bitmask || wow_bitmap_size < PMO_WOW_MAX_EVENT_BM_LEN) { + pmo_err("wow bitmask length shorter than %d", + PMO_WOW_MAX_EVENT_BM_LEN); + return; + } + pmo_get_event_bitmap_idx(event, wow_bitmap_size, &bit_idx, &idx); + bitmask[idx] |= 1 << bit_idx; +} + QDF_STATUS pmo_core_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev, struct pmo_wow_add_pattern *ptrn) { @@ -128,10 +143,12 @@ out: } void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t *bitmap) + uint32_t vdev_id, + WOW_WAKE_EVENT_TYPE wow_event) { QDF_STATUS status; struct wlan_objmgr_vdev *vdev; + uint32_t bitmap[PMO_WOW_MAX_EVENT_BM_LEN] = {0}; pmo_enter(); @@ -150,8 +167,8 @@ void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc, if (QDF_IS_STATUS_ERROR(status)) goto out; - pmo_info("enable wakeup event vdev_id %d wake up event 0x%x%x%x%x", - vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]); + pmo_set_wow_event_bitmap(wow_event, PMO_WOW_MAX_EVENT_BM_LEN, bitmap); + pmo_tgt_enable_wow_wakeup_event(vdev, bitmap); pmo_vdev_put_ref(vdev); @@ -161,10 +178,12 @@ out: } void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t *bitmap) + uint32_t vdev_id, + WOW_WAKE_EVENT_TYPE wow_event) { QDF_STATUS status; struct wlan_objmgr_vdev *vdev; + uint32_t bitmap[PMO_WOW_MAX_EVENT_BM_LEN] = {0}; pmo_enter(); if (!psoc) { @@ -182,8 +201,8 @@ void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc, if (QDF_IS_STATUS_ERROR(status)) goto out; - pmo_info("Disable wakeup event vdev_id %d wake up event 0x%x%x%x%x", - vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]); + pmo_set_wow_event_bitmap(wow_event, PMO_WOW_MAX_EVENT_BM_LEN, bitmap); + pmo_tgt_disable_wow_wakeup_event(vdev, bitmap); pmo_vdev_put_ref(vdev); @@ -317,24 +336,6 @@ bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc) return false; } -void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event, - uint32_t wow_bitmap_size, - uint32_t *bitmask) -{ - uint32_t bit_idx = 0, idx = 0; - - if (!bitmask || wow_bitmap_size < PMO_WOW_MAX_EVENT_BM_LEN) { - pmo_err("wow bitmask length shorter than %d", - PMO_WOW_MAX_EVENT_BM_LEN); - return; - } - pmo_get_event_bitmap_idx(event, wow_bitmap_size, &bit_idx, &idx); - bitmask[idx] |= 1 << bit_idx; - - pmo_debug("%s: bitmask updated %x%x%x%x", - __func__, bitmask[0], bitmask[1], bitmask[2], bitmask[3]); -} - void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size) { diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index 54ba0ff17b..9291180755 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -122,23 +122,25 @@ QDF_STATUS ucfg_pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc, * pmo_ucfg_enable_wakeup_event() - enable wow wakeup events * @psoc: objmgr psoc * @vdev_id: vdev id - * @bitmap: Event bitmap + * @wow_event: wow event to enable * * Return: none */ void pmo_ucfg_enable_wakeup_event(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t *bitmap); + uint32_t vdev_id, + WOW_WAKE_EVENT_TYPE wow_event); /** * pmo_ucfg_disable_wakeup_event() - disable wow wakeup events * @psoc: objmgr psoc * @vdev_id: vdev id - * @bitmap: Event bitmap + * @wow_event: wow event to disable * * Return: none */ void pmo_ucfg_disable_wakeup_event(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t bitmap); + uint32_t vdev_id, + WOW_WAKE_EVENT_TYPE wow_event); /** * pmo_ucfg_cache_arp_offload_req(): API to cache arp req in pmo vdev priv ctx diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c index 72ea3c2daf..d527be03f5 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c +++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c @@ -32,10 +32,12 @@ QDF_STATUS pmo_tgt_enable_wow_wakeup_event( QDF_STATUS status; struct wlan_objmgr_psoc *psoc; struct wlan_pmo_tx_ops pmo_tx_ops; + int vdev_id; pmo_enter(); psoc = pmo_vdev_get_psoc(vdev); + vdev_id = pmo_vdev_get_id(vdev); pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc); if (!pmo_tx_ops.send_enable_wow_wakeup_event_req) { @@ -43,6 +45,10 @@ QDF_STATUS pmo_tgt_enable_wow_wakeup_event( status = QDF_STATUS_E_NULL_VALUE; goto out; } + + pmo_debug("Enable wakeup events 0x%x%x%x%x for vdev_id %d", + bitmap[3], bitmap[2], bitmap[1], bitmap[0], vdev_id); + status = pmo_tx_ops.send_enable_wow_wakeup_event_req(vdev, bitmap); if (status != QDF_STATUS_SUCCESS) pmo_err("Failed to enable wow wakeup event"); @@ -59,10 +65,12 @@ QDF_STATUS pmo_tgt_disable_wow_wakeup_event( QDF_STATUS status; struct wlan_objmgr_psoc *psoc; struct wlan_pmo_tx_ops pmo_tx_ops; + int vdev_id; pmo_enter(); psoc = pmo_vdev_get_psoc(vdev); + vdev_id = pmo_vdev_get_id(vdev); pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc); if (!pmo_tx_ops.send_disable_wow_wakeup_event_req) { @@ -70,6 +78,10 @@ QDF_STATUS pmo_tgt_disable_wow_wakeup_event( status = QDF_STATUS_E_NULL_VALUE; goto out; } + + pmo_debug("Disable wakeup events 0x%x%x%x%x for vdev_id %d", + bitmap[3], bitmap[2], bitmap[1], bitmap[0], vdev_id); + status = pmo_tx_ops.send_disable_wow_wakeup_event_req(vdev, bitmap); if (status != QDF_STATUS_SUCCESS) pmo_err("Failed to disable wow wakeup event"); diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index dc8a99dffb..121f7907cd 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c @@ -104,15 +104,15 @@ bool ucfg_pmo_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev) } void pmo_ucfg_enable_wakeup_event(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t *bitmap) + uint32_t vdev_id, WOW_WAKE_EVENT_TYPE wow_event) { - pmo_core_enable_wakeup_event(psoc, vdev_id, bitmap); + pmo_core_enable_wakeup_event(psoc, vdev_id, wow_event); } void pmo_ucfg_disable_wakeup_event(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t bitmap) + uint32_t vdev_id, WOW_WAKE_EVENT_TYPE wow_event) { - pmo_core_disable_wakeup_event(psoc, vdev_id, &bitmap); + pmo_core_disable_wakeup_event(psoc, vdev_id, wow_event); } QDF_STATUS pmo_ucfg_cache_arp_offload_req(struct pmo_arp_req *arp_req) diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 3ac67b1104..404f0611e6 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -3775,7 +3775,7 @@ static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss) } if (SAP_WPS_DISABLED == add_bss->wps_state) pmo_ucfg_disable_wakeup_event(wma->psoc, vdev_id, - (1 << WOW_PROBE_REQ_WPS_IE_EVENT)); + WOW_PROBE_REQ_WPS_IE_EVENT); wma_set_bss_rate_flags(wma, vdev_id, add_bss); status = wma_create_peer(wma, pdev, vdev, add_bss->bssId, WMI_PEER_TYPE_DEFAULT, vdev_id, false);