2020-09-26 15:23:09

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH] mt76: mt7615: enable beacon filtering by default for offload fw

In order to reduce cpu cycles, enable hw beacon filter by default if the
device is running offload fw

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
.../wireless/mediatek/mt76/mt7615/debugfs.c | 9 +++-
.../net/wireless/mediatek/mt76/mt7615/mac.c | 43 -------------------
.../net/wireless/mediatek/mt76/mt7615/main.c | 26 ++---------
.../net/wireless/mediatek/mt76/mt7615/mcu.c | 29 ++++++++++---
.../wireless/mediatek/mt76/mt7615/mt7615.h | 3 +-
5 files changed, 35 insertions(+), 75 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
index 00ba550fc48f..2eaf6e4529a8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
@@ -59,7 +59,14 @@ mt7615_pm_set(void *data, u64 val)
if (!mt7615_wait_for_mcu_init(dev))
return 0;

- return mt7615_pm_set_enable(dev, val);
+ if (!mt7615_firmware_offload(dev) || !mt76_is_mmio(&dev->mt76))
+ return -EOPNOTSUPP;
+
+ mt7615_mutex_acquire(dev);
+ dev->pm.enable = val;
+ mt7615_mutex_release(dev);
+
+ return 0;
}

static int
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index 8dc645e398fd..40a34a5126e4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -1969,49 +1969,6 @@ void mt7615_pm_power_save_work(struct work_struct *work)
queue_delayed_work(dev->mt76.wq, &dev->pm.ps_work, delta);
}

-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;
-
- mt7615_mutex_acquire(dev);
-
- if (dev->pm.enable == 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);
-
- return 0;
-}
-
void mt7615_mac_work(struct work_struct *work)
{
struct mt7615_phy *phy;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 3186b7b2ca48..ab68997b7b43 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -211,15 +211,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
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);
- }
+ mt7615_mcu_set_bss_pm(phy, vif, true);
out:
mt7615_mutex_release(dev);

@@ -245,13 +237,6 @@ 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);
@@ -511,7 +496,6 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
} while (0)

phy->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
- MT_WF_RFCR_DROP_OTHER_BEACON |
MT_WF_RFCR_DROP_FRAME_REPORT |
MT_WF_RFCR_DROP_PROBEREQ |
MT_WF_RFCR_DROP_MCAST_FILTERED |
@@ -521,6 +505,8 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
MT_WF_RFCR_DROP_A2_BSSID |
MT_WF_RFCR_DROP_UNWANTED_CTL |
MT_WF_RFCR_DROP_STBC_MULTI);
+ if (!mt7615_firmware_offload(dev))
+ phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_BEACON;

MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |
MT_WF_RFCR_DROP_A3_MAC |
@@ -1127,7 +1113,6 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
{
struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt7615_phy *phy = mt7615_hw_phy(hw);
- bool ext_phy = phy != &dev->phy;
int err = 0;

cancel_delayed_work_sync(&dev->pm.ps_work);
@@ -1139,8 +1124,6 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
cancel_delayed_work_sync(&phy->scan_work);
cancel_delayed_work_sync(&phy->mac_work);

- mt76_set(dev, MT_WF_RFCR(ext_phy), MT_WF_RFCR_DROP_OTHER_BEACON);
-
set_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
ieee80211_iterate_active_interfaces(hw,
IEEE80211_IFACE_ITER_RESUME_ALL,
@@ -1158,7 +1141,7 @@ static int mt7615_resume(struct ieee80211_hw *hw)
{
struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt7615_phy *phy = mt7615_hw_phy(hw);
- bool running, ext_phy = phy != &dev->phy;
+ bool running;

mt7615_mutex_acquire(dev);

@@ -1182,7 +1165,6 @@ static int mt7615_resume(struct ieee80211_hw *hw)

ieee80211_queue_delayed_work(hw, &phy->mac_work,
MT7615_WATCHDOG_TIME);
- mt76_clear(dev, MT_WF_RFCR(ext_phy), MT_WF_RFCR_DROP_OTHER_BEACON);

mt7615_mutex_release(dev);

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
index 8de9bba384f4..462299ca85c1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
@@ -3499,7 +3499,7 @@ int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy)
return ret;
}

-int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
+int mt7615_mcu_set_bss_pm(struct mt7615_phy *phy, struct ieee80211_vif *vif,
bool enable)
{
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
@@ -3525,19 +3525,36 @@ int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
} req_hdr = {
.bss_idx = mvif->idx,
};
+ struct mt7615_dev *dev = phy->dev;
+ bool ext_phy = phy != &dev->phy;
int err;

if (vif->type != NL80211_IFTYPE_STATION ||
!mt7615_firmware_offload(dev))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;

err = __mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_BSS_ABORT,
&req_hdr, sizeof(req_hdr), false);
- if (err < 0 || !enable)
+ if (err < 0)
return err;

