Commit d0a2bc5f authored by Ming Yen Hsieh's avatar Ming Yen Hsieh Committed by Felix Fietkau

wifi: mt76: mt7921: fix CLC command timeout when suspend/resume

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: 4fc8df50 ("wifi: mt76: mt7921: get regulatory information from the clc event")
Signed-off-by: default avatarMing Yen Hsieh <mingyen.hsieh@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent fa6ad88e
...@@ -110,24 +110,37 @@ mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) ...@@ -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 static void
mt7921_regd_notifier(struct wiphy *wiphy, mt7921_regd_notifier(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
{ {
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct mt792x_dev *dev = mt792x_hw_dev(hw); 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)); memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));
dev->mt76.region = request->dfs_region; dev->mt76.region = request->dfs_region;
dev->country_ie_env = request->country_ie_env; dev->country_ie_env = request->country_ie_env;
if (pm->suspended)
return;
mt792x_mutex_acquire(dev); mt792x_mutex_acquire(dev);
mt7921_mcu_set_clc(dev, request->alpha2, request->country_ie_env); mt7921_regd_update(dev);
mt76_connac_mcu_set_channel_domain(hw->priv);
mt7921_set_tx_sar_pwr(hw, NULL);
mt792x_mutex_release(dev); mt792x_mutex_release(dev);
mt7921_regd_channel_update(wiphy, dev);
} }
int mt7921_mac_init(struct mt792x_dev *dev) int mt7921_mac_init(struct mt792x_dev *dev)
......
...@@ -234,6 +234,7 @@ mt7921_l1_rmw(struct mt792x_dev *dev, u32 addr, u32 mask, u32 val) ...@@ -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_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) #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); int mt7921_mac_init(struct mt792x_dev *dev);
bool mt7921_mac_wtbl_update(struct mt792x_dev *dev, int idx, u32 mask); 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, int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
......
...@@ -507,6 +507,9 @@ static int mt7921_pci_resume(struct device *device) ...@@ -507,6 +507,9 @@ static int mt7921_pci_resume(struct device *device)
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
err = mt76_connac_mcu_set_hif_suspend(mdev, false); err = mt76_connac_mcu_set_hif_suspend(mdev, false);
mt7921_regd_update(dev);
failed: failed:
pm->suspended = false; pm->suspended = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment