summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo@kernel.org>2022-01-11 12:34:17 +0300
committerFelix Fietkau <nbd@nbd.name>2022-02-03 15:57:59 +0300
commit4ad65a54617c87bbf43ce677274fe2e65048dfbf (patch)
treeb7c00577a0fff0f58848617c29133b8f74ffd76b /drivers/net/wireless/mediatek
parent4abe5b9288173f130b9e5d0b98f12c128271e2f2 (diff)
downloadlinux-4ad65a54617c87bbf43ce677274fe2e65048dfbf.tar.xz
mt76: mt7921: toggle runtime-pm adding a monitor vif
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>
Diffstat (limited to 'drivers/net/wireless/mediatek')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac.h8
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c36
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/init.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/main.c23
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h1
5 files changed, 45 insertions, 25 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index 426adbb56a2d..b353c26b7d27 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -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 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
index 45a393070e46..dd04909d980a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
@@ -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;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
index ad59ef9839dc..6059d8a0f227 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
@@ -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;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 0e101f14e41f..0444ef3bd4b7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -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:
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index 63e3c7ef5e89..c401fbb88342 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -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