- return __mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_BSS_CONNECTED,
- &req, sizeof(req), false);
+ if (enable) {
+ err = __mt76_mcu_send_msg(&dev->mt76,
+ MCU_CMD_SET_BSS_CONNECTED,
+ &req, sizeof(req), false);
+ if (err < 0)
+ return err;
+
+ 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);
+ }
+
+ return 0;
}

#ifdef CONFIG_PM
@@ -3743,8 +3760,6 @@ void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
int i;

- mt7615_mcu_set_bss_pm(phy->dev, vif, suspend);
-
mt7615_mcu_set_gtk_rekey(phy->dev, vif, suspend);
mt7615_mcu_set_arp_filter(phy->dev, vif, suspend);

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index 716956b58c13..84ae6ee0ef75 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -452,7 +452,6 @@ bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev);
void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
struct ieee80211_tx_rate *probe_rate,
struct ieee80211_tx_rate *rates);
-int mt7615_pm_set_enable(struct mt7615_dev *dev, bool enable);
void mt7615_pm_wake_work(struct work_struct *work);
int mt7615_pm_wake(struct mt7615_dev *dev);
void mt7615_pm_power_save_sched(struct mt7615_dev *dev);
@@ -651,7 +650,7 @@ int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
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,
+int mt7615_mcu_set_bss_pm(struct mt7615_phy *phy, 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,
--
2.26.2


2020-09-27 16:10:53

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH] mt76: mt7615: enable beacon filtering by default for offload fw

On 2020-09-26 17:22, Lorenzo Bianconi wrote:
> In order to reduce cpu cycles, enable hw beacon filter by default if the
> device is running offload fw
>
> Signed-off-by: Lorenzo Bianconi <[email protected]>
The beacon filtering part and runtime pm needs to take into account that
there could be more than one vif and we might be running an AP as well.

- Felix

2020-09-27 16:28:01

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH] mt76: mt7615: enable beacon filtering by default for offload fw

>
> On 2020-09-26 17:22, Lorenzo Bianconi wrote:
> > In order to reduce cpu cycles, enable hw beacon filter by default if the
> > device is running offload fw
> >
> > Signed-off-by: Lorenzo Bianconi <[email protected]>
> The beacon filtering part and runtime pm needs to take into account that
> there could be more than one vif and we might be running an AP as well.
>
> - Felix
>

Do you mean we should run mt7615_mcu_set_bss_pm() for other vif types, e.g. AP?
IIUC the fw can manage the rx beacon offload even for other modes.

@Sean: do we need to send any other message to mcu for rx beacon
offload for AP mode? Can the fw properly manage it?

Regards,
Lorenzo

2020-09-27 17:13:35

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH] mt76: mt7615: enable beacon filtering by default for offload fw


On 2020-09-27 18:27, Lorenzo Bianconi wrote:
>>
>> On 2020-09-26 17:22, Lorenzo Bianconi wrote:
>> > In order to reduce cpu cycles, enable hw beacon filter by default if the
>> > device is running offload fw
>> >
>> > Signed-off-by: Lorenzo Bianconi <[email protected]>
>> The beacon filtering part and runtime pm needs to take into account that
>> there could be more than one vif and we might be running an AP as well.
>>
>> - Felix
>>
>
> Do you mean we should run mt7615_mcu_set_bss_pm() for other vif types, e.g. AP?
> IIUC the fw can manage the rx beacon offload even for other modes.
>
> @Sean: do we need to send any other message to mcu for rx beacon
> offload for AP mode? Can the fw properly manage it?
I think we need to clear MT_WF_RFCR_DROP_OTHER_BEACON (since it's a
global bit) and maybe also dev->pm.enable if we have an active interface
that is not in client mode.

- Felix