diff --git a/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h index 222f09e4f3..2e394fe5b7 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h @@ -121,6 +121,8 @@ typedef int (*pmo_pld_auto_resume_cb)(void); * @psoc_send_target_resume_req: fp to send target resume request * @psoc_send_d0wow_enable_req: fp to send D0 WOW enable request * @psoc_send_d0wow_disable_req: fp to send D0 WOW disable request + * @psoc_send_idle_roam_suspend_mode: fp to send suspend mode for + * idle roam trigger to firmware. */ struct wlan_pmo_tx_ops { QDF_STATUS (*send_arp_offload_req)(struct wlan_objmgr_vdev *vdev, @@ -222,6 +224,8 @@ struct wlan_pmo_tx_ops { struct wlan_objmgr_psoc *psoc); QDF_STATUS (*psoc_send_d0wow_disable_req)( struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*psoc_send_idle_roam_suspend_mode)( + struct wlan_objmgr_psoc *psoc, uint8_t val); }; diff --git a/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h index f5e7dc8ec3..e08560b0e3 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h @@ -444,4 +444,15 @@ QDF_STATUS pmo_tgt_psoc_send_host_wakeup_ind(struct wlan_objmgr_psoc *psoc); */ QDF_STATUS pmo_tgt_psoc_send_target_resume_req(struct wlan_objmgr_psoc *psoc); +/** + * pmo_tgt_psoc_send_idle_roam_monitor() - Send idle roam set suspend mode + * command to firmware + * @psoc: objmgr psoc + * @val: Set suspend mode value + * + * Return: QDF_STATUS_SUCCESS on success else error code + */ +QDF_STATUS pmo_tgt_psoc_send_idle_roam_monitor(struct wlan_objmgr_psoc *psoc, + uint8_t val); + #endif /* end of _WLAN_PMO_TGT_API_H_ */ diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index 17f2150c54..1a751d7436 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -245,6 +245,19 @@ ucfg_pmo_get_max_ps_poll(struct wlan_objmgr_psoc *psoc); uint8_t ucfg_pmo_power_save_offload_enabled(struct wlan_objmgr_psoc *psoc); +/** + * ucfg_pmo_tgt_psoc_send_idle_roam_suspend_mode() - Send suspend mode to + * firmware + * @psoc: pointer to psoc object + * @val: Set suspend mode on/off sent from userspace + * + * Return: QDF_STATUS_SUCCESS if suspend mode is sent to fw else return + * corresponding QDF_STATUS failure code. + */ +QDF_STATUS +ucfg_pmo_tgt_psoc_send_idle_roam_suspend_mode(struct wlan_objmgr_psoc *psoc, + uint8_t val); + /** * ucfg_pmo_enable_wakeup_event() - enable wow wakeup events * @psoc: objmgr psoc diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c index 820e2b891f..1c08a0de9f 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c +++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c @@ -249,3 +249,15 @@ QDF_STATUS pmo_tgt_psoc_send_target_resume_req(struct wlan_objmgr_psoc *psoc) return pmo_tx_ops.psoc_send_target_resume_req(psoc); } +QDF_STATUS pmo_tgt_psoc_send_idle_roam_monitor(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + struct wlan_pmo_tx_ops pmo_tx_ops; + + pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc); + if (!pmo_tx_ops.psoc_send_idle_roam_suspend_mode) { + pmo_err("NULL fp"); + return QDF_STATUS_E_NULL_VALUE; + } + return pmo_tx_ops.psoc_send_idle_roam_suspend_mode(psoc, val); +} diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index 1e915b78f6..bc3615da54 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c @@ -696,6 +696,13 @@ ucfg_pmo_power_save_offload_enabled(struct wlan_objmgr_psoc *psoc) return powersave_offload_enabled; } +QDF_STATUS +ucfg_pmo_tgt_psoc_send_idle_roam_suspend_mode(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + return pmo_tgt_psoc_send_idle_roam_monitor(psoc, val); +} + #ifdef WLAN_FEATURE_EXTWOW_SUPPORT bool ucfg_pmo_extwow_is_goto_suspend_enabled(struct wlan_objmgr_psoc *psoc) @@ -825,4 +832,3 @@ ucfg_pmo_get_active_mc_bc_apf_mode(struct wlan_objmgr_psoc *psoc) return pmo_psoc_ctx->psoc_cfg.active_mc_bc_apf_mode; } - diff --git a/components/target_if/pmo/inc/target_if_pmo.h b/components/target_if/pmo/inc/target_if_pmo.h index 93df4cfcf9..d2991ea429 100644 --- a/components/target_if/pmo/inc/target_if_pmo.h +++ b/components/target_if/pmo/inc/target_if_pmo.h @@ -469,6 +469,17 @@ QDF_STATUS target_if_pmo_psoc_send_d0wow_enable_req( QDF_STATUS target_if_pmo_psoc_send_d0wow_disable_req( struct wlan_objmgr_psoc *psoc); +/** + * target_if_pmo_psoc_send_idle_monitor_cmd() - send screen status to firmware + * @psoc: objmgr psoc + * @val: Idle monitor value + * + * Return: QDF_STATUS_SUCCESS on success else error code + */ +QDF_STATUS +target_if_pmo_psoc_send_idle_monitor_cmd(struct wlan_objmgr_psoc *psoc, + uint8_t val); + /** * target_if_pmo_register_tx_ops() - Register PMO component TX OPS * @tx_ops: PMO if transmit ops diff --git a/components/target_if/pmo/src/target_if_pmo_main.c b/components/target_if/pmo/src/target_if_pmo_main.c index fdf857c7bc..c769ce4682 100644 --- a/components/target_if/pmo/src/target_if_pmo_main.c +++ b/components/target_if/pmo/src/target_if_pmo_main.c @@ -121,6 +121,8 @@ void target_if_pmo_register_tx_ops(struct wlan_pmo_tx_ops *pmo_tx_ops) target_if_pmo_psoc_send_d0wow_enable_req; pmo_tx_ops->psoc_send_d0wow_disable_req = target_if_pmo_psoc_send_d0wow_disable_req; + pmo_tx_ops->psoc_send_idle_roam_suspend_mode = + target_if_pmo_psoc_send_idle_monitor_cmd; tgt_if_pmo_reg_pkt_filter_ops(pmo_tx_ops); } diff --git a/components/target_if/pmo/src/target_if_pmo_suspend_resume.c b/components/target_if/pmo/src/target_if_pmo_suspend_resume.c index c0e1961274..87b2f0ca30 100644 --- a/components/target_if/pmo/src/target_if_pmo_suspend_resume.c +++ b/components/target_if/pmo/src/target_if_pmo_suspend_resume.c @@ -291,6 +291,21 @@ QDF_STATUS target_if_pmo_psoc_send_target_resume_req( return wmi_unified_resume_send(wmi_handle, TGT_WILDCARD_PDEV_ID); } +QDF_STATUS +target_if_pmo_psoc_send_idle_monitor_cmd(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + wmi_unified_t wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + return wmi_unified_send_idle_trigger_monitor(wmi_handle, val); +} + #ifdef FEATURE_WLAN_D0WOW QDF_STATUS target_if_pmo_psoc_send_d0wow_enable_req( struct wlan_objmgr_psoc *psoc) diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index 139cd226ff..114d1a5e78 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -55,6 +55,7 @@ */ #define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */ #define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */ +#define SIZE_OF_SETSUSPENDMODE 14 /* * Size of GETCOUNTRYREV output = (sizeof("GETCOUNTRYREV") = 14) + one (space) + @@ -3268,6 +3269,46 @@ exit: return ret; } +static int drv_cmd_set_suspend_mode(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + int errno; + uint8_t *value = command; + QDF_STATUS status; + uint8_t idle_monitor; + + if (QDF_STA_MODE != adapter->device_mode) { + hdd_debug("Non-STA interface"); + return 0; + } + + /* Move pointer to ahead of SETSUSPENDMODE */ + value = value + SIZE_OF_SETSUSPENDMODE + 1; + + /* Convert the value from ascii to integer */ + errno = kstrtou8(value, 10, &idle_monitor); + if (errno < 0) { + /* + * If the input value is greater than max value of datatype, + * then also kstrtou8 fails + */ + hdd_err("Range validation failed"); + return -EINVAL; + } + + hdd_debug("idle_monitor:%d", idle_monitor); + status = ucfg_pmo_tgt_psoc_send_idle_roam_suspend_mode(hdd_ctx->psoc, + idle_monitor); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_debug("Send suspend mode to fw failed"); + return -EINVAL; + } + return 0; +} + static int drv_cmd_get_roam_mode(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx, uint8_t *command, @@ -7393,7 +7434,7 @@ static const struct hdd_drv_cmd hdd_drv_cmds[] = { {"COUNTRY", drv_cmd_country, true}, {"SETCOUNTRYREV", drv_cmd_country, true}, {"GETCOUNTRYREV", drv_cmd_get_country, false}, - {"SETSUSPENDMODE", drv_cmd_dummy, false}, + {"SETSUSPENDMODE", drv_cmd_set_suspend_mode, true}, {"SET_AP_WPS_P2P_IE", drv_cmd_dummy, false}, {"SETROAMTRIGGER", drv_cmd_set_roam_trigger, true}, {"GETROAMTRIGGER", drv_cmd_get_roam_trigger, false},