diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7921')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/init.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/main.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/sdio.c | 2 |
6 files changed, 37 insertions, 2 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index 48433c6d5e7d..ef0c721d26e3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -138,9 +138,14 @@ mt7921_regd_notifier(struct wiphy *wiphy, if (pm->suspended) return; + dev->regd_in_progress = true; + mt792x_mutex_acquire(dev); mt7921_regd_update(dev); mt792x_mutex_release(dev); + + dev->regd_in_progress = false; + wake_up(&dev->wait); } int mt7921_mac_init(struct mt792x_dev *dev) @@ -261,6 +266,7 @@ int mt7921_register_device(struct mt792x_dev *dev) spin_lock_init(&dev->pm.wake.lock); mutex_init(&dev->pm.mutex); init_waitqueue_head(&dev->pm.wait); + init_waitqueue_head(&dev->wait); if (mt76_is_sdio(&dev->mt76)) init_waitqueue_head(&dev->mt76.sdio.wait); spin_lock_init(&dev->pm.txq_lock); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 0d5adc5ddae3..ca36de34171b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -325,6 +325,19 @@ static void mt7921_roc_iter(void *priv, u8 *mac, mt7921_mcu_abort_roc(phy, mvif, phy->roc_token_id); } +void mt7921_roc_abort_sync(struct mt792x_dev *dev) +{ + struct mt792x_phy *phy = &dev->phy; + + del_timer_sync(&phy->roc_timer); + cancel_work_sync(&phy->roc_work); + if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) + ieee80211_iterate_active_interfaces(mt76_hw(dev), + IEEE80211_IFACE_ITER_RESUME_ALL, + mt7921_roc_iter, (void *)phy); +} +EXPORT_SYMBOL_GPL(mt7921_roc_abort_sync); + void mt7921_roc_work(struct work_struct *work) { struct mt792x_phy *phy; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index f5582477c7e4..8b4ce32a2cd1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1272,7 +1272,7 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, .mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, alpha2), }; int ret, valid_cnt = 0; - u16 buf_len = 0; + u32 buf_len = 0; u8 *pos; if (!clc) @@ -1283,7 +1283,7 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, if (mt76_find_power_limits_node(&dev->mt76)) req.cap |= CLC_CAP_DTS_EN; - buf_len = le16_to_cpu(clc->len) - sizeof(*clc); + buf_len = le32_to_cpu(clc->len) - sizeof(*clc); pos = clc->data; while (buf_len > 16) { struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 1cb21133992b..3016636d18c6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -322,4 +322,5 @@ int mt7921_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, enum mt7921_roc_req type, u8 token_id); int mt7921_mcu_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, u8 token_id); +void mt7921_roc_abort_sync(struct mt792x_dev *dev); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index dde26f327478..cda853e86676 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -6,6 +6,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/of.h> #include "mt7921.h" #include "../mt76_connac2_mac.h" @@ -369,6 +370,9 @@ static int mt7921_pci_probe(struct pci_dev *pdev, if (ret) goto err_free_irq; + if (of_property_read_bool(dev->mt76.dev->of_node, "wakeup-source")) + device_init_wakeup(dev->mt76.dev, true); + return 0; err_free_irq: @@ -386,7 +390,11 @@ static void mt7921_pci_remove(struct pci_dev *pdev) struct mt76_dev *mdev = pci_get_drvdata(pdev); struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); + if (of_property_read_bool(dev->mt76.dev->of_node, "wakeup-source")) + device_init_wakeup(dev->mt76.dev, false); + mt7921e_unregister_device(dev); + set_bit(MT76_REMOVED, &mdev->phy.state); devm_free_irq(&pdev->dev, pdev->irq, dev); mt76_free_device(&dev->mt76); pci_free_irq_vectors(pdev); @@ -405,10 +413,15 @@ static int mt7921_pci_suspend(struct device *device) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); + mt7921_roc_abort_sync(dev); + err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto restore_suspend; + wait_event_timeout(dev->wait, + !dev->regd_in_progress, 5 * HZ); + err = mt76_connac_mcu_set_hif_suspend(mdev, true); if (err) goto restore_suspend; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c index a9ce1e746b95..004d942ee11a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c @@ -216,6 +216,8 @@ static int mt7921s_suspend(struct device *__dev) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); + mt7921_roc_abort_sync(dev); + err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto restore_suspend; |