wifi: mt76: mt7921: fix CLC command timeout when suspend/resume
authorMing Yen Hsieh <mingyen.hsieh@mediatek.com>
Wed, 22 Nov 2023 03:06:45 +0000 (11:06 +0800)
committerFelix Fietkau <nbd@nbd.name>
Mon, 11 Dec 2023 12:11:53 +0000 (13:11 +0100)
When enter suspend/resume while in a connected state, the upper layer
will trigger disconnection before entering suspend, and at the same time,
it will trigger regd_notifier() and update CLC, causing the CLC event to
not be received due to suspend, resulting in a command timeout.

Therefore, the update of CLC is postponed until resume, to ensure data
consistency and avoid the occurrence of command timeout.

Fixes: 4fc8df50fd41 ("wifi: mt76: mt7921: get regulatory information from the clc event")
Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7921/init.c
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
drivers/net/wireless/mediatek/mt76/mt7921/pci.c

index 7d6a9d746011102a6fe06b35acdb32cdcf240abf..48433c6d5e7d30e902a7659bd443641e672f9583 100644 (file)
@@ -110,24 +110,37 @@ mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)
        }
 }
 
+void mt7921_regd_update(struct mt792x_dev *dev)
+{
+       struct mt76_dev *mdev = &dev->mt76;
+       struct ieee80211_hw *hw = mdev->hw;
+       struct wiphy *wiphy = hw->wiphy;
+
+       mt7921_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env);
+       mt7921_regd_channel_update(wiphy, dev);
+       mt76_connac_mcu_set_channel_domain(hw->priv);
+       mt7921_set_tx_sar_pwr(hw, NULL);
+}
+EXPORT_SYMBOL_GPL(mt7921_regd_update);
+
 static void
 mt7921_regd_notifier(struct wiphy *wiphy,
                     struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct mt792x_dev *dev = mt792x_hw_dev(hw);
+       struct mt76_connac_pm *pm = &dev->pm;
 
        memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));
        dev->mt76.region = request->dfs_region;
        dev->country_ie_env = request->country_ie_env;
 
+       if (pm->suspended)
+               return;
+
        mt792x_mutex_acquire(dev);
-       mt7921_mcu_set_clc(dev, request->alpha2, request->country_ie_env);
-       mt76_connac_mcu_set_channel_domain(hw->priv);
-       mt7921_set_tx_sar_pwr(hw, NULL);
+       mt7921_regd_update(dev);
        mt792x_mutex_release(dev);
-
-       mt7921_regd_channel_update(wiphy, dev);
 }
 
 int mt7921_mac_init(struct mt792x_dev *dev)
index fcca93b3e14c52e83ba81926a4f49aaafa1a494f..1cb21133992b700fbcccbb730062caaa4b7ac505 100644 (file)
@@ -234,6 +234,7 @@ mt7921_l1_rmw(struct mt792x_dev *dev, u32 addr, u32 mask, u32 val)
 #define mt7921_l1_set(dev, addr, val)  mt7921_l1_rmw(dev, addr, 0, val)
 #define mt7921_l1_clear(dev, addr, val)        mt7921_l1_rmw(dev, addr, val, 0)
 
+void mt7921_regd_update(struct mt792x_dev *dev);
 int mt7921_mac_init(struct mt792x_dev *dev);
 bool mt7921_mac_wtbl_update(struct mt792x_dev *dev, int idx, u32 mask);
 int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
index 9bdaddd310be9053d024f423c4ddb035338f7198..57903c6e4f11f0735fd80c4a3c54c4299ca48be0 100644 (file)
@@ -507,6 +507,9 @@ static int mt7921_pci_resume(struct device *device)
                mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
 
        err = mt76_connac_mcu_set_hif_suspend(mdev, false);
+
+       mt7921_regd_update(dev);
+
 failed:
        pm->suspended = false;