mt76: mt7921: toggle runtime-pm adding a monitor vif
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 11 Jan 2022 09:34:17 +0000 (10:34 +0100)
committerFelix Fietkau <nbd@nbd.name>
Thu, 3 Feb 2022 12:57:59 +0000 (13:57 +0100)
Toggle runtime-pm and deep-sleep configuration adding/removing
a montior vif in order to forward all tx/rx frames to mac80211.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Tested-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76_connac.h
drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
drivers/net/wireless/mediatek/mt76/mt7921/init.c
drivers/net/wireless/mediatek/mt76/mt7921/main.c
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h

index 426adbb56a2dca19a75914333037e2230970b099..b353c26b7d27b7e8e3b5710cf5860ba49346c099 100644 (file)
@@ -45,9 +45,11 @@ enum {
 };
 
 struct mt76_connac_pm {
-       bool enable;
-       bool ds_enable;
-       bool suspended;
+       bool enable:1;
+       bool enable_user:1;
+       bool ds_enable:1;
+       bool ds_enable_user:1;
+       bool suspended:1;
 
        spinlock_t txq_lock;
        struct {
index 45a393070e465196961b44a59799b3aba090b5ee..dd04909d980a38f59b76d90e50ddc5516d90732c 100644 (file)
@@ -262,14 +262,6 @@ mt7921_txpwr(struct seq_file *s, void *data)
        return 0;
 }
 
-static void
-mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct mt7921_dev *dev = priv;
-
-       mt7921_mcu_set_beacon_filter(dev, vif, dev->pm.enable);
-}
-
 static int
 mt7921_pm_set(void *data, u64 val)
 {
@@ -278,10 +270,10 @@ mt7921_pm_set(void *data, u64 val)
 
        mutex_lock(&dev->mt76.mutex);
 
-       if (val == pm->enable)
+       if (val == pm->enable_user)
                goto out;
 
-       if (!pm->enable) {
+       if (!pm->enable_user) {
                pm->stats.last_wake_event = jiffies;
                pm->stats.last_doze_event = jiffies;
        }
@@ -291,12 +283,8 @@ mt7921_pm_set(void *data, u64 val)
        pm->enable = false;
        mt76_connac_pm_wake(&dev->mphy, pm);
 
-       pm->enable = val;
-       ieee80211_iterate_active_interfaces(mt76_hw(dev),
-                                           IEEE80211_IFACE_ITER_RESUME_ALL,
-                                           mt7921_pm_interface_iter, dev);
-
-       mt76_connac_mcu_set_deep_sleep(&dev->mt76, pm->ds_enable);
+       pm->enable_user = val;
+       mt7921_set_runtime_pm(dev);
        mt76_connac_power_save_sched(&dev->mphy, pm);
 out:
        mutex_unlock(&dev->mt76.mutex);
@@ -309,7 +297,7 @@ mt7921_pm_get(void *data, u64 *val)
 {
        struct mt7921_dev *dev = data;
 
-       *val = dev->pm.enable;
+       *val = dev->pm.enable_user;
 
        return 0;
 }
@@ -321,13 +309,17 @@ mt7921_deep_sleep_set(void *data, u64 val)
 {
        struct mt7921_dev *dev = data;
        struct mt76_connac_pm *pm = &dev->pm;
+       bool monitor = !!(dev->mphy.hw->conf.flags & IEEE80211_CONF_MONITOR);
        bool enable = !!val;
 
        mt7921_mutex_acquire(dev);
-       if (pm->ds_enable != enable) {
-               mt76_connac_mcu_set_deep_sleep(&dev->mt76, enable);
-               pm->ds_enable = enable;
-       }
+       if (pm->ds_enable_user == enable)
+               goto out;
+
+       pm->ds_enable_user = enable;
+       pm->ds_enable = enable && !monitor;
+       mt76_connac_mcu_set_deep_sleep(&dev->mt76, pm->ds_enable);
+out:
        mt7921_mutex_release(dev);
 
        return 0;
@@ -338,7 +330,7 @@ mt7921_deep_sleep_get(void *data, u64 *val)
 {
        struct mt7921_dev *dev = data;
 
-       *val = dev->pm.ds_enable;
+       *val = dev->pm.ds_enable_user;
 
        return 0;
 }
index ad59ef9839dc28e5a45abb2b6e89b88de621e2d6..6059d8a0f2270d7a652e4f106c9e6019b048aa5d 100644 (file)
@@ -229,7 +229,9 @@ int mt7921_register_device(struct mt7921_dev *dev)
 
        /* TODO: mt7921s run sleep mode on default  */
        if (mt76_is_mmio(&dev->mt76)) {
+               dev->pm.enable_user = true;
                dev->pm.enable = true;
+               dev->pm.ds_enable_user = true;
                dev->pm.ds_enable = true;
        }
 
index 0e101f14e41ff017a4c765d3e261f2a7a96e56dd..0444ef3bd4b705e3fa225935f0fe34d202f58074 100644 (file)
@@ -471,6 +471,28 @@ out:
        return err;
 }
 
+static void
+mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct mt7921_dev *dev = priv;
+
+       mt7921_mcu_set_beacon_filter(dev, vif, dev->pm.enable);
+}
+
+void mt7921_set_runtime_pm(struct mt7921_dev *dev)
+{
+       struct ieee80211_hw *hw = dev->mphy.hw;
+       struct mt76_connac_pm *pm = &dev->pm;
+       bool monitor = !!(hw->conf.flags & IEEE80211_CONF_MONITOR);
+
+       pm->enable = pm->enable_user && !monitor;
+       ieee80211_iterate_active_interfaces(hw,
+                                           IEEE80211_IFACE_ITER_RESUME_ALL,
+                                           mt7921_pm_interface_iter, dev);
+       pm->ds_enable = pm->ds_enable_user && !monitor;
+       mt76_connac_mcu_set_deep_sleep(&dev->mt76, pm->ds_enable);
+}
+
 static int mt7921_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct mt7921_dev *dev = mt7921_hw_dev(hw);
@@ -504,6 +526,7 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed)
                mt76_rmw_field(dev, MT_DMA_DCR0(0), MT_DMA_DCR0_RXD_G5_EN,
                               enabled);
                mt76_wr(dev, MT_WF_RFCR(0), phy->rxfilter);
+               mt7921_set_runtime_pm(dev);
        }
 
 out:
index 63e3c7ef5e89c6c2f9452b96ff492a5fe97a0423..c401fbb8834257bf30a374ee9a580eddddadd05a 100644 (file)
@@ -457,4 +457,5 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
 bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update);
 void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data);
+void mt7921_set_runtime_pm(struct mt7921_dev *dev);
 #endif