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