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 "mac.h" 8 #include "../sdio.h" 9 10 static void mt7921s_enable_irq(struct mt76_dev *dev) 11 { 12 struct mt76_sdio *sdio = &dev->sdio; 13 14 sdio_claim_host(sdio->func); 15 sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL); 16 sdio_release_host(sdio->func); 17 } 18 19 static void mt7921s_disable_irq(struct mt76_dev *dev) 20 { 21 struct mt76_sdio *sdio = &dev->sdio; 22 23 sdio_claim_host(sdio->func); 24 sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL); 25 sdio_release_host(sdio->func); 26 } 27 28 static u32 mt7921s_read_whcr(struct mt76_dev *dev) 29 { 30 return sdio_readl(dev->sdio.func, MCR_WHCR, NULL); 31 } 32 33 int mt7921s_wfsys_reset(struct mt7921_dev *dev) 34 { 35 struct mt76_sdio *sdio = &dev->mt76.sdio; 36 u32 val, status; 37 38 mt7921s_mcu_drv_pmctrl(dev); 39 40 sdio_claim_host(sdio->func); 41 42 val = sdio_readl(sdio->func, MCR_WHCR, NULL); 43 val &= ~WF_WHOLE_PATH_RSTB; 44 sdio_writel(sdio->func, val, MCR_WHCR, NULL); 45 46 msleep(50); 47 48 val = sdio_readl(sdio->func, MCR_WHCR, NULL); 49 val &= ~WF_SDIO_WF_PATH_RSTB; 50 sdio_writel(sdio->func, val, MCR_WHCR, NULL); 51 52 usleep_range(1000, 2000); 53 54 val = sdio_readl(sdio->func, MCR_WHCR, NULL); 55 val |= WF_WHOLE_PATH_RSTB; 56 sdio_writel(sdio->func, val, MCR_WHCR, NULL); 57 58 readx_poll_timeout(mt7921s_read_whcr, &dev->mt76, status, 59 status & WF_RST_DONE, 50000, 2000000); 60 61 sdio_release_host(sdio->func); 62 63 clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 64 65 /* activate mt7921s again */ 66 mt7921s_mcu_drv_pmctrl(dev); 67 mt76_clear(dev, MT_CONN_STATUS, MT_WIFI_PATCH_DL_STATE); 68 mt7921s_mcu_fw_pmctrl(dev); 69 mt7921s_mcu_drv_pmctrl(dev); 70 71 return 0; 72 } 73 74 int mt7921s_init_reset(struct mt7921_dev *dev) 75 { 76 set_bit(MT76_MCU_RESET, &dev->mphy.state); 77 78 wake_up(&dev->mt76.mcu.wait); 79 skb_queue_purge(&dev->mt76.mcu.res_q); 80 wait_event_timeout(dev->mt76.sdio.wait, 81 mt76s_txqs_empty(&dev->mt76), 5 * HZ); 82 mt76_worker_disable(&dev->mt76.sdio.txrx_worker); 83 84 mt7921s_disable_irq(&dev->mt76); 85 mt7921s_wfsys_reset(dev); 86 87 mt76_worker_enable(&dev->mt76.sdio.txrx_worker); 88 clear_bit(MT76_MCU_RESET, &dev->mphy.state); 89 mt7921s_enable_irq(&dev->mt76); 90 91 return 0; 92 } 93 94 int mt7921s_mac_reset(struct mt7921_dev *dev) 95 { 96 int err; 97 98 mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); 99 mt76_txq_schedule_all(&dev->mphy); 100 mt76_worker_disable(&dev->mt76.tx_worker); 101 set_bit(MT76_RESET, &dev->mphy.state); 102 set_bit(MT76_MCU_RESET, &dev->mphy.state); 103 wake_up(&dev->mt76.mcu.wait); 104 skb_queue_purge(&dev->mt76.mcu.res_q); 105 wait_event_timeout(dev->mt76.sdio.wait, 106 mt76s_txqs_empty(&dev->mt76), 5 * HZ); 107 mt76_worker_disable(&dev->mt76.sdio.txrx_worker); 108 mt76_worker_disable(&dev->mt76.sdio.status_worker); 109 mt76_worker_disable(&dev->mt76.sdio.net_worker); 110 cancel_work_sync(&dev->mt76.sdio.stat_work); 111 112 mt7921s_disable_irq(&dev->mt76); 113 mt7921s_wfsys_reset(dev); 114 115 mt76_worker_enable(&dev->mt76.sdio.txrx_worker); 116 mt76_worker_enable(&dev->mt76.sdio.status_worker); 117 mt76_worker_enable(&dev->mt76.sdio.net_worker); 118 119 dev->fw_assert = false; 120 clear_bit(MT76_MCU_RESET, &dev->mphy.state); 121 mt7921s_enable_irq(&dev->mt76); 122 123 err = mt7921_run_firmware(dev); 124 if (err) 125 goto out; 126 127 err = mt7921_mcu_set_eeprom(dev); 128 if (err) 129 goto out; 130 131 err = mt7921_mac_init(dev); 132 if (err) 133 goto out; 134 135 err = __mt7921_start(&dev->phy); 136 out: 137 clear_bit(MT76_RESET, &dev->mphy.state); 138 139 mt76_worker_enable(&dev->mt76.tx_worker); 140 141 return err; 142 } 143 144 void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e) 145 { 146 __le32 *txwi = (__le32 *)(e->skb->data + MT_SDIO_HDR_SIZE); 147 unsigned int headroom = MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE; 148 struct ieee80211_sta *sta; 149 struct mt76_wcid *wcid; 150 u16 idx; 151 152 idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX); 153 wcid = rcu_dereference(mdev->wcid[idx]); 154 sta = wcid_to_sta(wcid); 155 156 if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE))) 157 mt7921_tx_check_aggr(sta, txwi); 158 159 skb_pull(e->skb, headroom); 160 mt76_tx_complete_skb(mdev, e->wcid, e->skb); 161 } 162 163 bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update) 164 { 165 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); 166 167 mt7921_mutex_acquire(dev); 168 mt7921_mac_sta_poll(dev); 169 mt7921_mutex_release(dev); 170 171 return false; 172 } 173