xref: /linux/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c (revision 6015fb905d89063231ed33bc15be19ef0fc339b8)
1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2021 MediaTek Inc.
3  *
4  */
5 
6 #include <linux/kernel.h>
7 #include <linux/iopoll.h>
8 #include <linux/module.h>
9 
10 #include <linux/mmc/host.h>
11 #include <linux/mmc/sdio_ids.h>
12 #include <linux/mmc/sdio_func.h>
13 
14 #include "mt7921.h"
15 #include "../sdio.h"
16 #include "mac.h"
17 #include "mcu.h"
18 
19 static const struct sdio_device_id mt7921s_table[] = {
20 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, 0x7901) },
21 	{ }	/* Terminating entry */
22 };
23 
24 static void mt7921s_txrx_worker(struct mt76_worker *w)
25 {
26 	struct mt76_sdio *sdio = container_of(w, struct mt76_sdio,
27 					      txrx_worker);
28 	struct mt76_dev *mdev = container_of(sdio, struct mt76_dev, sdio);
29 	struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
30 
31 	if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
32 		queue_work(mdev->wq, &dev->pm.wake_work);
33 		return;
34 	}
35 
36 	mt76s_txrx_worker(sdio);
37 	mt76_connac_pm_unref(&dev->mphy, &dev->pm);
38 }
39 
40 static void mt7921s_unregister_device(struct mt7921_dev *dev)
41 {
42 	struct mt76_connac_pm *pm = &dev->pm;
43 
44 	mt76_unregister_device(&dev->mt76);
45 	cancel_delayed_work_sync(&pm->ps_work);
46 	cancel_work_sync(&pm->wake_work);
47 
48 	mt76s_deinit(&dev->mt76);
49 	mt7921s_wfsys_reset(dev);
50 	mt7921_mcu_exit(dev);
51 
52 	mt76_free_device(&dev->mt76);
53 }
54 
55 static int mt7921s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr)
56 {
57 	struct mt76_sdio *sdio = &dev->sdio;
58 	struct mt7921_sdio_intr *irq_data = sdio->intr_data;
59 	int i, err;
60 
61 	sdio_claim_host(sdio->func);
62 	err = sdio_readsb(sdio->func, irq_data, MCR_WHISR, sizeof(*irq_data));
63 	sdio_release_host(sdio->func);
64 
65 	if (err < 0)
66 		return err;
67 
68 	if (irq_data->rx.num[0] > 16 ||
69 	    irq_data->rx.num[1] > 128)
70 		return -EINVAL;
71 
72 	intr->isr = irq_data->isr;
73 	intr->rec_mb = irq_data->rec_mb;
74 	intr->tx.wtqcr = irq_data->tx.wtqcr;
75 	intr->rx.num = irq_data->rx.num;
76 	for (i = 0; i < 2 ; i++) {
77 		if (!i)
78 			intr->rx.len[0] = irq_data->rx.len0;
79 		else
80 			intr->rx.len[1] = irq_data->rx.len1;
81 	}
82 
83 	return 0;
84 }
85 
86 static int mt7921s_probe(struct sdio_func *func,
87 			 const struct sdio_device_id *id)
88 {
89 	static const struct mt76_driver_ops drv_ops = {
90 		.txwi_size = MT_SDIO_TXD_SIZE,
91 		.survey_flags = SURVEY_INFO_TIME_TX |
92 				SURVEY_INFO_TIME_RX |
93 				SURVEY_INFO_TIME_BSS_RX,
94 		.tx_prepare_skb = mt7921s_tx_prepare_skb,
95 		.tx_complete_skb = mt7921s_tx_complete_skb,
96 		.tx_status_data = mt7921s_tx_status_data,
97 		.rx_skb = mt7921_queue_rx_skb,
98 		.sta_ps = mt7921_sta_ps,
99 		.sta_add = mt7921_mac_sta_add,
100 		.sta_assoc = mt7921_mac_sta_assoc,
101 		.sta_remove = mt7921_mac_sta_remove,
102 		.update_survey = mt7921_update_channel,
103 	};
104 	static const struct mt76_bus_ops mt7921s_ops = {
105 		.rr = mt76s_rr,
106 		.rmw = mt76s_rmw,
107 		.wr = mt76s_wr,
108 		.write_copy = mt76s_write_copy,
109 		.read_copy = mt76s_read_copy,
110 		.wr_rp = mt76s_wr_rp,
111 		.rd_rp = mt76s_rd_rp,
112 		.type = MT76_BUS_SDIO,
113 	};
114 	static const struct mt7921_hif_ops mt7921_sdio_ops = {
115 		.init_reset = mt7921s_init_reset,
116 		.reset = mt7921s_mac_reset,
117 		.mcu_init = mt7921s_mcu_init,
118 		.drv_own = mt7921s_mcu_drv_pmctrl,
119 		.fw_own = mt7921s_mcu_fw_pmctrl,
120 	};
121 
122 	struct mt7921_dev *dev;
123 	struct mt76_dev *mdev;
124 	int ret;
125 
126 	mdev = mt76_alloc_device(&func->dev, sizeof(*dev), &mt7921_ops,
127 				 &drv_ops);
128 	if (!mdev)
129 		return -ENOMEM;
130 
131 	dev = container_of(mdev, struct mt7921_dev, mt76);
132 	dev->hif_ops = &mt7921_sdio_ops;
133 
134 	sdio_set_drvdata(func, dev);
135 
136 	ret = mt76s_init(mdev, func, &mt7921s_ops);
137 	if (ret < 0)
138 		goto error;
139 
140 	ret = mt76s_hw_init(mdev, func, MT76_CONNAC2_SDIO);
141 	if (ret)
142 		goto error;
143 
144 	mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
145 		    (mt76_rr(dev, MT_HW_REV) & 0xff);
146 	dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
147 
148 	mdev->sdio.parse_irq = mt7921s_parse_intr;
149 	mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
150 					    sizeof(struct mt7921_sdio_intr),
151 					    GFP_KERNEL);
152 	if (!mdev->sdio.intr_data) {
153 		ret = -ENOMEM;
154 		goto error;
155 	}
156 
157 	ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MAIN);
158 	if (ret)
159 		goto error;
160 
161 	ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MCU);
162 	if (ret)
163 		goto error;
164 
165 	ret = mt76s_alloc_tx(mdev);
166 	if (ret)
167 		goto error;
168 
169 	ret = mt76_worker_setup(mt76_hw(dev), &mdev->sdio.txrx_worker,
170 				mt7921s_txrx_worker, "sdio-txrx");
171 	if (ret)
172 		goto error;
173 
174 	sched_set_fifo_low(mdev->sdio.txrx_worker.task);
175 
176 	ret = mt7921_register_device(dev);
177 	if (ret)
178 		goto error;
179 
180 	return 0;
181 
182 error:
183 	mt76s_deinit(&dev->mt76);
184 	mt76_free_device(&dev->mt76);
185 
186 	return ret;
187 }
188 
189 static void mt7921s_remove(struct sdio_func *func)
190 {
191 	struct mt7921_dev *dev = sdio_get_drvdata(func);
192 
193 	mt7921s_unregister_device(dev);
194 }
195 
196 #ifdef CONFIG_PM
197 static int mt7921s_suspend(struct device *__dev)
198 {
199 	struct sdio_func *func = dev_to_sdio_func(__dev);
200 	struct mt7921_dev *dev = sdio_get_drvdata(func);
201 	struct mt76_connac_pm *pm = &dev->pm;
202 	struct mt76_dev *mdev = &dev->mt76;
203 	int err;
204 
205 	pm->suspended = true;
206 	set_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
207 
208 	cancel_delayed_work_sync(&pm->ps_work);
209 	cancel_work_sync(&pm->wake_work);
210 
211 	err = mt7921_mcu_drv_pmctrl(dev);
212 	if (err < 0)
213 		goto restore_suspend;
214 
215 	/* always enable deep sleep during suspend to reduce
216 	 * power consumption
217 	 */
218 	mt76_connac_mcu_set_deep_sleep(mdev, true);
219 
220 	mt76_txq_schedule_all(&dev->mphy);
221 	mt76_worker_disable(&mdev->tx_worker);
222 	mt76_worker_disable(&mdev->sdio.status_worker);
223 	cancel_work_sync(&mdev->sdio.stat_work);
224 	clear_bit(MT76_READING_STATS, &dev->mphy.state);
225 	mt76_tx_status_check(mdev, true);
226 
227 	mt76_worker_schedule(&mdev->sdio.txrx_worker);
228 	wait_event_timeout(dev->mt76.sdio.wait,
229 			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);
230 
231 	/* It is supposed that SDIO bus is idle at the point */
232 	err = mt76_connac_mcu_set_hif_suspend(mdev, true);
233 	if (err)
234 		goto restore_worker;
235 
236 	mt76_worker_disable(&mdev->sdio.txrx_worker);
237 	mt76_worker_disable(&mdev->sdio.net_worker);
238 
239 	err = mt7921_mcu_fw_pmctrl(dev);
240 	if (err)
241 		goto restore_txrx_worker;
242 
243 	sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
244 
245 	return 0;
246 
247 restore_txrx_worker:
248 	mt76_worker_enable(&mdev->sdio.net_worker);
249 	mt76_worker_enable(&mdev->sdio.txrx_worker);
250 	mt76_connac_mcu_set_hif_suspend(mdev, false);
251 
252 restore_worker:
253 	mt76_worker_enable(&mdev->tx_worker);
254 	mt76_worker_enable(&mdev->sdio.status_worker);
255 
256 	if (!pm->ds_enable)
257 		mt76_connac_mcu_set_deep_sleep(mdev, false);
258 
259 restore_suspend:
260 	clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
261 	pm->suspended = false;
262 
263 	return err;
264 }
265 
266 static int mt7921s_resume(struct device *__dev)
267 {
268 	struct sdio_func *func = dev_to_sdio_func(__dev);
269 	struct mt7921_dev *dev = sdio_get_drvdata(func);
270 	struct mt76_connac_pm *pm = &dev->pm;
271 	struct mt76_dev *mdev = &dev->mt76;
272 	int err;
273 
274 	clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
275 
276 	err = mt7921_mcu_drv_pmctrl(dev);
277 	if (err < 0)
278 		return err;
279 
280 	mt76_worker_enable(&mdev->tx_worker);
281 	mt76_worker_enable(&mdev->sdio.txrx_worker);
282 	mt76_worker_enable(&mdev->sdio.status_worker);
283 	mt76_worker_enable(&mdev->sdio.net_worker);
284 
285 	/* restore previous ds setting */
286 	if (!pm->ds_enable)
287 		mt76_connac_mcu_set_deep_sleep(mdev, false);
288 
289 	err = mt76_connac_mcu_set_hif_suspend(mdev, false);
290 	if (err)
291 		return err;
292 
293 	pm->suspended = false;
294 
295 	return err;
296 }
297 
298 static const struct dev_pm_ops mt7921s_pm_ops = {
299 	.suspend = mt7921s_suspend,
300 	.resume = mt7921s_resume,
301 };
302 #endif
303 
304 MODULE_DEVICE_TABLE(sdio, mt7921s_table);
305 MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
306 MODULE_FIRMWARE(MT7921_ROM_PATCH);
307 
308 static struct sdio_driver mt7921s_driver = {
309 	.name		= KBUILD_MODNAME,
310 	.probe		= mt7921s_probe,
311 	.remove		= mt7921s_remove,
312 	.id_table	= mt7921s_table,
313 #ifdef CONFIG_PM
314 	.drv = {
315 		.pm = &mt7921s_pm_ops,
316 	}
317 #endif
318 };
319 module_sdio_driver(mt7921s_driver);
320 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
321 MODULE_LICENSE("Dual BSD/GPL");
322