Skip to content

Commit ffa1bf9

Browse files
moore-brosnbd168
authored andcommitted
mt76: mt7921: introduce PM support
Introduce suspend/resume and WoW (Wake-on-WoWLAN) support to mt7921 driver to allow remote wakeu-up from the suspend state. Co-developed-by: Lorenzo Bianconi <[email protected]> Signed-off-by: Lorenzo Bianconi <[email protected]> Co-developed-by: Soul Huang <[email protected]> Signed-off-by: Soul Huang <[email protected]> Signed-off-by: Sean Wang <[email protected]> Signed-off-by: Felix Fietkau <[email protected]>
1 parent b88f5c6 commit ffa1bf9

File tree

5 files changed

+589
-0
lines changed

5 files changed

+589
-0
lines changed

drivers/net/wireless/mediatek/mt76/mt7921/main.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,79 @@ static void mt7921_sta_statistics(struct ieee80211_hw *hw,
966966
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
967967
}
968968

969+
#ifdef CONFIG_PM
970+
static int mt7921_suspend(struct ieee80211_hw *hw,
971+
struct cfg80211_wowlan *wowlan)
972+
{
973+
struct mt7921_dev *dev = mt7921_hw_dev(hw);
974+
struct mt7921_phy *phy = mt7921_hw_phy(hw);
975+
int err;
976+
977+
cancel_delayed_work_sync(&phy->scan_work);
978+
cancel_delayed_work_sync(&phy->mt76->mac_work);
979+
980+
mutex_lock(&dev->mt76.mutex);
981+
982+
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
983+
984+
set_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
985+
ieee80211_iterate_active_interfaces(hw,
986+
IEEE80211_IFACE_ITER_RESUME_ALL,
987+
mt7921_mcu_set_suspend_iter, phy);
988+
989+
err = mt7921_mcu_set_hif_suspend(dev, true);
990+
991+
mutex_unlock(&dev->mt76.mutex);
992+
993+
return err;
994+
}
995+
996+
static int mt7921_resume(struct ieee80211_hw *hw)
997+
{
998+
struct mt7921_dev *dev = mt7921_hw_dev(hw);
999+
struct mt7921_phy *phy = mt7921_hw_phy(hw);
1000+
int err;
1001+
1002+
mutex_lock(&dev->mt76.mutex);
1003+
1004+
err = mt7921_mcu_set_hif_suspend(dev, false);
1005+
if (err < 0)
1006+
goto out;
1007+
1008+
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
1009+
clear_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
1010+
ieee80211_iterate_active_interfaces(hw,
1011+
IEEE80211_IFACE_ITER_RESUME_ALL,
1012+
mt7921_mcu_set_suspend_iter, phy);
1013+
1014+
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
1015+
MT7921_WATCHDOG_TIME);
1016+
out:
1017+
mutex_unlock(&dev->mt76.mutex);
1018+
1019+
return err;
1020+
}
1021+
1022+
static void mt7921_set_wakeup(struct ieee80211_hw *hw, bool enabled)
1023+
{
1024+
struct mt7921_dev *dev = mt7921_hw_dev(hw);
1025+
struct mt76_dev *mdev = &dev->mt76;
1026+
1027+
device_set_wakeup_enable(mdev->dev, enabled);
1028+
}
1029+
1030+
static void mt7921_set_rekey_data(struct ieee80211_hw *hw,
1031+
struct ieee80211_vif *vif,
1032+
struct cfg80211_gtk_rekey_data *data)
1033+
{
1034+
struct mt7921_dev *dev = mt7921_hw_dev(hw);
1035+
1036+
mutex_lock(&dev->mt76.mutex);
1037+
mt7921_mcu_update_gtk_rekey(hw, vif, data);
1038+
mutex_unlock(&dev->mt76.mutex);
1039+
}
1040+
#endif /* CONFIG_PM */
1041+
9691042
const struct ieee80211_ops mt7921_ops = {
9701043
.tx = mt7921_tx,
9711044
.start = mt7921_start,
@@ -998,4 +1071,10 @@ const struct ieee80211_ops mt7921_ops = {
9981071
.sta_statistics = mt7921_sta_statistics,
9991072
.sched_scan_start = mt7921_start_sched_scan,
10001073
.sched_scan_stop = mt7921_stop_sched_scan,
1074+
#ifdef CONFIG_PM
1075+
.suspend = mt7921_suspend,
1076+
.resume = mt7921_resume,
1077+
.set_wakeup = mt7921_set_wakeup,
1078+
.set_rekey_data = mt7921_set_rekey_data,
1079+
#endif /* CONFIG_PM */
10011080
};

0 commit comments

Comments
 (0)