| From 1879c122435092c63eb0e8156f6e75d8e147fa13 Mon Sep 17 00:00:00 2001 |
| From: "fancy.liu" <fancy.liu@mediatek.com> |
| Date: Tue, 14 Nov 2023 10:13:24 +0800 |
| Subject: [PATCH 020/199] mtk: mt76: mt7996: ACS channel time too long on duty |
| channel |
| |
| Step and issue: |
| 1. Set channel to 36 in hostapd config; |
| 2. Bootup; |
| 3. Enable ACS through UCI command and reload; |
| 4. Check hostapd log, channel 36 channel_time is much longer than other channels. |
| |
| Root cause: |
| The reset chan_stat condition missed duty channel. |
| |
| Solution: |
| When scan start, need to reset chan_stat in each channel switch. |
| |
| Issue: |
| There's a chance that the channel time for duty channel is zero in ACS |
| scan. |
| |
| Root cause: |
| The chan_stat may be reset when restore to duty channel. |
| Mac80211 will notify to hostapd when scan done and then restore to duty |
| channel. |
| And mt76 will clear scan flag after restore done. |
| If hostapd get the chan_stat before channel_restore, will get the |
| correct channel time; |
| If hostapd get the chan_stat after channel_restore, will get zero |
| channel time; |
| |
| Solution: |
| When channel switch, will check the mac80211 scan state but not the mt76 scan flag. |
| Mac80211 scan state will be set in scanning, and will be reset after |
| scan done and before restore to duty channel. |
| |
| Signed-off-by: fancy.liu <fancy.liu@mediatek.com> |
| --- |
| mac80211.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| diff --git a/mac80211.c b/mac80211.c |
| index 6d47b26d..9df9109f 100644 |
| --- a/mac80211.c |
| +++ b/mac80211.c |
| @@ -928,6 +928,7 @@ void mt76_set_channel(struct mt76_phy *phy) |
| struct cfg80211_chan_def *chandef = &hw->conf.chandef; |
| bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL; |
| int timeout = HZ / 5; |
| + unsigned long was_scanning = ieee80211_get_scanning(hw); |
| |
| wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout); |
| mt76_update_survey(phy); |
| @@ -942,7 +943,7 @@ void mt76_set_channel(struct mt76_phy *phy) |
| if (!offchannel) |
| phy->main_chan = chandef->chan; |
| |
| - if (chandef->chan != phy->main_chan) |
| + if (chandef->chan != phy->main_chan || was_scanning) |
| memset(phy->chan_state, 0, sizeof(*phy->chan_state)); |
| } |
| EXPORT_SYMBOL_GPL(mt76_set_channel); |
| -- |
| 2.18.0 |
| |