Commit c3c25d09 authored by Felix Fietkau's avatar Felix Fietkau

mt76: mt7615: defer mcu initialization via workqueue

Loading the mcu firmware and waiting for it to boot takes a long time,
which adds a significant amount to the system boot time.
Fix this by running the mcu init from a workqueue and waiting for it to
complete before starting the phy or issuing mcu commands via debugfs
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent f0305d18
...@@ -7,6 +7,9 @@ mt7615_radar_pattern_set(void *data, u64 val) ...@@ -7,6 +7,9 @@ mt7615_radar_pattern_set(void *data, u64 val)
{ {
struct mt7615_dev *dev = data; struct mt7615_dev *dev = data;
if (!mt7615_wait_for_mcu_init(dev))
return 0;
return mt7615_mcu_rdd_send_pattern(dev); return mt7615_mcu_rdd_send_pattern(dev);
} }
...@@ -18,6 +21,9 @@ mt7615_scs_set(void *data, u64 val) ...@@ -18,6 +21,9 @@ mt7615_scs_set(void *data, u64 val)
{ {
struct mt7615_dev *dev = data; struct mt7615_dev *dev = data;
if (!mt7615_wait_for_mcu_init(dev))
return 0;
mt7615_mac_set_scs(dev, val); mt7615_mac_set_scs(dev, val);
return 0; return 0;
...@@ -41,6 +47,9 @@ mt7615_dbdc_set(void *data, u64 val) ...@@ -41,6 +47,9 @@ mt7615_dbdc_set(void *data, u64 val)
{ {
struct mt7615_dev *dev = data; struct mt7615_dev *dev = data;
if (!mt7615_wait_for_mcu_init(dev))
return 0;
if (val) if (val)
mt7615_register_ext_phy(dev); mt7615_register_ext_phy(dev);
else else
...@@ -131,6 +140,9 @@ static int mt7615_read_temperature(struct seq_file *s, void *data) ...@@ -131,6 +140,9 @@ static int mt7615_read_temperature(struct seq_file *s, void *data)
struct mt7615_dev *dev = dev_get_drvdata(s->private); struct mt7615_dev *dev = dev_get_drvdata(s->private);
int temp; int temp;
if (!mt7615_wait_for_mcu_init(dev))
return 0;
/* cpu */ /* cpu */
temp = mt7615_mcu_get_temperature(dev, 0); temp = mt7615_mcu_get_temperature(dev, 0);
seq_printf(s, "Temperature: %d\n", temp); seq_printf(s, "Temperature: %d\n", temp);
......
...@@ -104,12 +104,33 @@ static void mt7615_mac_init(struct mt7615_dev *dev) ...@@ -104,12 +104,33 @@ static void mt7615_mac_init(struct mt7615_dev *dev)
mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0, MT_WF_RMAC_MIB_RXTIME_EN); mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0, MT_WF_RMAC_MIB_RXTIME_EN);
} }
bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev)
{
flush_work(&dev->mcu_work);
return test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
}
static void mt7615_init_work(struct work_struct *work)
{
struct mt7615_dev *dev = container_of(work, struct mt7615_dev, mcu_work);
if (mt7615_mcu_init(dev))
return;
mt7615_mcu_set_eeprom(dev);
mt7615_mac_init(dev);
mt7615_phy_init(dev);
mt7615_mcu_del_wtbl_all(dev);
}
static int mt7615_init_hardware(struct mt7615_dev *dev) static int mt7615_init_hardware(struct mt7615_dev *dev)
{ {
int ret, idx; int ret, idx;
mt76_wr(dev, MT_INT_SOURCE_CSR, ~0); mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
INIT_WORK(&dev->mcu_work, mt7615_init_work);
spin_lock_init(&dev->token_lock); spin_lock_init(&dev->token_lock);
idr_init(&dev->token); idr_init(&dev->token);
...@@ -123,15 +144,6 @@ static int mt7615_init_hardware(struct mt7615_dev *dev) ...@@ -123,15 +144,6 @@ static int mt7615_init_hardware(struct mt7615_dev *dev)
set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
ret = mt7615_mcu_init(dev);
if (ret)
return ret;
mt7615_mcu_set_eeprom(dev);
mt7615_mac_init(dev);
mt7615_phy_init(dev);
mt7615_mcu_del_wtbl_all(dev);
/* Beacon and mgmt frames should occupy wcid 0 */ /* Beacon and mgmt frames should occupy wcid 0 */
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1); idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
if (idx) if (idx)
...@@ -392,6 +404,7 @@ int mt7615_register_device(struct mt7615_dev *dev) ...@@ -392,6 +404,7 @@ int mt7615_register_device(struct mt7615_dev *dev)
if (ret) if (ret)
return ret; return ret;
ieee80211_queue_work(mt76_hw(dev), &dev->mcu_work);
mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband); mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);
mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband); mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);
...@@ -401,11 +414,15 @@ int mt7615_register_device(struct mt7615_dev *dev) ...@@ -401,11 +414,15 @@ int mt7615_register_device(struct mt7615_dev *dev)
void mt7615_unregister_device(struct mt7615_dev *dev) void mt7615_unregister_device(struct mt7615_dev *dev)
{ {
struct mt76_txwi_cache *txwi; struct mt76_txwi_cache *txwi;
bool mcu_running;
int id; int id;
mcu_running = mt7615_wait_for_mcu_init(dev);
mt7615_unregister_ext_phy(dev); mt7615_unregister_ext_phy(dev);
mt76_unregister_device(&dev->mt76); mt76_unregister_device(&dev->mt76);
mt7615_mcu_exit(dev); if (mcu_running)
mt7615_mcu_exit(dev);
mt7615_dma_cleanup(dev); mt7615_dma_cleanup(dev);
spin_lock_bh(&dev->token_lock); spin_lock_bh(&dev->token_lock);
......
...@@ -30,6 +30,9 @@ static int mt7615_start(struct ieee80211_hw *hw) ...@@ -30,6 +30,9 @@ static int mt7615_start(struct ieee80211_hw *hw)
struct mt7615_phy *phy = mt7615_hw_phy(hw); struct mt7615_phy *phy = mt7615_hw_phy(hw);
bool running; bool running;
if (!mt7615_wait_for_mcu_init(dev))
return -EIO;
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
running = mt7615_dev_running(dev); running = mt7615_dev_running(dev);
......
...@@ -117,6 +117,8 @@ struct mt7615_dev { ...@@ -117,6 +117,8 @@ struct mt7615_dev {
u16 chainmask; u16 chainmask;
struct work_struct mcu_work;
struct list_head sta_poll_list; struct list_head sta_poll_list;
spinlock_t sta_poll_lock; spinlock_t sta_poll_lock;
...@@ -222,6 +224,7 @@ int mt7615_eeprom_get_power_index(struct mt7615_dev *dev, ...@@ -222,6 +224,7 @@ int mt7615_eeprom_get_power_index(struct mt7615_dev *dev,
int mt7615_dma_init(struct mt7615_dev *dev); int mt7615_dma_init(struct mt7615_dev *dev);
void mt7615_dma_cleanup(struct mt7615_dev *dev); void mt7615_dma_cleanup(struct mt7615_dev *dev);
int mt7615_mcu_init(struct mt7615_dev *dev); int mt7615_mcu_init(struct mt7615_dev *dev);
bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev);
int mt7615_mcu_set_dev_info(struct mt7615_dev *dev, int mt7615_mcu_set_dev_info(struct mt7615_dev *dev,
struct ieee80211_vif *vif, bool enable); struct ieee80211_vif *vif, bool enable);
int mt7615_mcu_set_bss_info(struct mt7615_dev *dev, struct ieee80211_vif *vif, int mt7615_mcu_set_bss_info(struct mt7615_dev *dev, struct ieee80211_vif *vif,
......
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