Commit 4ad65a54 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

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: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Tested-by: default avatarSven Eckelmann <sven@narfation.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 4abe5b92
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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 {
+14 −22
Original line number Diff line number Diff line
@@ -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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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;
	}

+23 −0
Original line number Diff line number Diff line
@@ -471,6 +471,28 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
	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:
+1 −0
Original line number Diff line number Diff line
@@ -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