diff --git a/core/hdd/inc/wlan_hdd_twt.h b/core/hdd/inc/wlan_hdd_twt.h index f1035e8589b5..e8fc645cf68b 100644 --- a/core/hdd/inc/wlan_hdd_twt.h +++ b/core/hdd/inc/wlan_hdd_twt.h @@ -310,6 +310,18 @@ void hdd_twt_update_work_handler(void *data); */ void wlan_twt_concurrency_update(struct hdd_context *hdd_ctx); +/** + * hdd_twt_del_dialog_in_ps_disable() - TWT teardown in case of ps disable + * @hdd_ctx: hdd context pointer + * @mac_addr: STA mac address + * @vdev_id: vdev id + * + * Return: None + */ +void hdd_twt_del_dialog_in_ps_disable(struct hdd_context *hdd_ctx, + struct qdf_mac_addr *mac_addr, + uint8_t vdev_id); + #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT \ { \ .info.vendor_id = QCA_NL80211_VENDOR_ID, \ @@ -411,6 +423,13 @@ static inline void wlan_twt_concurrency_update(struct hdd_context *hdd_ctx) { } +static inline +void hdd_twt_del_dialog_in_ps_disable(struct hdd_context *hdd_ctx, + struct qdf_mac_addr *mac_addr, + uint8_t vdev_id) +{ +} + #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT #endif diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 297279b5900e..c5d9c34311de 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1895,6 +1895,7 @@ int wlan_hdd_set_powersave(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx; QDF_STATUS status = QDF_STATUS_SUCCESS; bool is_bmps_enabled; + struct hdd_station_ctx *hdd_sta_ctx = NULL; if (!adapter) { hdd_err("Adapter NULL"); @@ -1907,6 +1908,12 @@ int wlan_hdd_set_powersave(struct hdd_adapter *adapter, return -EINVAL; } + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (!hdd_sta_ctx) { + hdd_err("hdd_sta_context is NULL"); + return -EINVAL; + } + hdd_debug("Allow power save: %d", allow_power_save); mac_handle = hdd_ctx->mac_handle; @@ -1972,10 +1979,19 @@ int wlan_hdd_set_powersave(struct hdd_adapter *adapter, goto end; ucfg_mlme_is_bmps_enabled(hdd_ctx->psoc, &is_bmps_enabled); - if (is_bmps_enabled) + if (is_bmps_enabled) { status = sme_ps_enable_disable(mac_handle, adapter->vdev_id, SME_PS_DISABLE); + if (status != QDF_STATUS_SUCCESS) + goto end; + } + + if (adapter->device_mode == QDF_STA_MODE) { + hdd_twt_del_dialog_in_ps_disable(hdd_ctx, + &hdd_sta_ctx->conn_info.bssid, + adapter->vdev_id); + } } end: diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index 610c390de787..182a1f20229a 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -1226,6 +1226,8 @@ int wmi_twt_del_status_to_vendor_twt_status(enum WMI_HOST_DEL_TWT_STATUS status) return QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS; case WMI_HOST_DEL_TWT_STATUS_SCAN_IN_PROGRESS: return QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS; + case WMI_HOST_DEL_TWT_STATUS_PS_DISABLE_TEARDOWN: + return QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE; default: return QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR; } @@ -4500,6 +4502,27 @@ void wlan_twt_concurrency_update(struct hdd_context *hdd_ctx) qdf_sched_work(0, &hdd_ctx->twt_en_dis_work); } +void hdd_twt_del_dialog_in_ps_disable(struct hdd_context *hdd_ctx, + struct qdf_mac_addr *mac_addr, + uint8_t vdev_id) +{ + struct wmi_twt_del_dialog_param params = {0}; + int ret; + + params.dialog_id = WLAN_ALL_SESSIONS_DIALOG_ID; + params.vdev_id = vdev_id; + qdf_mem_copy(params.peer_macaddr, mac_addr->bytes, QDF_MAC_ADDR_SIZE); + + if (ucfg_mlme_is_twt_setup_done(hdd_ctx->psoc, mac_addr, + params.dialog_id)) { + hdd_debug("vdev%d: Terminate existing TWT session %d due to ps disable", + params.vdev_id, params.dialog_id); + ret = hdd_send_twt_del_dialog_cmd(hdd_ctx, ¶ms); + if (ret) + hdd_debug("TWT teardown is failed on vdev: %d", vdev_id); + } +} + void wlan_hdd_twt_init(struct hdd_context *hdd_ctx) { QDF_STATUS status; diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 198c5daa3172..893b073d0c54 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2450,6 +2450,10 @@ sme_process_sta_twt_del_dialog_event( return; } + if (!mac->usr_cfg_ps_enable && + param->status == WMI_HOST_DEL_TWT_STATUS_OK) + param->status = WMI_HOST_DEL_TWT_STATUS_PS_DISABLE_TEARDOWN; + callback = mac->sme.twt_del_dialog_cb; if (callback) callback(mac->psoc, param); @@ -14910,6 +14914,11 @@ QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle, SME_ENTER(); + if (!mac->usr_cfg_ps_enable) { + sme_debug("Power save mode disable"); + return QDF_STATUS_E_INVAL; + } + is_twt_notify_in_progress = mlme_is_twt_notify_in_progress( mac->psoc, twt_params->vdev_id);