qtnfmac: implement basic WoWLAN support

This patch implements basic WoWLAN support in qtnfmac driver, including
processing of WoWLAN features reported by firmware and implementation
of cfg80211 suspend/resume/wakeup callbacks. Currently the following
WoWLAN triggers are supported: disconnect, magic packet,
custom pattern packet.

Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Sergey Matyukevich
2018-08-02 13:40:43 +03:00
committed by Kalle Valo
parent a33ce21e2a
commit 28b9188483
6 changed files with 248 additions and 0 deletions

View File

@@ -859,6 +859,72 @@ static int qtnf_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
return ret;
}
#ifdef CONFIG_PM
static int qtnf_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wowlan)
{
struct qtnf_wmac *mac = wiphy_priv(wiphy);
struct qtnf_vif *vif;
int ret = 0;
vif = qtnf_mac_get_base_vif(mac);
if (!vif) {
pr_err("MAC%u: primary VIF is not configured\n", mac->macid);
ret = -EFAULT;
goto exit;
}
if (!wowlan) {
pr_debug("WoWLAN triggers are not enabled\n");
qtnf_virtual_intf_cleanup(vif->netdev);
goto exit;
}
qtnf_scan_done(vif->mac, true);
ret = qtnf_cmd_send_wowlan_set(vif, wowlan);
if (ret) {
pr_err("MAC%u: failed to set WoWLAN triggers\n",
mac->macid);
goto exit;
}
exit:
return ret;
}
static int qtnf_resume(struct wiphy *wiphy)
{
struct qtnf_wmac *mac = wiphy_priv(wiphy);
struct qtnf_vif *vif;
int ret = 0;
vif = qtnf_mac_get_base_vif(mac);
if (!vif) {
pr_err("MAC%u: primary VIF is not configured\n", mac->macid);
ret = -EFAULT;
goto exit;
}
ret = qtnf_cmd_send_wowlan_set(vif, NULL);
if (ret) {
pr_err("MAC%u: failed to reset WoWLAN triggers\n",
mac->macid);
goto exit;
}
exit:
return ret;
}
static void qtnf_set_wakeup(struct wiphy *wiphy, bool enabled)
{
struct qtnf_wmac *mac = wiphy_priv(wiphy);
struct qtnf_bus *bus = mac->bus;
device_set_wakeup_enable(bus->dev, enabled);
}
#endif
static struct cfg80211_ops qtn_cfg80211_ops = {
.add_virtual_intf = qtnf_add_virtual_intf,
.change_virtual_intf = qtnf_change_virtual_intf,
@@ -886,6 +952,11 @@ static struct cfg80211_ops qtn_cfg80211_ops = {
.start_radar_detection = qtnf_start_radar_detection,
.set_mac_acl = qtnf_set_mac_acl,
.set_power_mgmt = qtnf_set_power_mgmt,
#ifdef CONFIG_PM
.suspend = qtnf_suspend,
.resume = qtnf_resume,
.set_wakeup = qtnf_set_wakeup,
#endif
};
static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in,
@@ -1038,6 +1109,11 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
if (hw_info->hw_capab & QLINK_HW_CAPAB_SCAN_RANDOM_MAC_ADDR)
wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
#ifdef CONFIG_PM
if (macinfo->wowlan)
wiphy->wowlan = macinfo->wowlan;
#endif
if (hw_info->hw_capab & QLINK_HW_CAPAB_REG_UPDATE) {
wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
REGULATORY_CUSTOM_REG;