diff --git a/components/pmo/core/inc/wlan_pmo_apf.h b/components/pmo/core/inc/wlan_pmo_apf.h index 366e86e42a..880bba42cb 100644 --- a/components/pmo/core/inc/wlan_pmo_apf.h +++ b/components/pmo/core/inc/wlan_pmo_apf.h @@ -23,4 +23,15 @@ #ifndef __WLAN_PMO_APF_H #define __WLAN_PMO_APF_H +#include "qdf_types.h" +#include "wlan_objmgr_psoc_obj.h" + +/** + * pmo_get_apf_instruction_size() - get the current APF instruction size + * @psoc: the psoc to query + * + * Return: APF instruction size + */ +uint32_t pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc); + #endif /* __WLAN_PMO_APF_H */ diff --git a/components/pmo/core/inc/wlan_pmo_main.h b/components/pmo/core/inc/wlan_pmo_main.h index a8157254d8..3700c624b0 100644 --- a/components/pmo/core/inc/wlan_pmo_main.h +++ b/components/pmo/core/inc/wlan_pmo_main.h @@ -48,14 +48,9 @@ #define PMO_VDEV_IN_STA_MODE(mode) \ ((mode) == QDF_STA_MODE || (mode) == QDF_P2P_CLIENT_MODE ? 1 : 0) -static inline enum QDF_OPMODE pmo_get_vdev_opmode( - struct wlan_objmgr_vdev *vdev) +static inline enum QDF_OPMODE pmo_get_vdev_opmode(struct wlan_objmgr_vdev *vdev) { - enum QDF_OPMODE opmode; - - opmode = wlan_vdev_mlme_get_opmode(vdev); - - return opmode; + return wlan_vdev_mlme_get_opmode(vdev); } /** @@ -355,4 +350,55 @@ bool pmo_is_vdev_up(struct wlan_objmgr_vdev *vdev) return state == WLAN_VDEV_S_RUN; } +/** + * pmo_intersect_arp_ns_offload() - intersect config and firmware capability for + * the ARP/NS Offload feature + * @psoc_ctx: A PMO psoc context + * + * Note: The caller is expected to grab the PMO context lock. + * + * Return: True if firmware supports and configuration has enabled the feature + */ +static inline bool +pmo_intersect_arp_ns_offload(struct pmo_psoc_priv_obj *psoc_ctx) +{ + struct pmo_psoc_cfg *cfg = &psoc_ctx->psoc_cfg; + bool arp_ns_enabled = + cfg->ns_offload_enable_static || + cfg->ns_offload_enable_dynamic || + cfg->arp_offload_enable; + + return arp_ns_enabled && psoc_ctx->caps.arp_ns_offload; +} + +/** + * pmo_intersect_apf() - intersect config and firmware capability for + * the BPF feature + * @psoc_ctx: A PMO psoc context + * + * Note: The caller is expected to grab the PMO context lock. + * + * Return: True if firmware supports and configuration has enabled the feature + */ +static inline bool pmo_intersect_apf(struct pmo_psoc_priv_obj *psoc_ctx) +{ + return psoc_ctx->psoc_cfg.apf_enable && psoc_ctx->caps.apf; +} + +/** + * pmo_intersect_packet_filter() - intersect config and firmware capability for + * the BPF feature + * @psoc_ctx: A PMO psoc context + * + * Note: The caller is expected to grab the PMO context lock. + * + * Return: True if firmware supports and configuration has enabled the feature + */ +static inline bool +pmo_intersect_packet_filter(struct pmo_psoc_priv_obj *psoc_ctx) +{ + return psoc_ctx->psoc_cfg.packet_filter_enabled && + psoc_ctx->caps.packet_filter; +} + #endif /* end of _WLAN_PMO_MAIN_H_ */ diff --git a/components/pmo/core/inc/wlan_pmo_pkt_filter.h b/components/pmo/core/inc/wlan_pmo_pkt_filter.h index 1af1f6d5d9..72245c3775 100644 --- a/components/pmo/core/inc/wlan_pmo_pkt_filter.h +++ b/components/pmo/core/inc/wlan_pmo_pkt_filter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -20,12 +20,20 @@ */ #ifndef _WLAN_PMO_PKT_FILTER_H_ -#define _WLAN_PMO_PKT_FILTER_ +#define _WLAN_PMO_PKT_FILTER_H_ #include "wlan_pmo_pkt_filter_public_struct.h" struct wlan_objmgr_psoc; +/** + * pmo_get_num_packet_filters() - get the number of packet filters + * @psoc: the psoc to query + * + * Return: number of packet filters + */ +uint8_t pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc); + /** * pmo_set_pkt_fltr_req() - Set packet filter * @vdev: objmgr vdev @@ -53,5 +61,5 @@ QDF_STATUS pmo_core_clear_pkt_filter(struct wlan_objmgr_psoc *psoc, struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_req, uint8_t vdev_id); -#endif /* end of _WLAN_PMO_PKT_FILTER_H_ */ +#endif /* _WLAN_PMO_PKT_FILTER_H_ */ diff --git a/components/pmo/core/inc/wlan_pmo_wow.h b/components/pmo/core/inc/wlan_pmo_wow.h index 84b58916df..1135861b90 100644 --- a/components/pmo/core/inc/wlan_pmo_wow.h +++ b/components/pmo/core/inc/wlan_pmo_wow.h @@ -105,6 +105,10 @@ #define PMO_WOW_MAX_EVENT_BM_LEN 4 +#define PMO_WOW_FILTERS_ARP_NS 2 +#define PMO_WOW_FILTERS_PKT_OR_APF 5 +#define PMO_WOW_FILTERS_MAX 22 + /** * pmo_get_and_increment_wow_default_ptrn() -Get and increment wow default ptrn * @vdev_ctx: pmo vdev priv ctx @@ -684,4 +688,12 @@ static inline void pmo_get_event_bitmap_idx(WOW_WAKE_EVENT_TYPE event, *bit_idx = event % (wow_bitmap_size * 8); } } + +/** + * pmo_get_num_wow_filters() - get the supported number of WoW filters + * @psoc: the psoc to query + * + * Return: number of WoW filters supported + */ +uint8_t pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc); #endif /* end of _WLAN_PMO_WOW_H_ */ diff --git a/components/pmo/core/src/wlan_pmo_apf.c b/components/pmo/core/src/wlan_pmo_apf.c index 22b312e816..bf67e3f865 100644 --- a/components/pmo/core/src/wlan_pmo_apf.c +++ b/components/pmo/core/src/wlan_pmo_apf.c @@ -20,5 +20,23 @@ * DOC: PMO implementations for Android Packet Filter (APF) functions */ +#include "qdf_types.h" +#include "wlan_objmgr_psoc_obj.h" #include "wlan_pmo_apf.h" +#include "wlan_pmo_main.h" + +#define PMO_APF_SIZE_AUTO 0 +#define PMO_APF_SIZE_DISABLE 0xffffffff + +uint32_t pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc) +{ + struct pmo_psoc_priv_obj *psoc_ctx; + bool enabled; + + pmo_psoc_with_ctx(psoc, psoc_ctx) { + enabled = pmo_intersect_apf(psoc_ctx); + } + + return enabled ? PMO_APF_SIZE_AUTO : PMO_APF_SIZE_DISABLE; +} diff --git a/components/pmo/core/src/wlan_pmo_pkt_filter.c b/components/pmo/core/src/wlan_pmo_pkt_filter.c index 8351b93125..8aaa32e246 100644 --- a/components/pmo/core/src/wlan_pmo_pkt_filter.c +++ b/components/pmo/core/src/wlan_pmo_pkt_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -24,6 +24,21 @@ #include "wlan_pmo_main.h" #include "wlan_pmo_obj_mgmt_public_struct.h" +#define PMO_PKT_FILTERS_DEFAULT 12 +#define PMO_PKT_FILTERS_DISABLED 0 + +uint8_t pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc) +{ + struct pmo_psoc_priv_obj *psoc_ctx; + bool enabled; + + pmo_psoc_with_ctx(psoc, psoc_ctx) { + enabled = pmo_intersect_packet_filter(psoc_ctx); + } + + return enabled ? PMO_PKT_FILTERS_DEFAULT : PMO_PKT_FILTERS_DISABLED; +} + QDF_STATUS pmo_core_set_pkt_filter(struct wlan_objmgr_psoc *psoc, struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req, uint8_t vdev_id) diff --git a/components/pmo/core/src/wlan_pmo_wow.c b/components/pmo/core/src/wlan_pmo_wow.c index 6b4a2b74fd..c812ebf4f2 100644 --- a/components/pmo/core/src/wlan_pmo_wow.c +++ b/components/pmo/core/src/wlan_pmo_wow.c @@ -386,7 +386,6 @@ void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size) pmo_set_wow_event_bitmap(WOW_11D_SCAN_EVENT, wow_bitmap_size, bitmask); - } void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size) @@ -420,3 +419,26 @@ void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size) wow_bitmap_size, bitmask); } + +uint8_t pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc) +{ + struct pmo_psoc_priv_obj *psoc_ctx; + bool apf; + bool arp_ns; + bool pkt_filter; + + pmo_psoc_with_ctx(psoc, psoc_ctx) { + apf = pmo_intersect_apf(psoc_ctx); + arp_ns = pmo_intersect_arp_ns_offload(psoc_ctx); + pkt_filter = pmo_intersect_packet_filter(psoc_ctx); + } + + if (!apf && !pkt_filter) + return PMO_WOW_FILTERS_MAX; + + if (arp_ns) + return PMO_WOW_FILTERS_ARP_NS; + + return PMO_WOW_FILTERS_PKT_OR_APF; +} + diff --git a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h index 5e1df9ac08..770f39fe65 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h @@ -261,12 +261,13 @@ enum pmo_auto_pwr_detect_failure_mode { * struct pmo_psoc_cfg - user configuration required for pmo * @ptrn_match_enable_all_vdev: true when pattern match is enable for all vdev * @ptrn_id_per_vdev: true when pattern id can be same for different vdev - * @bpf_enable: true if psoc supports bpf else false + * @apf_enable: true if psoc supports bpf else false * @arp_offload_enable: true if arp offload is supported for psoc else false * @hw_filter_mode: which mode the hardware filter should use during DTIM * @ns_offload_enable_static: true if psoc supports ns offload in ini else false * @ns_offload_enable_dynamic: to enable / disable the ns offload using * ioctl or vendor command. + * @packet_filter_enabled: true if feature is enabled by configuration * @ssdp: true if psoc supports if ssdp configuration in wow mode * @enable_mc_list: true if psoc supports mc addr list else false * @active_mode_offload: true if psoc supports active mode offload else false @@ -290,11 +291,12 @@ enum pmo_auto_pwr_detect_failure_mode { struct pmo_psoc_cfg { bool ptrn_match_enable_all_vdev; bool ptrn_id_per_vdev; - bool bpf_enable; + bool apf_enable; bool arp_offload_enable; enum pmo_hw_filter_mode hw_filter_mode; bool ns_offload_enable_static; bool ns_offload_enable_dynamic; + bool packet_filter_enabled; bool ssdp; bool enable_mc_list; bool active_mode_offload; diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index 8cb4e96517..99db95f9d9 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -33,6 +33,30 @@ #include "wlan_pmo_pkt_filter_public_struct.h" #include "wlan_pmo_hw_filter_public_struct.h" +/** + * ucfg_pmo_get_apf_instruction_size() - get the current APF instruction size + * @psoc: the psoc to query + * + * Return: APF instruction size + */ +uint32_t ucfg_pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_pmo_get_num_packet_filters() - get the number of packet filters + * @psoc: the psoc to query + * + * Return: number of packet filters + */ +uint8_t ucfg_pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_pmo_get_num_wow_filters() - get the supported number of WoW filters + * @psoc: the psoc to query + * + * Return: number of WoW filters supported + */ +uint8_t ucfg_pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc); + /** * ucfg_pmo_is_ap_mode_supports_arp_ns() - Check ap mode support arp&ns offload * @psoc: objmgr psoc diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index 7f2f6ae5af..afb4aa7877 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c @@ -20,6 +20,7 @@ */ #include "wlan_pmo_ucfg_api.h" +#include "wlan_pmo_apf.h" #include "wlan_pmo_arp.h" #include "wlan_pmo_ns.h" #include "wlan_pmo_gtk.h" @@ -31,6 +32,33 @@ #include "wlan_pmo_pkt_filter.h" #include "wlan_pmo_hw_filter.h" +uint32_t ucfg_pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc) +{ + QDF_BUG(psoc); + if (!psoc) + return 0; + + return pmo_get_apf_instruction_size(psoc); +} + +uint8_t ucfg_pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc) +{ + QDF_BUG(psoc); + if (!psoc) + return 0; + + return pmo_get_num_packet_filters(psoc); +} + +uint8_t ucfg_pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc) +{ + QDF_BUG(psoc); + if (!psoc) + return 0; + + return pmo_get_num_wow_filters(psoc); +} + QDF_STATUS ucfg_pmo_get_psoc_config(struct wlan_objmgr_psoc *psoc, struct pmo_psoc_cfg *psoc_cfg) { diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 9129d9d158..0475f677e1 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -12616,7 +12616,6 @@ static inline void hdd_ra_populate_pmo_config( */ static int hdd_update_pmo_config(struct hdd_context *hdd_ctx) { - struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc; struct pmo_psoc_cfg psoc_cfg; QDF_STATUS status; @@ -12632,40 +12631,36 @@ static int hdd_update_pmo_config(struct hdd_context *hdd_ctx) (hdd_ctx->config->wowEnable & 0x01) ? true : false; psoc_cfg.ptrn_match_enable_all_vdev = (hdd_ctx->config->wowEnable & 0x02) ? true : false; - psoc_cfg.ptrn_id_per_vdev = wma_is_service_enabled( - wmi_service_unified_wow_capability); - psoc_cfg.bpf_enable = - hdd_ctx->config->bpf_packet_filter_enable; + psoc_cfg.ptrn_id_per_vdev = + wma_is_service_enabled(wmi_service_unified_wow_capability); + psoc_cfg.apf_enable = hdd_ctx->config->bpf_packet_filter_enable; psoc_cfg.arp_offload_enable = hdd_ctx->config->fhostArpOffload; psoc_cfg.hw_filter_mode = hdd_ctx->config->hw_filter_mode; + psoc_cfg.ns_offload_enable_dynamic = hdd_ctx->config->fhostNSOffload; psoc_cfg.ns_offload_enable_static = hdd_ctx->config->fhostNSOffload; - if (hdd_ctx->config->fhostNSOffload) - psoc_cfg.ns_offload_enable_dynamic = true; + psoc_cfg.packet_filter_enabled = !hdd_ctx->config->disablePacketFilter; psoc_cfg.ssdp = hdd_ctx->config->ssdp; psoc_cfg.enable_mc_list = hdd_ctx->config->fEnableMCAddrList; - psoc_cfg.active_mode_offload = - hdd_ctx->config->active_mode_offload; + psoc_cfg.active_mode_offload = hdd_ctx->config->active_mode_offload; psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support; psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported(); psoc_cfg.max_wow_filters = hdd_ctx->config->maxWoWFilters; psoc_cfg.sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM; psoc_cfg.sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM; psoc_cfg.sta_max_li_mod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM; - psoc_cfg.power_save_mode = - hdd_ctx->config->enablePowersaveOffload; + psoc_cfg.power_save_mode = hdd_ctx->config->enablePowersaveOffload; psoc_cfg.auto_power_save_fail_mode = hdd_ctx->config->auto_pwr_save_fail_mode; hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx); hdd_nan_populate_pmo_config(&psoc_cfg, hdd_ctx); hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx); - status = ucfg_pmo_update_psoc_config(psoc, &psoc_cfg); - if (status != QDF_STATUS_SUCCESS) { - hdd_err("failed pmo psoc configuration"); - return -EINVAL; - } - return 0; + status = ucfg_pmo_update_psoc_config(hdd_ctx->hdd_psoc, &psoc_cfg); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("failed pmo psoc configuration; status:%d", status); + + return qdf_status_to_os_return(status); } #ifdef FEATURE_WLAN_SCAN_PNO diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 1784d37f7d..e0e72c5449 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -4486,33 +4486,23 @@ QDF_STATUS wma_close(void) /** * wma_update_fw_config() - update fw configuration - * @wma_handle: wma handle - * @tgt_cap: pointer to structure target_psoc_info - * @tgt_hdl: Target capability info + * @psoc: psoc to query configuration from + * @tgt_hdl: target capability info * * Return: none */ -static void wma_update_fw_config(tp_wma_handle wma_handle, - struct wma_target_cap *tgt_cap, +static void wma_update_fw_config(struct wlan_objmgr_psoc *psoc, struct target_psoc_info *tgt_hdl) { - /* - * tgt_cap contains default target resource configuration - * which can be modified here, if required - */ + target_resource_config *cfg = &tgt_hdl->info.wlan_res_cfg; + /* Override the no. of max fragments as per platform configuration */ - tgt_cap->wlan_resource_config.max_frag_entries = - QDF_MIN(QCA_OL_11AC_TX_MAX_FRAGS, + cfg->max_frag_entries = QDF_MIN(QCA_OL_11AC_TX_MAX_FRAGS, target_if_get_max_frag_entry(tgt_hdl)); + target_if_set_max_frag_entry(tgt_hdl, cfg->max_frag_entries); - target_if_set_max_frag_entry(tgt_hdl, - tgt_cap->wlan_resource_config.max_frag_entries); - - /* Update no. of maxWoWFilters depending on BPF service */ - if (wmi_service_enabled(wma_handle->wmi_handle, - wmi_service_bpf_offload)) - tgt_cap->wlan_resource_config.num_wow_filters = - WMA_STA_WOW_DEFAULT_PTRN_MAX; + cfg->num_wow_filters = ucfg_pmo_get_num_wow_filters(psoc); + cfg->bpf_instruction_size = ucfg_pmo_get_apf_instruction_size(psoc); } /** @@ -5655,7 +5645,7 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info, wma_set_component_caps(wma_handle->psoc); target_cap.wlan_resource_config = tgt_hdl->info.wlan_res_cfg; - wma_update_fw_config(wma_handle, &target_cap, tgt_hdl); + wma_update_fw_config(wma_handle->psoc, tgt_hdl); qdf_mem_copy(wma_handle->wmi_service_bitmap, service_bitmap, sizeof(wma_handle->wmi_service_bitmap));