mt76: mt7615: enable beacon hw filter for runtime-pm
authorLorenzo Bianconi <lorenzo@kernel.org>
Fri, 3 Jul 2020 08:15:59 +0000 (10:15 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 21 Jul 2020 17:01:17 +0000 (19:01 +0200)
In order to reduce number of received interrupts and power consumption,
enable hw beacon filter if runtime-pm is enabled

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7615/mac.c
drivers/net/wireless/mediatek/mt76/mt7615/main.c
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h

index 59f788be72681a68b7c9ac80c3afc230a1f13cdb..1c86ecf8fcd981fa0f3e131022647f8afd6299a4 100644 (file)
@@ -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);
 
index 0ce76472df2ceb6f090b68609cc3593d4fc5794c..b1cfae7c4b557992219d7c99b8dbb7255e5e5a4e 100644 (file)
@@ -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);
index 6118c2eeece867a36ca91367fbc1c6ed5340b8ce..2d10154516995f2d15177eea7b90195a16e8c1dc 100644 (file)
@@ -3460,43 +3460,8 @@ out:
        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,
-                     bool enable)
+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;
        struct {
@@ -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)
index ad7b206ab043b966dbb763068b248a6d976265e4..9bbfe1168208737fe4d7ff754f788309fd2c5184 100644 (file)
@@ -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);