OSDN Git Service

mt76: mt7921: move mt7921_init_hw in a dedicated work
authorLorenzo Bianconi <lorenzo@kernel.org>
Mon, 14 Mar 2022 16:29:13 +0000 (17:29 +0100)
committerFelix Fietkau <nbd@nbd.name>
Wed, 16 Mar 2022 16:40:23 +0000 (17:40 +0100)
Firmware initialization can take a while. Move mt7921_init_hw routine in
a dedicated work in order to not slow down bootstrap process.

Tested-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
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
drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
drivers/net/wireless/mediatek/mt76/mt7921/usb.c

index ceb2265..91fc419 100644 (file)
@@ -165,7 +165,7 @@ out:
 
 static int mt7921_init_hardware(struct mt7921_dev *dev)
 {
-       int ret, idx, i;
+       int ret, i;
 
        set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
 
@@ -182,6 +182,13 @@ static int mt7921_init_hardware(struct mt7921_dev *dev)
                return ret;
        }
 
+       return 0;
+}
+
+static int mt7921_init_wcid(struct mt7921_dev *dev)
+{
+       int idx;
+
        /* Beacon and mgmt frames should occupy wcid 0 */
        idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7921_WTBL_STA - 1);
        if (idx)
@@ -195,6 +202,38 @@ static int mt7921_init_hardware(struct mt7921_dev *dev)
        return 0;
 }
 
+static void mt7921_init_work(struct work_struct *work)
+{
+       struct mt7921_dev *dev = container_of(work, struct mt7921_dev,
+                                             init_work);
+       int ret;
+
+       ret = mt7921_init_hardware(dev);
+       if (ret)
+               return;
+
+       mt76_set_stream_caps(&dev->mphy, true);
+       mt7921_set_stream_he_caps(&dev->phy);
+
+       ret = mt76_register_device(&dev->mt76, true, mt76_rates,
+                                  ARRAY_SIZE(mt76_rates));
+       if (ret) {
+               dev_err(dev->mt76.dev, "register device failed\n");
+               return;
+       }
+
+       ret = mt7921_init_debugfs(dev);
+       if (ret) {
+               dev_err(dev->mt76.dev, "register debugfs failed\n");
+               return;
+       }
+
+       /* we support chip reset now */
+       dev->hw_init_done = true;
+
+       mt76_connac_mcu_set_deep_sleep(&dev->mt76, dev->pm.ds_enable);
+}
+
 int mt7921_register_device(struct mt7921_dev *dev)
 {
        struct ieee80211_hw *hw = mt76_hw(dev);
@@ -222,6 +261,7 @@ int mt7921_register_device(struct mt7921_dev *dev)
        spin_lock_init(&dev->sta_poll_lock);
 
        INIT_WORK(&dev->reset_work, mt7921_mac_reset_work);
+       INIT_WORK(&dev->init_work, mt7921_init_work);
 
        dev->pm.idle_timeout = MT7921_PM_TIMEOUT;
        dev->pm.stats.last_wake_event = jiffies;
@@ -236,7 +276,7 @@ int mt7921_register_device(struct mt7921_dev *dev)
        if (!mt76_is_mmio(&dev->mt76))
                hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;
 
-       ret = mt7921_init_hardware(dev);
+       ret = mt7921_init_wcid(dev);
        if (ret)
                return ret;
 
@@ -264,23 +304,7 @@ int mt7921_register_device(struct mt7921_dev *dev)
        dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;
        dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;
 
-       mt76_set_stream_caps(&dev->mphy, true);
-       mt7921_set_stream_he_caps(&dev->phy);
-
-       ret = mt76_register_device(&dev->mt76, true, mt76_rates,
-                                  ARRAY_SIZE(mt76_rates));
-       if (ret)
-               return ret;
-
-       ret = mt7921_init_debugfs(dev);
-       if (ret)
-               return ret;
-
-       ret = mt76_connac_mcu_set_deep_sleep(&dev->mt76, dev->pm.ds_enable);
-       if (ret)
-               return ret;
-
-       dev->hw_init_done = true;
+       queue_work(system_wq, &dev->init_work);
 
        return 0;
 }
index 1ea7814..7690364 100644 (file)
@@ -205,6 +205,8 @@ struct mt7921_dev {
        struct list_head sta_poll_list;
        spinlock_t sta_poll_lock;
 
+       struct work_struct init_work;
+
        u8 fw_debug;
 
        struct mt76_connac_pm pm;
index a0c82d1..1a01d02 100644 (file)
@@ -105,6 +105,7 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev)
        int i;
        struct mt76_connac_pm *pm = &dev->pm;
 
+       cancel_work_sync(&dev->init_work);
        mt76_unregister_device(&dev->mt76);
        mt76_for_each_q_rx(&dev->mt76, i)
                napi_disable(&dev->mt76.napi[i]);
index 9b2bc0b..af26d59 100644 (file)
@@ -41,6 +41,7 @@ static void mt7921s_unregister_device(struct mt7921_dev *dev)
 {
        struct mt76_connac_pm *pm = &dev->pm;
 
+       cancel_work_sync(&dev->init_work);
        mt76_unregister_device(&dev->mt76);
        cancel_delayed_work_sync(&pm->ps_work);
        cancel_work_sync(&pm->wake_work);
index 0f99d05..b7771e9 100644 (file)
@@ -275,6 +275,7 @@ static void mt7921u_disconnect(struct usb_interface *usb_intf)
 {
        struct mt7921_dev *dev = usb_get_intfdata(usb_intf);
 
+       cancel_work_sync(&dev->init_work);
        if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
                return;