diff --git a/components/pmo/core/inc/wlan_pmo_static_config.h b/components/pmo/core/inc/wlan_pmo_static_config.h index ca87040a3e..5c76ccf1ef 100644 --- a/components/pmo/core/inc/wlan_pmo_static_config.h +++ b/components/pmo/core/inc/wlan_pmo_static_config.h @@ -148,6 +148,55 @@ QDF_STATUS pmo_core_vdev_get_ps_params(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } +/** + * pmo_vdev_set_ps_opm_mode() - set OPM mode + * @vdev: objmgr vdev handle + * @opm_mode: OPM mode + * + * Return: QDF_STATUS + */ +static inline +QDF_STATUS pmo_vdev_set_ps_opm_mode(struct wlan_objmgr_vdev *vdev, + enum powersave_mode opm_mode) +{ + struct pmo_vdev_priv_obj *vdev_ctx; + + vdev_ctx = pmo_vdev_get_priv(vdev); + if (!vdev_ctx) { + pmo_err("vdev ctx is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock); + vdev_ctx->ps_params.opm_mode = opm_mode; + qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock); + + return QDF_STATUS_SUCCESS; +} + +/** + * pmo_vdev_get_ps_opm_mode() - get OPM mode + * @vdev: objmgr vdev handle + * @opm_mode: OPM mode + * + * Return: QDF_STATUS + */ +static inline +QDF_STATUS pmo_vdev_get_ps_opm_mode(struct wlan_objmgr_vdev *vdev, + enum powersave_mode *opm_mode) +{ + struct pmo_vdev_priv_obj *vdev_ctx; + + vdev_ctx = pmo_vdev_get_priv(vdev); + if (!vdev_ctx) + return QDF_STATUS_E_NULL_VALUE; + + qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock); + *opm_mode = vdev_ctx->ps_params.opm_mode; + qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock); + return QDF_STATUS_SUCCESS; +} + #ifdef WLAN_FEATURE_NAN /** * pmo_set_ndp_wow_bitmask() - set predefined NDP wow wakeup events diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index 6d33b4c535..8267dbab4c 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -829,6 +829,26 @@ ucfg_pmo_set_ps_params(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_pmo_get_ps_params(struct wlan_objmgr_vdev *vdev, struct pmo_ps_params *ps_params); +/** + * ucfg_pmo_core_vdev_set_ps_opm_mode() - Set OPM mode + * @vdev: pointer to vdev object + * @opm_mode: OPM mode + * + * Return: QDF Status + */ +QDF_STATUS ucfg_pmo_core_vdev_set_ps_opm_mode(struct wlan_objmgr_vdev *vdev, + enum powersave_mode opm_mode); + +/** + * ucfg_pmo_core_vdev_get_ps_opm_mode() - Get OPM mode + * @vdev: pointer to vdev object + * @opm_mode: OPM mode + * + * Return: QDF Status + */ +QDF_STATUS ucfg_pmo_core_vdev_get_ps_opm_mode(struct wlan_objmgr_vdev *vdev, + enum powersave_mode *opm_mode); + /** * ucfg_pmo_get_gtk_rsp(): API to send gtk response request to fwr * @vdev: objmgr vdev handle diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index 14be19872a..efe9fa52a8 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c @@ -607,6 +607,18 @@ QDF_STATUS ucfg_pmo_get_ps_params(struct wlan_objmgr_vdev *vdev, return pmo_core_vdev_get_ps_params(vdev, ps_params); } +QDF_STATUS ucfg_pmo_core_vdev_set_ps_opm_mode(struct wlan_objmgr_vdev *vdev, + enum powersave_mode opm_mode) +{ + return pmo_vdev_set_ps_opm_mode(vdev, opm_mode); +} + +QDF_STATUS ucfg_pmo_core_vdev_get_ps_opm_mode(struct wlan_objmgr_vdev *vdev, + enum powersave_mode *opm_mode) +{ + return pmo_vdev_get_ps_opm_mode(vdev, opm_mode); +} + bool ucfg_pmo_is_arp_offload_enabled(struct wlan_objmgr_psoc *psoc) { diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 5c035b0ae1..1c70480306 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -9908,8 +9908,13 @@ static int hdd_config_power(struct wlan_hdd_link_info *link_info, tb[QCA_WLAN_VENDOR_ATTR_CONFIG_OPM_SPEC_WAKE_INTERVAL]; int ret; - if (!power_attr && !opm_attr) + hdd_enter_dev(adapter->dev); + + if (!power_attr && !opm_attr) { + hdd_err_rl("power attr and opm attr is null"); return 0; + } + if (power_attr && opm_attr) { hdd_err_rl("Invalid OPM set attribute"); @@ -9922,11 +9927,14 @@ static int hdd_config_power(struct wlan_hdd_link_info *link_info, } opm_mode = power_attr ? nla_get_u8(power_attr) : nla_get_u8(opm_attr); - if (opm_mode == QCA_WLAN_VENDOR_OPM_MODE_USER_DEFINED) + hdd_debug("opm_mode %d", opm_mode); + + if (opm_mode == QCA_WLAN_VENDOR_OPM_MODE_USER_DEFINED) { if (!ps_ito_attr || !spec_wake_attr) { hdd_err_rl("Invalid User defined OPM attributes"); return -EINVAL; } + } ret = hdd_set_power_config(hdd_ctx, adapter, &opm_mode); if (ret) @@ -9936,19 +9944,34 @@ static int hdd_config_power(struct wlan_hdd_link_info *link_info, if (opm_mode == QCA_WLAN_VENDOR_OPM_MODE_USER_DEFINED) { ps_params.ps_ito = nla_get_u16(ps_ito_attr); ps_params.spec_wake = nla_get_u16(spec_wake_attr); + + if (!ps_params.ps_ito) + return -EINVAL; + + hdd_debug("ps_ito %d spec_wake %d opm_mode %d", + ps_params.ps_ito, ps_params.spec_wake, + ps_params.opm_mode); + ret = hdd_set_power_config_params(hdd_ctx, adapter, ps_params.ps_ito, ps_params.spec_wake); + if (ret) return ret; } vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_POWER_ID); - if (vdev) { - ucfg_pmo_set_ps_params(vdev, &ps_params); - hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_POWER_ID); + if (!vdev) { + hdd_err("vdev is null"); + return 0; } + if (opm_mode == QCA_WLAN_VENDOR_OPM_MODE_USER_DEFINED) + ucfg_pmo_set_ps_params(vdev, &ps_params); + else + ucfg_pmo_core_vdev_set_ps_opm_mode(vdev, ps_params.opm_mode); + + hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_POWER_ID); return 0; }