1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2021 MediaTek Inc.
6 #include <linux/kernel.h>
7 #include <linux/iopoll.h>
8 #include <linux/module.h>
10 #include <linux/mmc/host.h>
11 #include <linux/mmc/sdio_ids.h>
12 #include <linux/mmc/sdio_func.h>
16 #include "../mt76_connac2_mac.h"
19 static const struct sdio_device_id mt7921s_table
[] = {
20 { SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK
, 0x7901),
21 .driver_data
= (kernel_ulong_t
)MT7921_FIRMWARE_WM
},
22 { } /* Terminating entry */
25 static void mt7921s_txrx_worker(struct mt76_worker
*w
)
27 struct mt76_sdio
*sdio
= container_of(w
, struct mt76_sdio
,
29 struct mt76_dev
*mdev
= container_of(sdio
, struct mt76_dev
, sdio
);
30 struct mt792x_dev
*dev
= container_of(mdev
, struct mt792x_dev
, mt76
);
32 if (!mt76_connac_pm_ref(&dev
->mphy
, &dev
->pm
)) {
33 queue_work(mdev
->wq
, &dev
->pm
.wake_work
);
37 mt76s_txrx_worker(sdio
);
38 mt76_connac_pm_unref(&dev
->mphy
, &dev
->pm
);
41 static void mt7921s_unregister_device(struct mt792x_dev
*dev
)
43 struct mt76_connac_pm
*pm
= &dev
->pm
;
45 cancel_work_sync(&dev
->init_work
);
46 mt76_unregister_device(&dev
->mt76
);
47 cancel_delayed_work_sync(&pm
->ps_work
);
48 cancel_work_sync(&pm
->wake_work
);
50 mt76s_deinit(&dev
->mt76
);
51 mt7921s_wfsys_reset(dev
);
52 skb_queue_purge(&dev
->mt76
.mcu
.res_q
);
54 mt76_free_device(&dev
->mt76
);
57 static int mt7921s_parse_intr(struct mt76_dev
*dev
, struct mt76s_intr
*intr
)
59 struct mt76_sdio
*sdio
= &dev
->sdio
;
60 struct mt7921_sdio_intr
*irq_data
= sdio
->intr_data
;
63 sdio_claim_host(sdio
->func
);
64 err
= sdio_readsb(sdio
->func
, irq_data
, MCR_WHISR
, sizeof(*irq_data
));
65 sdio_release_host(sdio
->func
);
70 if (irq_data
->rx
.num
[0] > 16 ||
71 irq_data
->rx
.num
[1] > 128)
74 intr
->isr
= irq_data
->isr
;
75 intr
->rec_mb
= irq_data
->rec_mb
;
76 intr
->tx
.wtqcr
= irq_data
->tx
.wtqcr
;
77 intr
->rx
.num
= irq_data
->rx
.num
;
78 for (i
= 0; i
< 2 ; i
++) {
80 intr
->rx
.len
[0] = irq_data
->rx
.len0
;
82 intr
->rx
.len
[1] = irq_data
->rx
.len1
;
88 static int mt7921s_probe(struct sdio_func
*func
,
89 const struct sdio_device_id
*id
)
91 static const struct mt76_driver_ops drv_ops
= {
92 .txwi_size
= MT_SDIO_TXD_SIZE
,
93 .drv_flags
= MT_DRV_AMSDU_OFFLOAD
,
94 .survey_flags
= SURVEY_INFO_TIME_TX
|
96 SURVEY_INFO_TIME_BSS_RX
,
97 .tx_prepare_skb
= mt7921_usb_sdio_tx_prepare_skb
,
98 .tx_complete_skb
= mt7921_usb_sdio_tx_complete_skb
,
99 .tx_status_data
= mt7921_usb_sdio_tx_status_data
,
100 .rx_skb
= mt7921_queue_rx_skb
,
101 .rx_check
= mt7921_rx_check
,
102 .sta_add
= mt7921_mac_sta_add
,
103 .sta_event
= mt7921_mac_sta_event
,
104 .sta_remove
= mt7921_mac_sta_remove
,
105 .update_survey
= mt792x_update_channel
,
106 .set_channel
= mt7921_set_channel
,
108 static const struct mt76_bus_ops mt7921s_ops
= {
112 .write_copy
= mt76s_write_copy
,
113 .read_copy
= mt76s_read_copy
,
114 .wr_rp
= mt76s_wr_rp
,
115 .rd_rp
= mt76s_rd_rp
,
116 .type
= MT76_BUS_SDIO
,
118 static const struct mt792x_hif_ops mt7921_sdio_ops
= {
119 .init_reset
= mt7921s_init_reset
,
120 .reset
= mt7921s_mac_reset
,
121 .mcu_init
= mt7921s_mcu_init
,
122 .drv_own
= mt7921s_mcu_drv_pmctrl
,
123 .fw_own
= mt7921s_mcu_fw_pmctrl
,
125 struct ieee80211_ops
*ops
;
126 struct mt792x_dev
*dev
;
127 struct mt76_dev
*mdev
;
131 ops
= mt792x_get_mac80211_ops(&func
->dev
, &mt7921_ops
,
132 (void *)id
->driver_data
, &features
);
136 mdev
= mt76_alloc_device(&func
->dev
, sizeof(*dev
), ops
, &drv_ops
);
140 dev
= container_of(mdev
, struct mt792x_dev
, mt76
);
141 dev
->fw_features
= features
;
142 dev
->hif_ops
= &mt7921_sdio_ops
;
143 sdio_set_drvdata(func
, dev
);
145 ret
= mt76s_init(mdev
, func
, &mt7921s_ops
);
149 ret
= mt76s_hw_init(mdev
, func
, MT76_CONNAC2_SDIO
);
153 mdev
->rev
= (mt76_rr(dev
, MT_HW_CHIPID
) << 16) |
154 (mt76_rr(dev
, MT_HW_REV
) & 0xff);
155 dev_dbg(mdev
->dev
, "ASIC revision: %04x\n", mdev
->rev
);
157 mdev
->sdio
.parse_irq
= mt7921s_parse_intr
;
158 mdev
->sdio
.intr_data
= devm_kmalloc(mdev
->dev
,
159 sizeof(struct mt7921_sdio_intr
),
161 if (!mdev
->sdio
.intr_data
) {
166 ret
= mt76s_alloc_rx_queue(mdev
, MT_RXQ_MAIN
);
170 ret
= mt76s_alloc_rx_queue(mdev
, MT_RXQ_MCU
);
174 ret
= mt76s_alloc_tx(mdev
);
178 ret
= mt76_worker_setup(mt76_hw(dev
), &mdev
->sdio
.txrx_worker
,
179 mt7921s_txrx_worker
, "sdio-txrx");
183 sched_set_fifo_low(mdev
->sdio
.txrx_worker
.task
);
185 ret
= mt7921_register_device(dev
);
192 mt76s_deinit(&dev
->mt76
);
193 mt76_free_device(&dev
->mt76
);
198 static void mt7921s_remove(struct sdio_func
*func
)
200 struct mt792x_dev
*dev
= sdio_get_drvdata(func
);
202 mt7921s_unregister_device(dev
);
205 static int mt7921s_suspend(struct device
*__dev
)
207 struct sdio_func
*func
= dev_to_sdio_func(__dev
);
208 struct mt792x_dev
*dev
= sdio_get_drvdata(func
);
209 struct mt76_connac_pm
*pm
= &dev
->pm
;
210 struct mt76_dev
*mdev
= &dev
->mt76
;
213 pm
->suspended
= true;
214 set_bit(MT76_STATE_SUSPEND
, &mdev
->phy
.state
);
216 flush_work(&dev
->reset_work
);
217 cancel_delayed_work_sync(&pm
->ps_work
);
218 cancel_work_sync(&pm
->wake_work
);
220 mt7921_roc_abort_sync(dev
);
222 err
= mt792x_mcu_drv_pmctrl(dev
);
224 goto restore_suspend
;
226 /* always enable deep sleep during suspend to reduce
229 mt76_connac_mcu_set_deep_sleep(mdev
, true);
231 mt76_txq_schedule_all(&dev
->mphy
);
232 mt76_worker_disable(&mdev
->tx_worker
);
233 mt76_worker_disable(&mdev
->sdio
.status_worker
);
234 mt76_worker_disable(&mdev
->sdio
.stat_worker
);
235 clear_bit(MT76_READING_STATS
, &dev
->mphy
.state
);
236 mt76_tx_status_check(mdev
, true);
238 mt76_worker_schedule(&mdev
->sdio
.txrx_worker
);
239 wait_event_timeout(dev
->mt76
.sdio
.wait
,
240 mt76s_txqs_empty(&dev
->mt76
), 5 * HZ
);
242 /* It is supposed that SDIO bus is idle at the point */
243 err
= mt76_connac_mcu_set_hif_suspend(mdev
, true);
247 mt76_worker_disable(&mdev
->sdio
.txrx_worker
);
248 mt76_worker_disable(&mdev
->sdio
.net_worker
);
250 err
= mt792x_mcu_fw_pmctrl(dev
);
252 goto restore_txrx_worker
;
254 sdio_set_host_pm_flags(func
, MMC_PM_KEEP_POWER
);
259 mt76_worker_enable(&mdev
->sdio
.net_worker
);
260 mt76_worker_enable(&mdev
->sdio
.txrx_worker
);
261 mt76_connac_mcu_set_hif_suspend(mdev
, false);
264 mt76_worker_enable(&mdev
->tx_worker
);
265 mt76_worker_enable(&mdev
->sdio
.status_worker
);
266 mt76_worker_enable(&mdev
->sdio
.stat_worker
);
269 mt76_connac_mcu_set_deep_sleep(mdev
, false);
272 clear_bit(MT76_STATE_SUSPEND
, &mdev
->phy
.state
);
273 pm
->suspended
= false;
276 mt792x_reset(&dev
->mt76
);
281 static int mt7921s_resume(struct device
*__dev
)
283 struct sdio_func
*func
= dev_to_sdio_func(__dev
);
284 struct mt792x_dev
*dev
= sdio_get_drvdata(func
);
285 struct mt76_connac_pm
*pm
= &dev
->pm
;
286 struct mt76_dev
*mdev
= &dev
->mt76
;
289 clear_bit(MT76_STATE_SUSPEND
, &mdev
->phy
.state
);
291 err
= mt792x_mcu_drv_pmctrl(dev
);
295 mt76_worker_enable(&mdev
->tx_worker
);
296 mt76_worker_enable(&mdev
->sdio
.txrx_worker
);
297 mt76_worker_enable(&mdev
->sdio
.status_worker
);
298 mt76_worker_enable(&mdev
->sdio
.net_worker
);
299 mt76_worker_enable(&mdev
->sdio
.stat_worker
);
301 /* restore previous ds setting */
303 mt76_connac_mcu_set_deep_sleep(mdev
, false);
305 err
= mt76_connac_mcu_set_hif_suspend(mdev
, false);
307 pm
->suspended
= false;
310 mt792x_reset(&dev
->mt76
);
315 MODULE_DEVICE_TABLE(sdio
, mt7921s_table
);
316 MODULE_FIRMWARE(MT7921_FIRMWARE_WM
);
317 MODULE_FIRMWARE(MT7921_ROM_PATCH
);
319 static DEFINE_SIMPLE_DEV_PM_OPS(mt7921s_pm_ops
, mt7921s_suspend
, mt7921s_resume
);
321 static struct sdio_driver mt7921s_driver
= {
322 .name
= KBUILD_MODNAME
,
323 .probe
= mt7921s_probe
,
324 .remove
= mt7921s_remove
,
325 .id_table
= mt7921s_table
,
326 .drv
.pm
= pm_sleep_ptr(&mt7921s_pm_ops
),
328 module_sdio_driver(mt7921s_driver
);
329 MODULE_DESCRIPTION("MediaTek MT7921S (SDIO) wireless driver");
330 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
331 MODULE_LICENSE("Dual BSD/GPL");