Skip to content

Commit

Permalink
mt76: mt7921: move mt7921_init_hw in a dedicated work
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lorenzo Bianconi authored and Felix Fietkau committed Mar 16, 2022
1 parent 0d2afe0 commit 1c71e03
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 19 deletions.
62 changes: 43 additions & 19 deletions drivers/net/wireless/mediatek/mt76/mt7921/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ static int __mt7921_init_hardware(struct mt7921_dev *dev)

static int mt7921_init_hardware(struct mt7921_dev *dev)
{
int ret, idx, i;
int ret, i;

set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);

Expand All @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/mediatek/mt76/mt7921/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/mediatek/mt76/mt7921/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 1c71e03

Please sign in to comment.