1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2021 MediaTek Inc. */ 3 4 #include <linux/iopoll.h> 5 #include <linux/mmc/sdio_func.h> 6 #include "mt7921.h" 7 #include "../mt76_connac2_mac.h" 8 #include "../sdio.h" 9 #include <linux/mmc/host.h> 10 #include <linux/kallsyms.h> 11 12 static void mt7921s_enable_irq(struct mt76_dev *dev) 13 { 14 struct mt76_sdio *sdio = &dev->sdio; 15 16 sdio_claim_host(sdio->func); 17 sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL); 18 sdio_release_host(sdio->func); 19 } 20 21 static void mt7921s_disable_irq(struct mt76_dev *dev) 22 { 23 struct mt76_sdio *sdio = &dev->sdio; 24 25 sdio_claim_host(sdio->func); 26 sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL); 27 sdio_release_host(sdio->func); 28 } 29 30 static u32 mt7921s_read_whcr(struct mt76_dev *dev) 31 { 32 return sdio_readl(dev->sdio.func, MCR_WHCR, NULL); 33 } 34 35 int mt7921s_wfsys_reset(struct mt792x_dev *dev) 36 { 37 struct mt76_sdio *sdio = &dev->mt76.sdio; 38 u32 val, status; 39 40 if (atomic_read(&dev->mt76.bus_hung)) 41 return 0; 42 43 mt7921s_mcu_drv_pmctrl(dev); 44 45 sdio_claim_host(sdio->func); 46 47 val = sdio_readl(sdio->func, MCR_WHCR, NULL); 48 val &= ~WF_WHOLE_PATH_RSTB; 49 sdio_writel(sdio->func, val, MCR_WHCR, NULL); 50 51 msleep(50); 52 53 val = sdio_readl(sdio->func, MCR_WHCR, NULL); 54 val &= ~WF_SDIO_WF_PATH_RSTB; 55 sdio_writel(sdio->func, val, MCR_WHCR, NULL); 56 57 usleep_range(1000, 2000); 58 59 val = sdio_readl(sdio->func, MCR_WHCR, NULL); 60 val |= WF_WHOLE_PATH_RSTB; 61 sdio_writel(sdio->func, val, MCR_WHCR, NULL); 62 63 readx_poll_timeout(mt7921s_read_whcr, &dev->mt76, status, 64 status & WF_RST_DONE, 50000, 2000000); 65 66 sdio_release_host(sdio->func); 67 68 clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 69 70 /* activate mt7921s again */ 71 mt7921s_mcu_drv_pmctrl(dev); 72 mt76_clear(dev, MT_CONN_STATUS, MT_WIFI_PATCH_DL_STATE); 73 mt7921s_mcu_fw_pmctrl(dev); 74 mt7921s_mcu_drv_pmctrl(dev); 75 76 return 0; 77 } 78 79 int mt7921s_init_reset(struct mt792x_dev *dev) 80 { 81 set_bit(MT76_MCU_RESET, &dev->mphy.state); 82 83 wake_up(&dev->mt76.mcu.wait); 84 skb_queue_purge(&dev->mt76.mcu.res_q); 85 wait_event_timeout(dev->mt76.sdio.wait, 86 mt76s_txqs_empty(&dev->mt76), 5 * HZ); 87 mt76_worker_disable(&dev->mt76.sdio.txrx_worker); 88 89 mt7921s_disable_irq(&dev->mt76); 90 mt7921s_wfsys_reset(dev); 91 92 mt76_worker_enable(&dev->mt76.sdio.txrx_worker); 93 clear_bit(MT76_MCU_RESET, &dev->mphy.state); 94 mt7921s_enable_irq(&dev->mt76); 95 96 return 0; 97 } 98 99 static struct mt76_sdio *msdio; 100 static void mt7921s_card_reset(struct work_struct *work) 101 { 102 struct mmc_host *sdio_host = msdio->func->card->host; 103 104 sdio_claim_host(msdio->func); 105 sdio_release_irq(msdio->func); 106 sdio_release_host(msdio->func); 107 108 mmc_remove_host(sdio_host); 109 msleep(50); 110 mmc_add_host(sdio_host); 111 } 112 113 static DECLARE_WORK(sdio_reset_work, mt7921s_card_reset); 114 static int mt7921s_check_bus(struct mt76_dev *dev) 115 { 116 struct mt76_sdio *sdio = &dev->sdio; 117 int err; 118 119 sdio_claim_host(sdio->func); 120 sdio_readl(dev->sdio.func, MCR_WHCR, &err); 121 sdio_release_host(sdio->func); 122 123 return err; 124 } 125 126 static int mt7921s_host_reset(struct mt792x_dev *dev) 127 { 128 struct mt76_dev *mdev = &dev->mt76; 129 int err = -1; 130 131 if (!atomic_read(&mdev->bus_hung)) 132 err = mt7921s_check_bus(&dev->mt76); 133 134 if (err) { 135 atomic_set(&mdev->bus_hung, true); 136 msdio = &dev->mt76.sdio; 137 dev_err(mdev->dev, "SDIO bus problem detected(%d), resetting card!!\n", err); 138 schedule_work(&sdio_reset_work); 139 return err; 140 } 141 142 atomic_set(&mdev->bus_hung, false); 143 144 return 0; 145 } 146 147 int mt7921s_mac_reset(struct mt792x_dev *dev) 148 { 149 int err; 150 151 mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); 152 153 mt7921s_host_reset(dev); 154 if (atomic_read(&dev->mt76.bus_hung)) 155 return 0; 156 157 mt76_txq_schedule_all(&dev->mphy); 158 mt76_worker_disable(&dev->mt76.tx_worker); 159 set_bit(MT76_MCU_RESET, &dev->mphy.state); 160 wake_up(&dev->mt76.mcu.wait); 161 skb_queue_purge(&dev->mt76.mcu.res_q); 162 wait_event_timeout(dev->mt76.sdio.wait, 163 mt76s_txqs_empty(&dev->mt76), 5 * HZ); 164 mt76_worker_disable(&dev->mt76.sdio.txrx_worker); 165 mt76_worker_disable(&dev->mt76.sdio.status_worker); 166 mt76_worker_disable(&dev->mt76.sdio.net_worker); 167 mt76_worker_disable(&dev->mt76.sdio.stat_worker); 168 169 mt7921s_disable_irq(&dev->mt76); 170 mt7921s_wfsys_reset(dev); 171 172 mt76_worker_enable(&dev->mt76.sdio.txrx_worker); 173 mt76_worker_enable(&dev->mt76.sdio.status_worker); 174 mt76_worker_enable(&dev->mt76.sdio.net_worker); 175 mt76_worker_enable(&dev->mt76.sdio.stat_worker); 176 177 dev->fw_assert = false; 178 clear_bit(MT76_MCU_RESET, &dev->mphy.state); 179 mt7921s_enable_irq(&dev->mt76); 180 181 err = mt7921_run_firmware(dev); 182 if (err) 183 goto out; 184 185 err = mt7921_mcu_set_eeprom(dev); 186 if (err) 187 goto out; 188 189 err = mt7921_mac_init(dev); 190 if (err) 191 goto out; 192 193 err = __mt7921_start(&dev->phy); 194 out: 195 196 mt76_worker_enable(&dev->mt76.tx_worker); 197 198 return err; 199 } 200