Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7925/pci.c
48525 views
1
// SPDX-License-Identifier: ISC
2
/* Copyright (C) 2023 MediaTek Inc. */
3
4
#include <linux/kernel.h>
5
#include <linux/module.h>
6
#include <linux/pci.h>
7
8
#include "mt7925.h"
9
#include "mac.h"
10
#include "mcu.h"
11
#include "../dma.h"
12
13
static const struct pci_device_id mt7925_pci_device_table[] = {
14
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7925),
15
.driver_data = (kernel_ulong_t)MT7925_FIRMWARE_WM },
16
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0717),
17
.driver_data = (kernel_ulong_t)MT7925_FIRMWARE_WM },
18
{ },
19
};
20
21
static bool mt7925_disable_aspm;
22
module_param_named(disable_aspm, mt7925_disable_aspm, bool, 0644);
23
MODULE_PARM_DESC(disable_aspm, "disable PCI ASPM support");
24
25
static int mt7925e_init_reset(struct mt792x_dev *dev)
26
{
27
return mt792x_wpdma_reset(dev, true);
28
}
29
30
static void mt7925e_unregister_device(struct mt792x_dev *dev)
31
{
32
int i;
33
struct mt76_connac_pm *pm = &dev->pm;
34
struct ieee80211_hw *hw = mt76_hw(dev);
35
36
if (dev->phy.chip_cap & MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN)
37
wiphy_rfkill_stop_polling(hw->wiphy);
38
39
cancel_work_sync(&dev->init_work);
40
mt76_unregister_device(&dev->mt76);
41
mt76_for_each_q_rx(&dev->mt76, i)
42
napi_disable(&dev->mt76.napi[i]);
43
cancel_delayed_work_sync(&pm->ps_work);
44
cancel_work_sync(&pm->wake_work);
45
cancel_work_sync(&dev->reset_work);
46
47
mt7925_tx_token_put(dev);
48
__mt792x_mcu_drv_pmctrl(dev);
49
mt792x_dma_cleanup(dev);
50
mt792x_wfsys_reset(dev);
51
skb_queue_purge(&dev->mt76.mcu.res_q);
52
53
tasklet_disable(&dev->mt76.irq_tasklet);
54
}
55
56
static void mt7925_reg_remap_restore(struct mt792x_dev *dev)
57
{
58
/* remap to ori status */
59
if (unlikely(dev->backup_l1)) {
60
dev->bus_ops->wr(&dev->mt76, MT_HIF_REMAP_L1, dev->backup_l1);
61
dev->backup_l1 = 0;
62
}
63
64
if (dev->backup_l2) {
65
dev->bus_ops->wr(&dev->mt76, MT_HIF_REMAP_L2, dev->backup_l2);
66
dev->backup_l2 = 0;
67
}
68
}
69
70
static u32 mt7925_reg_map_l1(struct mt792x_dev *dev, u32 addr)
71
{
72
u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr);
73
u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr);
74
75
dev->backup_l1 = dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);
76
77
dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L1,
78
MT_HIF_REMAP_L1_MASK,
79
FIELD_PREP(MT_HIF_REMAP_L1_MASK, base));
80
81
/* use read to push write */
82
dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);
83
84
return MT_HIF_REMAP_BASE_L1 + offset;
85
}
86
87
static u32 mt7925_reg_map_l2(struct mt792x_dev *dev, u32 addr)
88
{
89
u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, MT_HIF_REMAP_BASE_L2);
90
91
dev->backup_l2 = dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);
92
93
dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L1,
94
MT_HIF_REMAP_L1_MASK,
95
FIELD_PREP(MT_HIF_REMAP_L1_MASK, base));
96
97
dev->bus_ops->wr(&dev->mt76, MT_HIF_REMAP_L2, addr);
98
/* use read to push write */
99
dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);
100
101
return MT_HIF_REMAP_BASE_L1;
102
}
103
104
static u32 __mt7925_reg_addr(struct mt792x_dev *dev, u32 addr)
105
{
106
static const struct mt76_connac_reg_map fixed_map[] = {
107
{ 0x830c0000, 0x000000, 0x0001000 }, /* WF_MCU_BUS_CR_REMAP */
108
{ 0x54000000, 0x002000, 0x0001000 }, /* WFDMA PCIE0 MCU DMA0 */
109
{ 0x55000000, 0x003000, 0x0001000 }, /* WFDMA PCIE0 MCU DMA1 */
110
{ 0x56000000, 0x004000, 0x0001000 }, /* WFDMA reserved */
111
{ 0x57000000, 0x005000, 0x0001000 }, /* WFDMA MCU wrap CR */
112
{ 0x58000000, 0x006000, 0x0001000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */
113
{ 0x59000000, 0x007000, 0x0001000 }, /* WFDMA PCIE1 MCU DMA1 */
114
{ 0x820c0000, 0x008000, 0x0004000 }, /* WF_UMAC_TOP (PLE) */
115
{ 0x820c8000, 0x00c000, 0x0002000 }, /* WF_UMAC_TOP (PSE) */
116
{ 0x820cc000, 0x00e000, 0x0002000 }, /* WF_UMAC_TOP (PP) */
117
{ 0x74030000, 0x010000, 0x0001000 }, /* PCIe MAC */
118
{ 0x820e0000, 0x020000, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */
119
{ 0x820e1000, 0x020400, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */
120
{ 0x820e2000, 0x020800, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */
121
{ 0x820e3000, 0x020c00, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */
122
{ 0x820e4000, 0x021000, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */
123
{ 0x820e5000, 0x021400, 0x0000800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */
124
{ 0x820ce000, 0x021c00, 0x0000200 }, /* WF_LMAC_TOP (WF_SEC) */
125
{ 0x820e7000, 0x021e00, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */
126
{ 0x820cf000, 0x022000, 0x0001000 }, /* WF_LMAC_TOP (WF_PF) */
127
{ 0x820e9000, 0x023400, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */
128
{ 0x820ea000, 0x024000, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */
129
{ 0x820eb000, 0x024200, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */
130
{ 0x820ec000, 0x024600, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_INT) */
131
{ 0x820ed000, 0x024800, 0x0000800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */
132
{ 0x820ca000, 0x026000, 0x0002000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */
133
{ 0x820d0000, 0x030000, 0x0010000 }, /* WF_LMAC_TOP (WF_WTBLON) */
134
{ 0x40000000, 0x070000, 0x0010000 }, /* WF_UMAC_SYSRAM */
135
{ 0x00400000, 0x080000, 0x0010000 }, /* WF_MCU_SYSRAM */
136
{ 0x00410000, 0x090000, 0x0010000 }, /* WF_MCU_SYSRAM (configure register) */
137
{ 0x820f0000, 0x0a0000, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */
138
{ 0x820f1000, 0x0a0600, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */
139
{ 0x820f2000, 0x0a0800, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */
140
{ 0x820f3000, 0x0a0c00, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */
141
{ 0x820f4000, 0x0a1000, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */
142
{ 0x820f5000, 0x0a1400, 0x0000800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */
143
{ 0x820f7000, 0x0a1e00, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */
144
{ 0x820f9000, 0x0a3400, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */
145
{ 0x820fa000, 0x0a4000, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */
146
{ 0x820fb000, 0x0a4200, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */
147
{ 0x820fc000, 0x0a4600, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_INT) */
148
{ 0x820fd000, 0x0a4800, 0x0000800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */
149
{ 0x820c4000, 0x0a8000, 0x0004000 }, /* WF_LMAC_TOP BN1 (WF_MUCOP) */
150
{ 0x820b0000, 0x0ae000, 0x0001000 }, /* [APB2] WFSYS_ON */
151
{ 0x80020000, 0x0b0000, 0x0010000 }, /* WF_TOP_MISC_OFF */
152
{ 0x81020000, 0x0c0000, 0x0010000 }, /* WF_TOP_MISC_ON */
153
{ 0x7c020000, 0x0d0000, 0x0010000 }, /* CONN_INFRA, wfdma */
154
{ 0x7c060000, 0x0e0000, 0x0010000 }, /* CONN_INFRA, conn_host_csr_top */
155
{ 0x7c000000, 0x0f0000, 0x0010000 }, /* CONN_INFRA */
156
{ 0x70020000, 0x1f0000, 0x0010000 }, /* Reserved for CBTOP, can't switch */
157
{ 0x7c500000, 0x060000, 0x2000000 }, /* remap */
158
{ 0x0, 0x0, 0x0 } /* End */
159
};
160
int i;
161
162
if (addr < 0x200000)
163
return addr;
164
165
mt7925_reg_remap_restore(dev);
166
167
for (i = 0; i < ARRAY_SIZE(fixed_map); i++) {
168
u32 ofs;
169
170
if (addr < fixed_map[i].phys)
171
continue;
172
173
ofs = addr - fixed_map[i].phys;
174
if (ofs > fixed_map[i].size)
175
continue;
176
177
return fixed_map[i].maps + ofs;
178
}
179
180
if ((addr >= 0x18000000 && addr < 0x18c00000) ||
181
(addr >= 0x70000000 && addr < 0x78000000) ||
182
(addr >= 0x7c000000 && addr < 0x7c400000))
183
return mt7925_reg_map_l1(dev, addr);
184
185
return mt7925_reg_map_l2(dev, addr);
186
}
187
188
static u32 mt7925_rr(struct mt76_dev *mdev, u32 offset)
189
{
190
struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
191
u32 addr = __mt7925_reg_addr(dev, offset);
192
193
return dev->bus_ops->rr(mdev, addr);
194
}
195
196
static void mt7925_wr(struct mt76_dev *mdev, u32 offset, u32 val)
197
{
198
struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
199
u32 addr = __mt7925_reg_addr(dev, offset);
200
201
dev->bus_ops->wr(mdev, addr, val);
202
}
203
204
static u32 mt7925_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
205
{
206
struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
207
u32 addr = __mt7925_reg_addr(dev, offset);
208
209
return dev->bus_ops->rmw(mdev, addr, mask, val);
210
}
211
212
static int mt7925_dma_init(struct mt792x_dev *dev)
213
{
214
int ret;
215
216
mt76_dma_attach(&dev->mt76);
217
218
ret = mt792x_dma_disable(dev, true);
219
if (ret)
220
return ret;
221
222
/* init tx queue */
223
ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7925_TXQ_BAND0,
224
MT7925_TX_RING_SIZE,
225
MT_TX_RING_BASE, NULL, 0);
226
if (ret)
227
return ret;
228
229
mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4);
230
231
/* command to WM */
232
ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7925_TXQ_MCU_WM,
233
MT7925_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
234
if (ret)
235
return ret;
236
237
/* firmware download */
238
ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7925_TXQ_FWDL,
239
MT7925_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);
240
if (ret)
241
return ret;
242
243
/* rx event */
244
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
245
MT7925_RXQ_MCU_WM, MT7925_RX_MCU_RING_SIZE,
246
MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE);
247
if (ret)
248
return ret;
249
250
/* rx data */
251
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
252
MT7925_RXQ_BAND0, MT7925_RX_RING_SIZE,
253
MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE);
254
if (ret)
255
return ret;
256
257
ret = mt76_init_queues(dev, mt792x_poll_rx);
258
if (ret < 0)
259
return ret;
260
261
netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi,
262
mt792x_poll_tx);
263
napi_enable(&dev->mt76.tx_napi);
264
265
return mt792x_dma_enable(dev);
266
}
267
268
static int mt7925_pci_probe(struct pci_dev *pdev,
269
const struct pci_device_id *id)
270
{
271
static const struct mt76_driver_ops drv_ops = {
272
/* txwi_size = txd size + txp size */
273
.txwi_size = MT_TXD_SIZE + sizeof(struct mt76_connac_hw_txp),
274
.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ |
275
MT_DRV_AMSDU_OFFLOAD,
276
.survey_flags = SURVEY_INFO_TIME_TX |
277
SURVEY_INFO_TIME_RX |
278
SURVEY_INFO_TIME_BSS_RX,
279
.token_size = MT7925_TOKEN_SIZE,
280
.tx_prepare_skb = mt7925e_tx_prepare_skb,
281
.tx_complete_skb = mt76_connac_tx_complete_skb,
282
.rx_check = mt7925_rx_check,
283
.rx_skb = mt7925_queue_rx_skb,
284
.rx_poll_complete = mt792x_rx_poll_complete,
285
.sta_add = mt7925_mac_sta_add,
286
.sta_event = mt7925_mac_sta_event,
287
.sta_remove = mt7925_mac_sta_remove,
288
.update_survey = mt792x_update_channel,
289
};
290
static const struct mt792x_hif_ops mt7925_pcie_ops = {
291
.init_reset = mt7925e_init_reset,
292
.reset = mt7925e_mac_reset,
293
.mcu_init = mt7925e_mcu_init,
294
.drv_own = mt792xe_mcu_drv_pmctrl,
295
.fw_own = mt792xe_mcu_fw_pmctrl,
296
};
297
static const struct mt792x_irq_map irq_map = {
298
.host_irq_enable = MT_WFDMA0_HOST_INT_ENA,
299
.tx = {
300
.all_complete_mask = MT_INT_TX_DONE_ALL,
301
.mcu_complete_mask = MT_INT_TX_DONE_MCU,
302
},
303
.rx = {
304
.data_complete_mask = HOST_RX_DONE_INT_ENA2,
305
.wm_complete_mask = HOST_RX_DONE_INT_ENA0,
306
},
307
};
308
struct ieee80211_ops *ops;
309
struct mt76_bus_ops *bus_ops;
310
struct mt792x_dev *dev;
311
struct mt76_dev *mdev;
312
u8 features;
313
int ret;
314
u16 cmd;
315
316
ret = pcim_enable_device(pdev);
317
if (ret)
318
return ret;
319
320
ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
321
if (ret)
322
return ret;
323
324
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
325
if (!(cmd & PCI_COMMAND_MEMORY)) {
326
cmd |= PCI_COMMAND_MEMORY;
327
pci_write_config_word(pdev, PCI_COMMAND, cmd);
328
}
329
pci_set_master(pdev);
330
331
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
332
if (ret < 0)
333
return ret;
334
335
ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
336
if (ret)
337
goto err_free_pci_vec;
338
339
if (mt7925_disable_aspm)
340
mt76_pci_disable_aspm(pdev);
341
342
ops = mt792x_get_mac80211_ops(&pdev->dev, &mt7925_ops,
343
(void *)id->driver_data, &features);
344
if (!ops) {
345
ret = -ENOMEM;
346
goto err_free_pci_vec;
347
}
348
349
mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), ops, &drv_ops);
350
if (!mdev) {
351
ret = -ENOMEM;
352
goto err_free_pci_vec;
353
}
354
355
pci_set_drvdata(pdev, mdev);
356
357
dev = container_of(mdev, struct mt792x_dev, mt76);
358
dev->fw_features = features;
359
dev->hif_ops = &mt7925_pcie_ops;
360
dev->irq_map = &irq_map;
361
mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
362
tasklet_init(&mdev->irq_tasklet, mt792x_irq_tasklet, (unsigned long)dev);
363
364
dev->phy.dev = dev;
365
dev->phy.mt76 = &dev->mt76.phy;
366
dev->mt76.phy.priv = &dev->phy;
367
dev->bus_ops = dev->mt76.bus;
368
bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),
369
GFP_KERNEL);
370
if (!bus_ops) {
371
ret = -ENOMEM;
372
goto err_free_dev;
373
}
374
375
bus_ops->rr = mt7925_rr;
376
bus_ops->wr = mt7925_wr;
377
bus_ops->rmw = mt7925_rmw;
378
dev->mt76.bus = bus_ops;
379
380
if (!mt7925_disable_aspm && mt76_pci_aspm_supported(pdev))
381
dev->aspm_supported = true;
382
383
ret = __mt792x_mcu_fw_pmctrl(dev);
384
if (ret)
385
goto err_free_dev;
386
387
ret = __mt792xe_mcu_drv_pmctrl(dev);
388
if (ret)
389
goto err_free_dev;
390
391
mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
392
(mt76_rr(dev, MT_HW_REV) & 0xff);
393
394
dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
395
396
mt76_rmw_field(dev, MT_HW_EMI_CTL, MT_HW_EMI_CTL_SLPPROT_EN, 1);
397
398
ret = mt792x_wfsys_reset(dev);
399
if (ret)
400
goto err_free_dev;
401
402
mt76_wr(dev, irq_map.host_irq_enable, 0);
403
404
mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
405
406
ret = devm_request_irq(mdev->dev, pdev->irq, mt792x_irq_handler,
407
IRQF_SHARED, KBUILD_MODNAME, dev);
408
if (ret)
409
goto err_free_dev;
410
411
ret = mt7925_dma_init(dev);
412
if (ret)
413
goto err_free_irq;
414
415
ret = mt7925_register_device(dev);
416
if (ret)
417
goto err_free_irq;
418
419
return 0;
420
421
err_free_irq:
422
devm_free_irq(&pdev->dev, pdev->irq, dev);
423
err_free_dev:
424
mt76_free_device(&dev->mt76);
425
err_free_pci_vec:
426
pci_free_irq_vectors(pdev);
427
428
return ret;
429
}
430
431
static void mt7925_pci_remove(struct pci_dev *pdev)
432
{
433
struct mt76_dev *mdev = pci_get_drvdata(pdev);
434
struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
435
436
mt7925e_unregister_device(dev);
437
set_bit(MT76_REMOVED, &mdev->phy.state);
438
devm_free_irq(&pdev->dev, pdev->irq, dev);
439
mt76_free_device(&dev->mt76);
440
pci_free_irq_vectors(pdev);
441
}
442
443
#if !defined(__FreeBSD__) || defined(CONFIG_PM_SLEEP)
444
static int mt7925_pci_suspend(struct device *device)
445
{
446
struct pci_dev *pdev = to_pci_dev(device);
447
struct mt76_dev *mdev = pci_get_drvdata(pdev);
448
struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
449
struct mt76_connac_pm *pm = &dev->pm;
450
int i, err, ret;
451
452
pm->suspended = true;
453
dev->hif_resumed = false;
454
flush_work(&dev->reset_work);
455
cancel_delayed_work_sync(&pm->ps_work);
456
cancel_work_sync(&pm->wake_work);
457
458
mt7925_roc_abort_sync(dev);
459
460
err = mt792x_mcu_drv_pmctrl(dev);
461
if (err < 0)
462
goto restore_suspend;
463
464
wait_event_timeout(dev->wait,
465
!dev->regd_in_progress, 5 * HZ);
466
467
/* always enable deep sleep during suspend to reduce
468
* power consumption
469
*/
470
mt7925_mcu_set_deep_sleep(dev, true);
471
472
mt76_connac_mcu_set_hif_suspend(mdev, true, false);
473
ret = wait_event_timeout(dev->wait,
474
dev->hif_idle, 3 * HZ);
475
if (!ret) {
476
err = -ETIMEDOUT;
477
goto restore_suspend;
478
}
479
480
napi_disable(&mdev->tx_napi);
481
mt76_worker_disable(&mdev->tx_worker);
482
483
mt76_for_each_q_rx(mdev, i) {
484
napi_disable(&mdev->napi[i]);
485
}
486
487
/* wait until dma is idle */
488
mt76_poll(dev, MT_WFDMA0_GLO_CFG,
489
MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
490
MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000);
491
492
/* put dma disabled */
493
mt76_clear(dev, MT_WFDMA0_GLO_CFG,
494
MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
495
496
/* disable interrupt */
497
mt76_wr(dev, dev->irq_map->host_irq_enable, 0);
498
499
mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
500
501
synchronize_irq(pdev->irq);
502
tasklet_kill(&mdev->irq_tasklet);
503
504
err = mt792x_mcu_fw_pmctrl(dev);
505
if (err)
506
goto restore_napi;
507
508
return 0;
509
510
restore_napi:
511
mt76_for_each_q_rx(mdev, i) {
512
napi_enable(&mdev->napi[i]);
513
}
514
napi_enable(&mdev->tx_napi);
515
516
if (!pm->ds_enable)
517
mt7925_mcu_set_deep_sleep(dev, false);
518
519
mt76_connac_mcu_set_hif_suspend(mdev, false, false);
520
ret = wait_event_timeout(dev->wait,
521
dev->hif_resumed, 3 * HZ);
522
if (!ret)
523
err = -ETIMEDOUT;
524
restore_suspend:
525
pm->suspended = false;
526
527
if (err < 0)
528
mt792x_reset(&dev->mt76);
529
530
return err;
531
}
532
533
static int mt7925_pci_resume(struct device *device)
534
{
535
struct pci_dev *pdev = to_pci_dev(device);
536
struct mt76_dev *mdev = pci_get_drvdata(pdev);
537
struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
538
struct mt76_connac_pm *pm = &dev->pm;
539
int i, err, ret;
540
541
dev->hif_idle = false;
542
err = mt792x_mcu_drv_pmctrl(dev);
543
if (err < 0)
544
goto failed;
545
546
mt792x_wpdma_reinit_cond(dev);
547
548
/* enable interrupt */
549
mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
550
mt76_connac_irq_enable(&dev->mt76,
551
dev->irq_map->tx.all_complete_mask |
552
MT_INT_RX_DONE_ALL | MT_INT_MCU_CMD);
553
mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);
554
555
/* put dma enabled */
556
mt76_set(dev, MT_WFDMA0_GLO_CFG,
557
MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
558
559
mt76_worker_enable(&mdev->tx_worker);
560
561
mt76_for_each_q_rx(mdev, i) {
562
napi_enable(&mdev->napi[i]);
563
}
564
napi_enable(&mdev->tx_napi);
565
566
local_bh_disable();
567
mt76_for_each_q_rx(mdev, i) {
568
napi_schedule(&mdev->napi[i]);
569
}
570
napi_schedule(&mdev->tx_napi);
571
local_bh_enable();
572
573
mt76_connac_mcu_set_hif_suspend(mdev, false, false);
574
ret = wait_event_timeout(dev->wait,
575
dev->hif_resumed, 3 * HZ);
576
if (!ret) {
577
err = -ETIMEDOUT;
578
goto failed;
579
}
580
581
/* restore previous ds setting */
582
if (!pm->ds_enable)
583
mt7925_mcu_set_deep_sleep(dev, false);
584
585
mt7925_regd_update(dev);
586
failed:
587
pm->suspended = false;
588
589
if (err < 0)
590
mt792x_reset(&dev->mt76);
591
592
return err;
593
}
594
#endif
595
596
static void mt7925_pci_shutdown(struct pci_dev *pdev)
597
{
598
mt7925_pci_remove(pdev);
599
}
600
601
static DEFINE_SIMPLE_DEV_PM_OPS(mt7925_pm_ops, mt7925_pci_suspend, mt7925_pci_resume);
602
603
static struct pci_driver mt7925_pci_driver = {
604
.name = KBUILD_MODNAME,
605
.id_table = mt7925_pci_device_table,
606
.probe = mt7925_pci_probe,
607
.remove = mt7925_pci_remove,
608
.shutdown = mt7925_pci_shutdown,
609
.driver.pm = pm_sleep_ptr(&mt7925_pm_ops),
610
};
611
612
module_pci_driver(mt7925_pci_driver);
613
614
MODULE_DEVICE_TABLE(pci, mt7925_pci_device_table);
615
MODULE_FIRMWARE(MT7925_FIRMWARE_WM);
616
MODULE_FIRMWARE(MT7925_ROM_PATCH);
617
MODULE_AUTHOR("Deren Wu <[email protected]>");
618
MODULE_AUTHOR("Lorenzo Bianconi <[email protected]>");
619
MODULE_DESCRIPTION("MediaTek MT7925E (PCIe) wireless driver");
620
MODULE_LICENSE("Dual BSD/GPL");
621
#if defined(__FreeBSD__)
622
MODULE_VERSION(mt7925_pci, 1);
623
MODULE_DEPEND(mt7925_pci, linuxkpi, 1, 1, 1);
624
MODULE_DEPEND(mt7925_pci, linuxkpi_wlan, 1, 1, 1);
625
MODULE_DEPEND(mt7925_pci, mt76_core, 1, 1, 1);
626
#endif
627
628