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 /* activate mt7921s again */ 64 mt7921s_mcu_fw_pmctrl(dev); 65 mt7921s_mcu_drv_pmctrl(dev); 66 67 return 0; 68 } 69 70 int mt7921s_init_reset(struct mt7921_dev *dev) 71 { 72 set_bit(MT76_MCU_RESET, &dev->mphy.state); 73 74 wake_up(&dev->mt76.mcu.wait); 75 skb_queue_purge(&dev->mt76.mcu.res_q); 76 wait_event_timeout(dev->mt76.sdio.wait, 77 mt76s_txqs_empty(&dev->mt76), 5 * HZ); 78 mt76_worker_disable(&dev->mt76.sdio.txrx_worker); 79 80 mt7921s_disable_irq(&dev->mt76); 81 mt7921s_wfsys_reset(dev); 82 83 mt76_worker_enable(&dev->mt76.sdio.txrx_worker); 84 clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 85 clear_bit(MT76_MCU_RESET, &dev->mphy.state); 86 mt7921s_enable_irq(&dev->mt76); 87 88 return 0; 89 } 90 91 int mt7921s_mac_reset(struct mt7921_dev *dev) 92 { 93 int err; 94 95 mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); 96 mt76_txq_schedule_all(&dev->mphy); 97 mt76_worker_disable(&dev->mt76.tx_worker); 98 set_bit(MT76_RESET, &dev->mphy.state); 99 set_bit(MT76_MCU_RESET, &dev->mphy.state); 100 wake_up(&dev->mt76.mcu.wait); 101 skb_queue_purge(&dev->mt76.mcu.res_q); 102 wait_event_timeout(dev->mt76.sdio.wait, 103 mt76s_txqs_empty(&dev->mt76), 5 * HZ); 104 mt76_worker_disable(&dev->mt76.sdio.txrx_worker); 105 mt76_worker_disable(&dev->mt76.sdio.status_worker); 106 mt76_worker_disable(&dev->mt76.sdio.net_worker); 107 cancel_work_sync(&dev->mt76.sdio.stat_work); 108 109 mt7921s_disable_irq(&dev->mt76); 110 mt7921s_wfsys_reset(dev); 111 112 mt76_worker_enable(&dev->mt76.sdio.txrx_worker); 113 mt76_worker_enable(&dev->mt76.sdio.status_worker); 114 mt76_worker_enable(&dev->mt76.sdio.net_worker); 115 116 dev->fw_assert = false; 117 clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 118 clear_bit(MT76_MCU_RESET, &dev->mphy.state); 119 mt7921s_enable_irq(&dev->mt76); 120 121 err = mt7921_run_firmware(dev); 122 if (err) 123 goto out; 124 125 err = mt7921_mcu_set_eeprom(dev); 126 if (err) 127 goto out; 128 129 err = mt7921_mac_init(dev); 130 if (err) 131 goto out; 132 133 err = __mt7921_start(&dev->phy); 134 out: 135 clear_bit(MT76_RESET, &dev->mphy.state); 136 137 mt76_worker_enable(&dev->mt76.tx_worker); 138 139 return err; 140 } 141 142 static void 143 mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid, 144 enum mt76_txq_id qid, struct ieee80211_sta *sta, 145 struct sk_buff *skb) 146 { 147 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 148 struct ieee80211_key_conf *key = info->control.hw_key; 149 __le32 *txwi; 150 int pid; 151 152 pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb); 153 txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE); 154 memset(txwi, 0, MT_SDIO_TXD_SIZE); 155 mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false); 156 skb_push(skb, MT_SDIO_TXD_SIZE); 157 } 158 159 int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, 160 enum mt76_txq_id qid, struct mt76_wcid *wcid, 161 struct ieee80211_sta *sta, 162 struct mt76_tx_info *tx_info) 163 { 164 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); 165 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); 166 struct sk_buff *skb = tx_info->skb; 167 int pad; 168 169 if (unlikely(tx_info->skb->len <= ETH_HLEN)) 170 return -EINVAL; 171 172 if (!wcid) 173 wcid = &dev->mt76.global_wcid; 174 175 if (sta) { 176 struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; 177 178 if (time_after(jiffies, msta->last_txs + HZ / 4)) { 179 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 180 msta->last_txs = jiffies; 181 } 182 } 183 184 mt7921s_write_txwi(dev, wcid, qid, sta, skb); 185 186 mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA); 187 pad = round_up(skb->len, 4) - skb->len; 188 189 return mt76_skb_adjust_pad(skb, pad); 190 } 191 192 void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e) 193 { 194 __le32 *txwi = (__le32 *)(e->skb->data + MT_SDIO_HDR_SIZE); 195 unsigned int headroom = MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE; 196 struct ieee80211_sta *sta; 197 struct mt76_wcid *wcid; 198 u16 idx; 199 200 idx = FIELD_GET(MT_TXD1_WLAN_IDX, le32_to_cpu(txwi[1])); 201 wcid = rcu_dereference(mdev->wcid[idx]); 202 sta = wcid_to_sta(wcid); 203 204 if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE))) 205 mt7921_tx_check_aggr(sta, txwi); 206 207 skb_pull(e->skb, headroom); 208 mt76_tx_complete_skb(mdev, e->wcid, e->skb); 209 } 210 211 bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update) 212 { 213 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); 214 215 mt7921_mutex_acquire(dev); 216 mt7921_mac_sta_poll(dev); 217 mt7921_mutex_release(dev); 218 219 return 0; 220 } 221