Search Linux Wireless

[PATCH 3/5] fix dma register and add firmware ready check

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



correct DMA registers and poll for firmware state, to fix "failed to get patch semaphore" timeout

Signed-off-by: tnguy3333 <tnguy3333@xxxxxxxxx>
---
 .../net/wireless/mediatek/mt76/mt7902/mcu.c   | 62 ++++++++++++++++++-
 .../wireless/mediatek/mt76/mt7902/mt7902.h    |  6 +-
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7902/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7902/mcu.c
index dfb1b9ef9..677c2c165 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7902/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7902/mcu.c
@@ -634,11 +634,71 @@ int mt7902_mcu_fw_log_2_host(struct mt792x_dev *dev, u8 ctrl)
 				 &data, sizeof(data), false);
 }
 
+int mt7902_firmware_state(struct mt792x_dev *dev, bool wa)
+{
+	u32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,
+			       wa ? FW_STATE_RDY : FW_STATE_FW_DOWNLOAD);
+
+	if (!mt76_poll_msec(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE,
+			    state, 1000)) {
+		dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+int mt7902_load_firmware(struct mt792x_dev *dev)
+{
+	int ret;
+    
+    /* make sure fw is download state */
+	if (mt7902_firmware_state(dev, false)) {
+		/* restart firmware once */
+		mt76_connac_mcu_restart(&dev->mt76);
+		ret = mt7902_firmware_state(dev, false);
+		if (ret) {
+			dev_err(dev->mt76.dev,
+				"Firmware is not ready for download\n");
+			return ret;
+		}
+	}
+
+	ret = mt76_connac2_load_patch(&dev->mt76, mt792x_patch_name(dev));
+	if (ret)
+		return ret;
+
+	if (mt76_is_sdio(&dev->mt76)) {
+		/* activate again */
+		ret = __mt792x_mcu_fw_pmctrl(dev);
+		if (!ret)
+			ret = __mt792x_mcu_drv_pmctrl(dev);
+	}
+
+	ret = mt76_connac2_load_ram(&dev->mt76, mt792x_ram_name(dev), NULL);
+	if (ret)
+		return ret;
+
+	if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY,
+			    MT_TOP_MISC2_FW_N9_RDY, 1500)) {
+		dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
+
+		return -EIO;
+	}
+
+#ifdef CONFIG_PM
+	dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
+#endif /* CONFIG_PM */
+
+	dev_dbg(dev->mt76.dev, "Firmware init done\n");
+
+	return 0;
+}
+
 int mt7902_run_firmware(struct mt792x_dev *dev)
 {
 	int err;
 
-	err = mt792x_load_firmware(dev);
+	err = mt7902_load_firmware(dev);
 	if (err)
 		return err;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7902/mt7902.h b/drivers/net/wireless/mediatek/mt76/mt7902/mt7902.h
index 03beb683b..debd18034 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7902/mt7902.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7902/mt7902.h
@@ -107,8 +107,8 @@ struct mt7902_sdio_intr {
 enum mt7902_txq_id {
 	MT7902_TXQ_BAND0,
 	MT7902_TXQ_BAND1,
-	MT7902_TXQ_FWDL = 16,
-	MT7902_TXQ_MCU_WM,
+	MT7902_TXQ_MCU_WM = 15,
+	MT7902_TXQ_FWDL,
 };
 
 enum mt7902_rxq_id {
@@ -188,6 +188,8 @@ u32 mt7902_reg_map(struct mt792x_dev *dev, u32 addr);
 int __mt7902_start(struct mt792x_phy *phy);
 int mt7902_register_device(struct mt792x_dev *dev);
 void mt7902_unregister_device(struct mt792x_dev *dev);
+int mt7902_firmware_state(struct mt792x_dev *dev, bool wa);
+int mt7902_load_firmware(struct mt792x_dev *dev);
 int mt7902_run_firmware(struct mt792x_dev *dev);
 int mt7902_set_channel(struct mt76_phy *mphy);
 int mt7902_mcu_set_bss_pm(struct mt792x_dev *dev, struct ieee80211_vif *vif,
-- 
2.39.5





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux