From: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> Introduce mt7921_wpdma_reset routine to reset wpdma during chip reset or driver_own request. Signed-off-by: Sean Wang <sean.wang@xxxxxxxxxxxx> Signed-off-by: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> --- .../net/wireless/mediatek/mt76/mt7921/dma.c | 44 ++++++++++++++++++- .../net/wireless/mediatek/mt76/mt7921/mac.c | 29 ++---------- .../wireless/mediatek/mt76/mt7921/mt7921.h | 2 +- 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c index f8815aa247eb..4aad355f8394 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c @@ -206,7 +206,7 @@ static int mt7921_dmashdl_disabled(struct mt7921_dev *dev) return 0; } -int mt7921_dma_reset(struct mt7921_dev *dev, bool force) +static int mt7921_dma_reset(struct mt7921_dev *dev, bool force) { int i; @@ -277,6 +277,48 @@ int mt7921_dma_reset(struct mt7921_dev *dev, bool force) return 0; } +int mt7921_wfsys_reset(struct mt7921_dev *dev) +{ + mt76_set(dev, 0x70002600, BIT(0)); + msleep(200); + mt76_clear(dev, 0x70002600, BIT(0)); + + if (!__mt76_poll_msec(&dev->mt76, MT_WFSYS_SW_RST_B, + WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500)) + return -ETIMEDOUT; + + return 0; +} + +int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force) +{ + int i, err; + + /* clean up hw queues */ + for (i = 0; i < ARRAY_SIZE(dev->mt76.phy.q_tx); i++) + mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true); + + for (i = 0; i < ARRAY_SIZE(dev->mt76.q_mcu); i++) + mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true); + + mt76_for_each_q_rx(&dev->mt76, i) + mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]); + + if (force) { + err = mt7921_wfsys_reset(dev); + if (err) + return err; + } + err = mt7921_dma_reset(dev, force); + if (err) + return err; + + mt76_for_each_q_rx(&dev->mt76, i) + mt76_queue_rx_reset(dev, i); + + return 0; +} + int mt7921_dma_init(struct mt7921_dev *dev) { /* Increase buffer size to receive large VHT/HE MPDUs */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 4e319f1521a6..6e89cd41641e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -1210,16 +1210,6 @@ void mt7921_update_channel(struct mt76_dev *mdev) mt76_connac_power_save_sched(&dev->mphy, &dev->pm); } -int mt7921_wfsys_reset(struct mt7921_dev *dev) -{ - mt76_set(dev, 0x70002600, BIT(0)); - msleep(200); - mt76_clear(dev, 0x70002600, BIT(0)); - - return __mt76_poll_msec(&dev->mt76, MT_WFSYS_SW_RST_B, - WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500); -} - void mt7921_tx_token_put(struct mt7921_dev *dev) { struct mt76_txwi_cache *txwi; @@ -1279,21 +1269,11 @@ mt7921_mac_reset(struct mt7921_dev *dev) mt7921_tx_token_put(dev); idr_init(&dev->token); - /* clean up hw queues */ - for (i = 0; i < ARRAY_SIZE(dev->mt76.phy.q_tx); i++) - mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true); - - for (i = 0; i < ARRAY_SIZE(dev->mt76.q_mcu); i++) - mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true); - - mt76_for_each_q_rx(&dev->mt76, i) - mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]); - - mt7921_wfsys_reset(dev); - mt7921_dma_reset(dev, true); + err = mt7921_wpdma_reset(dev, true); + if (err) + return err; mt76_for_each_q_rx(&dev->mt76, i) { - mt76_queue_rx_reset(dev, i); napi_enable(&dev->mt76.napi[i]); napi_schedule(&dev->mt76.napi[i]); } @@ -1306,9 +1286,6 @@ mt7921_mac_reset(struct mt7921_dev *dev) mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); - mt7921_irq_enable(dev, - MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL | - MT_INT_MCU_CMD); err = mt7921_run_firmware(dev); if (err) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 9b476641616d..06a85d2d1c6f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -253,7 +253,7 @@ int mt7921_eeprom_get_target_power(struct mt7921_dev *dev, u8 chain_idx); void mt7921_eeprom_init_sku(struct mt7921_dev *dev); int mt7921_dma_init(struct mt7921_dev *dev); -int mt7921_dma_reset(struct mt7921_dev *dev, bool force); +int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force); void mt7921_dma_cleanup(struct mt7921_dev *dev); int mt7921_run_firmware(struct mt7921_dev *dev); int mt7921_mcu_init(struct mt7921_dev *dev); -- 2.25.1