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