Commit 83b9f42a authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

mt76: mt7615: enable beacon hw filter for runtime-pm



In order to reduce number of received interrupts and power consumption,
enable hw beacon filter if runtime-pm is enabled

Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent b5b4c7dd
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -1929,8 +1929,31 @@ void mt7615_pm_power_save_work(struct work_struct *work)
				   MT7615_PM_TIMEOUT);
}

static void
mt7615_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
	struct mt7615_phy *phy = priv;
	struct mt7615_dev *dev = phy->dev;
	bool ext_phy = phy != &dev->phy;

	if (mt7615_mcu_set_bss_pm(dev, vif, dev->pm.enable))
		return;

	if (dev->pm.enable) {
		vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
		mt76_set(dev, MT_WF_RFCR(ext_phy),
			 MT_WF_RFCR_DROP_OTHER_BEACON);
	} else {
		vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
		mt76_clear(dev, MT_WF_RFCR(ext_phy),
			   MT_WF_RFCR_DROP_OTHER_BEACON);
	}
}

int mt7615_pm_set_enable(struct mt7615_dev *dev, bool enable)
{
	struct mt76_phy *mphy = dev->phy.mt76;

	if (!mt7615_firmware_offload(dev) || !mt76_is_mmio(&dev->mt76))
		return -EOPNOTSUPP;

@@ -1940,6 +1963,9 @@ int mt7615_pm_set_enable(struct mt7615_dev *dev, bool enable)
		goto out;

	dev->pm.enable = enable;
	ieee80211_iterate_active_interfaces(mphy->hw,
					    IEEE80211_IFACE_ITER_RESUME_ALL,
					    mt7615_pm_interface_iter, mphy->priv);
out:
	mt7615_mutex_release(dev);

+19 −0
Original line number Diff line number Diff line
@@ -209,6 +209,18 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
	}

	ret = mt7615_mcu_add_dev_info(dev, vif, true);
	if (ret)
		goto out;

	if (dev->pm.enable) {
		ret = mt7615_mcu_set_bss_pm(dev, vif, true);
		if (ret)
			goto out;

		vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
		mt76_set(dev, MT_WF_RFCR(ext_phy),
			 MT_WF_RFCR_DROP_OTHER_BEACON);
	}
out:
	mt7615_mutex_release(dev);

@@ -234,6 +246,13 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,

	mt7615_free_pending_tx_skbs(dev, msta);

	if (dev->pm.enable) {
		bool ext_phy = phy != &dev->phy;

		mt7615_mcu_set_bss_pm(dev, vif, false);
		mt76_clear(dev, MT_WF_RFCR(ext_phy),
			   MT_WF_RFCR_DROP_OTHER_BEACON);
	}
	mt7615_mcu_add_dev_info(dev, vif, false);

	rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
+36 −37
Original line number Diff line number Diff line
@@ -3460,42 +3460,7 @@ int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy)
	return ret;
}

#ifdef CONFIG_PM
int mt7615_mcu_set_hif_suspend(struct mt7615_dev *dev, bool suspend)
{
	struct {
		struct {
			u8 hif_type; /* 0x0: HIF_SDIO
				      * 0x1: HIF_USB
				      * 0x2: HIF_PCIE
				      */
			u8 pad[3];
		} __packed hdr;
		struct hif_suspend_tlv {
			__le16 tag;
			__le16 len;
			u8 suspend;
		} __packed hif_suspend;
	} req = {
		.hif_suspend = {
			.tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
			.len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
			.suspend = suspend,
		},
	};

	if (mt76_is_mmio(&dev->mt76))
		req.hdr.hif_type = 2;
	else if (mt76_is_usb(&dev->mt76))
		req.hdr.hif_type = 1;

	return __mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_HIF_CTRL,
				   &req, sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt7615_mcu_set_hif_suspend);

static int
mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
			  bool enable)
{
	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
@@ -3536,6 +3501,40 @@ mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
				   &req, sizeof(req), false);
}

#ifdef CONFIG_PM
int mt7615_mcu_set_hif_suspend(struct mt7615_dev *dev, bool suspend)
{
	struct {
		struct {
			u8 hif_type; /* 0x0: HIF_SDIO
				      * 0x1: HIF_USB
				      * 0x2: HIF_PCIE
				      */
			u8 pad[3];
		} __packed hdr;
		struct hif_suspend_tlv {
			__le16 tag;
			__le16 len;
			u8 suspend;
		} __packed hif_suspend;
	} req = {
		.hif_suspend = {
			.tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
			.len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
			.suspend = suspend,
		},
	};

	if (mt76_is_mmio(&dev->mt76))
		req.hdr.hif_type = 2;
	else if (mt76_is_usb(&dev->mt76))
		req.hdr.hif_type = 1;

	return __mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_HIF_CTRL,
				   &req, sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt7615_mcu_set_hif_suspend);

static int
mt7615_mcu_set_wow_ctrl(struct mt7615_phy *phy, struct ieee80211_vif *vif,
			bool suspend, struct cfg80211_wowlan *wowlan)
+2 −0
Original line number Diff line number Diff line
@@ -640,6 +640,8 @@ int mt7615_driver_own(struct mt7615_dev *dev);
int mt7615_init_debugfs(struct mt7615_dev *dev);
int mt7615_mcu_wait_response(struct mt7615_dev *dev, int cmd, int seq);

int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
			  bool enable);
int mt7615_mcu_set_hif_suspend(struct mt7615_dev *dev, bool suspend);
void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
				 struct ieee80211_vif *vif);