Merge "ath10k: Enable WoWLAN for the wcn3990 snoc wlan module"

This commit is contained in:
Linux Build Service Account 2017-11-23 14:01:14 -08:00 committed by Gerrit - the friendly Code Review server
commit aa673858c8
8 changed files with 73 additions and 3 deletions

View file

@ -1304,6 +1304,9 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
fw_file = &ar->normal_mode_fw.fw_file;
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_TLV;
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
__set_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
fw_file->fw_features);
__set_bit(WMI_SERVICE_WOW, ar->wmi.svc_map);
return 0;
}

View file

@ -7578,6 +7578,7 @@ static const struct ieee80211_ops ath10k_ops = {
#ifdef CONFIG_PM
.suspend = ath10k_wow_op_suspend,
.resume = ath10k_wow_op_resume,
.set_wakeup = ath10k_wow_op_set_wakeup,
#endif
#ifdef CONFIG_MAC80211_DEBUGFS
.sta_add_debugfs = ath10k_sta_add_debugfs,

View file

@ -30,7 +30,8 @@
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
#define WCN3990_MAX_IRQ 12
#define WCN3990_MAX_IRQ 12
#define WCN3990_WAKE_IRQ_CE 2
const char *ce_name[WCN3990_MAX_IRQ] = {
"WLAN_CE_0",
@ -1161,7 +1162,8 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar)
atomic_set(&ar_snoc->pm_ops_inprogress, 0);
}
if (ar->state == ATH10K_STATE_ON ||
if ((ar->state == ATH10K_STATE_ON) ||
(ar->state == ATH10K_STATE_RESTARTING) ||
test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
ret = ath10k_snoc_bus_configure(ar);
if (ret) {
@ -1571,6 +1573,50 @@ static int ath10k_hw_power_off(struct ath10k *ar)
return ret;
}
static int ath10k_snoc_hif_suspend(struct ath10k *ar)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
int ret = 0;
if (!ar_snoc)
return -EINVAL;
if (!device_may_wakeup(ar->dev))
return -EINVAL;
ret = enable_irq_wake(ar_snoc->ce_irqs[WCN3990_WAKE_IRQ_CE].irq_line);
if (ret) {
ath10k_dbg(ar, ATH10K_DBG_SNOC,
"HIF Suspend: Failed to enable wakeup IRQ\n");
return ret;
}
ath10k_dbg(ar, ATH10K_DBG_SNOC, "HIF Suspended\n");
return ret;
}
static int ath10k_snoc_hif_resume(struct ath10k *ar)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
int ret = 0;
if (!ar_snoc)
return -EINVAL;
if (!device_may_wakeup(ar->dev))
return -EINVAL;
ret = disable_irq_wake(ar_snoc->ce_irqs[WCN3990_WAKE_IRQ_CE].irq_line);
if (ret) {
ath10k_dbg(ar, ATH10K_DBG_SNOC,
"HIF Resume: Failed to disable wakeup IRQ\n");
return ret;
}
ath10k_dbg(ar, ATH10K_DBG_SNOC, "HIF Resumed\n");
return ret;
}
static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.tx_sg = ath10k_snoc_hif_tx_sg,
.start = ath10k_snoc_hif_start,
@ -1583,6 +1629,8 @@ static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.power_down = ath10k_snoc_hif_power_down,
.read32 = ath10k_snoc_read32,
.write32 = ath10k_snoc_write32,
.suspend = ath10k_snoc_hif_suspend,
.resume = ath10k_snoc_hif_resume,
};
static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {

View file

@ -3028,6 +3028,8 @@ ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
cmd = (void *)tlv->value;
cmd->enable = __cpu_to_le32(1);
if (QCA_REV_WCN3990(ar))
cmd->pause_iface_config = __cpu_to_le32(1);
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n");
return skb;

View file

@ -1554,6 +1554,7 @@ struct wmi_tlv_wow_add_del_event_cmd {
struct wmi_tlv_wow_enable_cmd {
__le32 enable;
__le32 pause_iface_config;
} __packed;
struct wmi_tlv_wow_host_wakeup_ind {

View file

@ -309,6 +309,18 @@ exit:
return ret ? 1 : 0;
}
void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled)
{
struct ath10k *ar = hw->priv;
mutex_lock(&ar->conf_mutex);
if (test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
ar->running_fw->fw_file.fw_features)) {
device_set_wakeup_enable(ar->dev, enabled);
}
mutex_unlock(&ar->conf_mutex);
}
int ath10k_wow_op_resume(struct ieee80211_hw *hw)
{
struct ath10k *ar = hw->priv;
@ -368,5 +380,7 @@ int ath10k_wow_init(struct ath10k *ar)
ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns;
ar->hw->wiphy->wowlan = &ar->wow.wowlan_support;
device_set_wakeup_capable(ar->dev, true);
return 0;
}

View file

@ -28,6 +28,7 @@ int ath10k_wow_init(struct ath10k *ar);
int ath10k_wow_op_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan);
int ath10k_wow_op_resume(struct ieee80211_hw *hw);
void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled);
#else

View file

@ -97,7 +97,7 @@ static int wiphy_suspend(struct device *dev)
rtnl_lock();
if (rdev->wiphy.registered)
if (rdev->ops->suspend)
ret = rdev_suspend(rdev, NULL);
ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
rtnl_unlock();
return ret;