diff --git a/components/pmo/core/inc/wlan_pmo_main.h b/components/pmo/core/inc/wlan_pmo_main.h index f9d783f527..0137d0aa03 100644 --- a/components/pmo/core/inc/wlan_pmo_main.h +++ b/components/pmo/core/inc/wlan_pmo_main.h @@ -160,6 +160,15 @@ QDF_STATUS pmo_core_get_psoc_config(struct wlan_objmgr_psoc *psoc, QDF_STATUS pmo_core_update_psoc_config(struct wlan_objmgr_psoc *psoc, struct pmo_psoc_cfg *psoc_cfg); +/** + * pmo_psoc_set_caps() - overwrite configured device capability flags + * @psoc: the psoc for which the capabilities apply + * @caps: the cabability information to configure + * + * Return: None + */ +void pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc, + struct pmo_device_caps *caps); /** * pmo_core_get_vdev_op_mode(): API to get the vdev operation mode diff --git a/components/pmo/core/inc/wlan_pmo_priv.h b/components/pmo/core/inc/wlan_pmo_priv.h index 84a3ad1932..cc216d18bd 100644 --- a/components/pmo/core/inc/wlan_pmo_priv.h +++ b/components/pmo/core/inc/wlan_pmo_priv.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 @@ -37,6 +37,7 @@ * @psoc_cfg: place holder for psoc configuration * @pmo_tx_ops: transmit ops for PMO * @wow: wow configuration + * @caps: PMO specific device capability bits * @dp_hdl: psoc data path handle * @htc_hdl: htc layer handle * @hif_hdl: hif layer handle @@ -49,6 +50,7 @@ struct pmo_psoc_priv_obj { struct pmo_psoc_cfg psoc_cfg; struct wlan_pmo_tx_ops pmo_tx_ops; struct pmo_wow wow; + struct pmo_device_caps caps; void *dp_hdl; void *htc_hdl; void *hif_hdl; diff --git a/components/pmo/core/src/wlan_pmo_main.c b/components/pmo/core/src/wlan_pmo_main.c index dbec0db20a..659cfc8e7a 100644 --- a/components/pmo/core/src/wlan_pmo_main.c +++ b/components/pmo/core/src/wlan_pmo_main.c @@ -205,6 +205,16 @@ out: return status; } +void pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc, + struct pmo_device_caps *caps) +{ + struct pmo_psoc_priv_obj *psoc_ctx; + + pmo_psoc_with_ctx(psoc, psoc_ctx) { + qdf_mem_copy(&psoc_ctx->caps, caps, sizeof(psoc_ctx->caps)); + } +} + void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc, void *hif_hdl) { 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 2c2f39ec23..5e1df9ac08 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.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 @@ -316,5 +316,21 @@ struct pmo_psoc_cfg { enum pmo_auto_pwr_detect_failure_mode auto_power_save_fail_mode; }; +/** + * pmo_device_caps - device capability flags (true if feature is supported) + * @apf: Android Packet Filter (aka BPF) + * @arp_ns_offload: APR/NS offload + * @packet_filter: Legacy "Packet Filter" + * @unified_wow: Firmware supports "interface pause" flag in WoW command. + * This allows both D0-WoW (bus up) and Non-D0-WoW (bus down) to use one + * unified command + */ +struct pmo_device_caps { + bool apf; + bool arp_ns_offload; + bool packet_filter; + bool unified_wow; +}; + #endif /* end of _WLAN_PMO_COMMONP_STRUCT_H_ */ diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index bed04204f2..8cb4e96517 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.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 @@ -83,6 +83,16 @@ QDF_STATUS ucfg_pmo_get_psoc_config(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_pmo_update_psoc_config(struct wlan_objmgr_psoc *psoc, struct pmo_psoc_cfg *psoc_cfg); +/** + * ucfg_pmo_psoc_set_caps() - overwrite configured device capability flags + * @psoc: the psoc for which the capabilities apply + * @caps: the cabability information to configure + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc, + struct pmo_device_caps *caps); + /** * pmo_ucfg_enable_wakeup_event() - enable wow wakeup events * @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 db93aa724c..7f2f6ae5af 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.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 @@ -43,6 +43,22 @@ QDF_STATUS ucfg_pmo_update_psoc_config(struct wlan_objmgr_psoc *psoc, return pmo_core_update_psoc_config(psoc, psoc_cfg); } +QDF_STATUS ucfg_pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc, + struct pmo_device_caps *caps) +{ + QDF_BUG(psoc); + if (!psoc) + return QDF_STATUS_E_INVAL; + + QDF_BUG(caps); + if (!caps) + return QDF_STATUS_E_INVAL; + + pmo_psoc_set_caps(psoc, caps); + + return QDF_STATUS_SUCCESS; +} + bool ucfg_pmo_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE vdev_opmode) { diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 36fd078914..3bb38f05b5 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -5330,6 +5330,30 @@ static void wma_update_ra__limit(tp_wma_handle handle) } #endif +static void wma_set_pmo_caps(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct pmo_device_caps caps; + + caps.arp_ns_offload = + wma_is_service_enabled(wmi_service_arpns_offload); + caps.apf = + wma_is_service_enabled(wmi_service_bpf_offload); + caps.packet_filter = + wma_is_service_enabled(wmi_service_packet_filter_offload); + caps.unified_wow = + wma_is_service_enabled(wmi_service_unified_wow_capability); + + status = ucfg_pmo_psoc_set_caps(psoc, &caps); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("Failed to set PMO capabilities; status:%d", status); +} + +static void wma_set_component_caps(struct wlan_objmgr_psoc *psoc) +{ + wma_set_pmo_caps(psoc); +} + /** * wma_rx_service_ready_event() - event handler to process * wmi rx sevice ready event. @@ -5618,6 +5642,9 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info, qdf_mem_copy(target_cap.wmi_service_bitmap, service_bitmap, sizeof(wma_handle->wmi_service_bitmap)); + + 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); qdf_mem_copy(wma_handle->wmi_service_bitmap,