// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2020 The Linux Foundation. All rights reserved. */ #include <linux/delay.h> #include "mac.h" #include "core.h" #include "hif.h" #include "debug.h" #include "wmi.h" #include "wow.h" int ath11k_wow_enable(struct ath11k_base *ab) { struct ath11k *ar = ath11k_ab_to_ar(ab, 0); int i, ret; clear_bit(ATH11K_FLAG_HTC_SUSPEND_COMPLETE, &ab->dev_flags); for (i = 0; i < ATH11K_WOW_RETRY_NUM; i++) { reinit_completion(&ab->htc_suspend); ret = ath11k_wmi_wow_enable(ar); if (ret) { ath11k_warn(ab, "failed to issue wow enable: %d\n", ret); return ret; } ret = wait_for_completion_timeout(&ab->htc_suspend, 3 * HZ); if (ret == 0) { ath11k_warn(ab, "timed out while waiting for htc suspend completion\n"); return -ETIMEDOUT; } if (test_bit(ATH11K_FLAG_HTC_SUSPEND_COMPLETE, &ab->dev_flags)) /* success, suspend complete received */ return 0; ath11k_warn(ab, "htc suspend not complete, retrying (try %d)\n", i); msleep(ATH11K_WOW_RETRY_WAIT_MS); } ath11k_warn(ab, "htc suspend not complete, failing after %d tries\n", i); return -ETIMEDOUT; } int ath11k_wow_wakeup(struct ath11k_base *ab) { struct ath11k *ar = ath11k_ab_to_ar(ab, 0); int ret; reinit_completion(&ab->wow.wakeup_completed); ret = ath11k_wmi_wow_host_wakeup_ind(ar); if (ret) { ath11k_warn(ab, "failed to send wow wakeup indication: %d\n", ret); return ret; } ret = wait_for_completion_timeout(&ab->wow.wakeup_completed, 3 * HZ); if (ret == 0) { ath11k_warn(ab, "timed out while waiting for wow wakeup completion\n"); return -ETIMEDOUT; } return 0; }