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
mt7921s_enable_irq(struct mt76_dev * dev)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
mt7921s_disable_irq(struct mt76_dev * dev)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
mt7921s_read_whcr(struct mt76_dev * dev)28 static u32 mt7921s_read_whcr(struct mt76_dev *dev)
29 {
30 return sdio_readl(dev->sdio.func, MCR_WHCR, NULL);
31 }
32
mt7921s_wfsys_reset(struct mt7921_dev * dev)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
mt7921s_init_reset(struct mt7921_dev * dev)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
mt7921s_mac_reset(struct mt7921_dev * dev)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
mt7921s_write_txwi(struct mt7921_dev * dev,struct mt76_wcid * wcid,enum mt76_txq_id qid,struct ieee80211_sta * sta,struct ieee80211_key_conf * key,int pid,struct sk_buff * skb)143 mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid,
144 enum mt76_txq_id qid, struct ieee80211_sta *sta,
145 struct ieee80211_key_conf *key, int pid,
146 struct sk_buff *skb)
147 {
148 __le32 *txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
149
150 memset(txwi, 0, MT_SDIO_TXD_SIZE);
151 mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false);
152 skb_push(skb, MT_SDIO_TXD_SIZE);
153 }
154
mt7921s_tx_prepare_skb(struct mt76_dev * mdev,void * txwi_ptr,enum mt76_txq_id qid,struct mt76_wcid * wcid,struct ieee80211_sta * sta,struct mt76_tx_info * tx_info)155 int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
156 enum mt76_txq_id qid, struct mt76_wcid *wcid,
157 struct ieee80211_sta *sta,
158 struct mt76_tx_info *tx_info)
159 {
160 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
161 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
162 struct ieee80211_key_conf *key = info->control.hw_key;
163 struct sk_buff *skb = tx_info->skb;
164 int err, pad, pktid;
165
166 if (unlikely(tx_info->skb->len <= ETH_HLEN))
167 return -EINVAL;
168
169 if (!wcid)
170 wcid = &dev->mt76.global_wcid;
171
172 if (sta) {
173 struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv;
174
175 if (time_after(jiffies, msta->last_txs + HZ / 4)) {
176 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
177 msta->last_txs = jiffies;
178 }
179 }
180
181 pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
182 mt7921s_write_txwi(dev, wcid, qid, sta, key, pktid, skb);
183
184 mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA);
185 pad = round_up(skb->len, 4) - skb->len;
186
187 err = mt76_skb_adjust_pad(skb, pad);
188 if (err)
189 /* Release pktid in case of error. */
190 idr_remove(&wcid->pktid, pktid);
191
192 return err;
193 }
194
mt7921s_tx_complete_skb(struct mt76_dev * mdev,struct mt76_queue_entry * e)195 void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
196 {
197 __le32 *txwi = (__le32 *)(e->skb->data + MT_SDIO_HDR_SIZE);
198 unsigned int headroom = MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;
199 struct ieee80211_sta *sta;
200 struct mt76_wcid *wcid;
201 u16 idx;
202
203 idx = FIELD_GET(MT_TXD1_WLAN_IDX, le32_to_cpu(txwi[1]));
204 wcid = rcu_dereference(mdev->wcid[idx]);
205 sta = wcid_to_sta(wcid);
206
207 if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE)))
208 mt7921_tx_check_aggr(sta, txwi);
209
210 skb_pull(e->skb, headroom);
211 mt76_tx_complete_skb(mdev, e->wcid, e->skb);
212 }
213
mt7921s_tx_status_data(struct mt76_dev * mdev,u8 * update)214 bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update)
215 {
216 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
217
218 mt7921_mutex_acquire(dev);
219 mt7921_mac_sta_poll(dev);
220 mt7921_mutex_release(dev);
221
222 return 0;
223 }
224