Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7925/pci.c
48525 views
// SPDX-License-Identifier: ISC1/* Copyright (C) 2023 MediaTek Inc. */23#include <linux/kernel.h>4#include <linux/module.h>5#include <linux/pci.h>67#include "mt7925.h"8#include "mac.h"9#include "mcu.h"10#include "../dma.h"1112static const struct pci_device_id mt7925_pci_device_table[] = {13{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7925),14.driver_data = (kernel_ulong_t)MT7925_FIRMWARE_WM },15{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0717),16.driver_data = (kernel_ulong_t)MT7925_FIRMWARE_WM },17{ },18};1920static bool mt7925_disable_aspm;21module_param_named(disable_aspm, mt7925_disable_aspm, bool, 0644);22MODULE_PARM_DESC(disable_aspm, "disable PCI ASPM support");2324static int mt7925e_init_reset(struct mt792x_dev *dev)25{26return mt792x_wpdma_reset(dev, true);27}2829static void mt7925e_unregister_device(struct mt792x_dev *dev)30{31int i;32struct mt76_connac_pm *pm = &dev->pm;33struct ieee80211_hw *hw = mt76_hw(dev);3435if (dev->phy.chip_cap & MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN)36wiphy_rfkill_stop_polling(hw->wiphy);3738cancel_work_sync(&dev->init_work);39mt76_unregister_device(&dev->mt76);40mt76_for_each_q_rx(&dev->mt76, i)41napi_disable(&dev->mt76.napi[i]);42cancel_delayed_work_sync(&pm->ps_work);43cancel_work_sync(&pm->wake_work);44cancel_work_sync(&dev->reset_work);4546mt7925_tx_token_put(dev);47__mt792x_mcu_drv_pmctrl(dev);48mt792x_dma_cleanup(dev);49mt792x_wfsys_reset(dev);50skb_queue_purge(&dev->mt76.mcu.res_q);5152tasklet_disable(&dev->mt76.irq_tasklet);53}5455static void mt7925_reg_remap_restore(struct mt792x_dev *dev)56{57/* remap to ori status */58if (unlikely(dev->backup_l1)) {59dev->bus_ops->wr(&dev->mt76, MT_HIF_REMAP_L1, dev->backup_l1);60dev->backup_l1 = 0;61}6263if (dev->backup_l2) {64dev->bus_ops->wr(&dev->mt76, MT_HIF_REMAP_L2, dev->backup_l2);65dev->backup_l2 = 0;66}67}6869static u32 mt7925_reg_map_l1(struct mt792x_dev *dev, u32 addr)70{71u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr);72u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr);7374dev->backup_l1 = dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);7576dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L1,77MT_HIF_REMAP_L1_MASK,78FIELD_PREP(MT_HIF_REMAP_L1_MASK, base));7980/* use read to push write */81dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);8283return MT_HIF_REMAP_BASE_L1 + offset;84}8586static u32 mt7925_reg_map_l2(struct mt792x_dev *dev, u32 addr)87{88u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, MT_HIF_REMAP_BASE_L2);8990dev->backup_l2 = dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);9192dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L1,93MT_HIF_REMAP_L1_MASK,94FIELD_PREP(MT_HIF_REMAP_L1_MASK, base));9596dev->bus_ops->wr(&dev->mt76, MT_HIF_REMAP_L2, addr);97/* use read to push write */98dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);99100return MT_HIF_REMAP_BASE_L1;101}102103static u32 __mt7925_reg_addr(struct mt792x_dev *dev, u32 addr)104{105static const struct mt76_connac_reg_map fixed_map[] = {106{ 0x830c0000, 0x000000, 0x0001000 }, /* WF_MCU_BUS_CR_REMAP */107{ 0x54000000, 0x002000, 0x0001000 }, /* WFDMA PCIE0 MCU DMA0 */108{ 0x55000000, 0x003000, 0x0001000 }, /* WFDMA PCIE0 MCU DMA1 */109{ 0x56000000, 0x004000, 0x0001000 }, /* WFDMA reserved */110{ 0x57000000, 0x005000, 0x0001000 }, /* WFDMA MCU wrap CR */111{ 0x58000000, 0x006000, 0x0001000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */112{ 0x59000000, 0x007000, 0x0001000 }, /* WFDMA PCIE1 MCU DMA1 */113{ 0x820c0000, 0x008000, 0x0004000 }, /* WF_UMAC_TOP (PLE) */114{ 0x820c8000, 0x00c000, 0x0002000 }, /* WF_UMAC_TOP (PSE) */115{ 0x820cc000, 0x00e000, 0x0002000 }, /* WF_UMAC_TOP (PP) */116{ 0x74030000, 0x010000, 0x0001000 }, /* PCIe MAC */117{ 0x820e0000, 0x020000, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */118{ 0x820e1000, 0x020400, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */119{ 0x820e2000, 0x020800, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */120{ 0x820e3000, 0x020c00, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */121{ 0x820e4000, 0x021000, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */122{ 0x820e5000, 0x021400, 0x0000800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */123{ 0x820ce000, 0x021c00, 0x0000200 }, /* WF_LMAC_TOP (WF_SEC) */124{ 0x820e7000, 0x021e00, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */125{ 0x820cf000, 0x022000, 0x0001000 }, /* WF_LMAC_TOP (WF_PF) */126{ 0x820e9000, 0x023400, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */127{ 0x820ea000, 0x024000, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */128{ 0x820eb000, 0x024200, 0x0000400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */129{ 0x820ec000, 0x024600, 0x0000200 }, /* WF_LMAC_TOP BN0 (WF_INT) */130{ 0x820ed000, 0x024800, 0x0000800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */131{ 0x820ca000, 0x026000, 0x0002000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */132{ 0x820d0000, 0x030000, 0x0010000 }, /* WF_LMAC_TOP (WF_WTBLON) */133{ 0x40000000, 0x070000, 0x0010000 }, /* WF_UMAC_SYSRAM */134{ 0x00400000, 0x080000, 0x0010000 }, /* WF_MCU_SYSRAM */135{ 0x00410000, 0x090000, 0x0010000 }, /* WF_MCU_SYSRAM (configure register) */136{ 0x820f0000, 0x0a0000, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */137{ 0x820f1000, 0x0a0600, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */138{ 0x820f2000, 0x0a0800, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */139{ 0x820f3000, 0x0a0c00, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */140{ 0x820f4000, 0x0a1000, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */141{ 0x820f5000, 0x0a1400, 0x0000800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */142{ 0x820f7000, 0x0a1e00, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */143{ 0x820f9000, 0x0a3400, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */144{ 0x820fa000, 0x0a4000, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */145{ 0x820fb000, 0x0a4200, 0x0000400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */146{ 0x820fc000, 0x0a4600, 0x0000200 }, /* WF_LMAC_TOP BN1 (WF_INT) */147{ 0x820fd000, 0x0a4800, 0x0000800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */148{ 0x820c4000, 0x0a8000, 0x0004000 }, /* WF_LMAC_TOP BN1 (WF_MUCOP) */149{ 0x820b0000, 0x0ae000, 0x0001000 }, /* [APB2] WFSYS_ON */150{ 0x80020000, 0x0b0000, 0x0010000 }, /* WF_TOP_MISC_OFF */151{ 0x81020000, 0x0c0000, 0x0010000 }, /* WF_TOP_MISC_ON */152{ 0x7c020000, 0x0d0000, 0x0010000 }, /* CONN_INFRA, wfdma */153{ 0x7c060000, 0x0e0000, 0x0010000 }, /* CONN_INFRA, conn_host_csr_top */154{ 0x7c000000, 0x0f0000, 0x0010000 }, /* CONN_INFRA */155{ 0x70020000, 0x1f0000, 0x0010000 }, /* Reserved for CBTOP, can't switch */156{ 0x7c500000, 0x060000, 0x2000000 }, /* remap */157{ 0x0, 0x0, 0x0 } /* End */158};159int i;160161if (addr < 0x200000)162return addr;163164mt7925_reg_remap_restore(dev);165166for (i = 0; i < ARRAY_SIZE(fixed_map); i++) {167u32 ofs;168169if (addr < fixed_map[i].phys)170continue;171172ofs = addr - fixed_map[i].phys;173if (ofs > fixed_map[i].size)174continue;175176return fixed_map[i].maps + ofs;177}178179if ((addr >= 0x18000000 && addr < 0x18c00000) ||180(addr >= 0x70000000 && addr < 0x78000000) ||181(addr >= 0x7c000000 && addr < 0x7c400000))182return mt7925_reg_map_l1(dev, addr);183184return mt7925_reg_map_l2(dev, addr);185}186187static u32 mt7925_rr(struct mt76_dev *mdev, u32 offset)188{189struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);190u32 addr = __mt7925_reg_addr(dev, offset);191192return dev->bus_ops->rr(mdev, addr);193}194195static void mt7925_wr(struct mt76_dev *mdev, u32 offset, u32 val)196{197struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);198u32 addr = __mt7925_reg_addr(dev, offset);199200dev->bus_ops->wr(mdev, addr, val);201}202203static u32 mt7925_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)204{205struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);206u32 addr = __mt7925_reg_addr(dev, offset);207208return dev->bus_ops->rmw(mdev, addr, mask, val);209}210211static int mt7925_dma_init(struct mt792x_dev *dev)212{213int ret;214215mt76_dma_attach(&dev->mt76);216217ret = mt792x_dma_disable(dev, true);218if (ret)219return ret;220221/* init tx queue */222ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7925_TXQ_BAND0,223MT7925_TX_RING_SIZE,224MT_TX_RING_BASE, NULL, 0);225if (ret)226return ret;227228mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4);229230/* command to WM */231ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7925_TXQ_MCU_WM,232MT7925_TX_MCU_RING_SIZE, MT_TX_RING_BASE);233if (ret)234return ret;235236/* firmware download */237ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7925_TXQ_FWDL,238MT7925_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);239if (ret)240return ret;241242/* rx event */243ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],244MT7925_RXQ_MCU_WM, MT7925_RX_MCU_RING_SIZE,245MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE);246if (ret)247return ret;248249/* rx data */250ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],251MT7925_RXQ_BAND0, MT7925_RX_RING_SIZE,252MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE);253if (ret)254return ret;255256ret = mt76_init_queues(dev, mt792x_poll_rx);257if (ret < 0)258return ret;259260netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi,261mt792x_poll_tx);262napi_enable(&dev->mt76.tx_napi);263264return mt792x_dma_enable(dev);265}266267static int mt7925_pci_probe(struct pci_dev *pdev,268const struct pci_device_id *id)269{270static const struct mt76_driver_ops drv_ops = {271/* txwi_size = txd size + txp size */272.txwi_size = MT_TXD_SIZE + sizeof(struct mt76_connac_hw_txp),273.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ |274MT_DRV_AMSDU_OFFLOAD,275.survey_flags = SURVEY_INFO_TIME_TX |276SURVEY_INFO_TIME_RX |277SURVEY_INFO_TIME_BSS_RX,278.token_size = MT7925_TOKEN_SIZE,279.tx_prepare_skb = mt7925e_tx_prepare_skb,280.tx_complete_skb = mt76_connac_tx_complete_skb,281.rx_check = mt7925_rx_check,282.rx_skb = mt7925_queue_rx_skb,283.rx_poll_complete = mt792x_rx_poll_complete,284.sta_add = mt7925_mac_sta_add,285.sta_event = mt7925_mac_sta_event,286.sta_remove = mt7925_mac_sta_remove,287.update_survey = mt792x_update_channel,288};289static const struct mt792x_hif_ops mt7925_pcie_ops = {290.init_reset = mt7925e_init_reset,291.reset = mt7925e_mac_reset,292.mcu_init = mt7925e_mcu_init,293.drv_own = mt792xe_mcu_drv_pmctrl,294.fw_own = mt792xe_mcu_fw_pmctrl,295};296static const struct mt792x_irq_map irq_map = {297.host_irq_enable = MT_WFDMA0_HOST_INT_ENA,298.tx = {299.all_complete_mask = MT_INT_TX_DONE_ALL,300.mcu_complete_mask = MT_INT_TX_DONE_MCU,301},302.rx = {303.data_complete_mask = HOST_RX_DONE_INT_ENA2,304.wm_complete_mask = HOST_RX_DONE_INT_ENA0,305},306};307struct ieee80211_ops *ops;308struct mt76_bus_ops *bus_ops;309struct mt792x_dev *dev;310struct mt76_dev *mdev;311u8 features;312int ret;313u16 cmd;314315ret = pcim_enable_device(pdev);316if (ret)317return ret;318319ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));320if (ret)321return ret;322323pci_read_config_word(pdev, PCI_COMMAND, &cmd);324if (!(cmd & PCI_COMMAND_MEMORY)) {325cmd |= PCI_COMMAND_MEMORY;326pci_write_config_word(pdev, PCI_COMMAND, cmd);327}328pci_set_master(pdev);329330ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);331if (ret < 0)332return ret;333334ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));335if (ret)336goto err_free_pci_vec;337338if (mt7925_disable_aspm)339mt76_pci_disable_aspm(pdev);340341ops = mt792x_get_mac80211_ops(&pdev->dev, &mt7925_ops,342(void *)id->driver_data, &features);343if (!ops) {344ret = -ENOMEM;345goto err_free_pci_vec;346}347348mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), ops, &drv_ops);349if (!mdev) {350ret = -ENOMEM;351goto err_free_pci_vec;352}353354pci_set_drvdata(pdev, mdev);355356dev = container_of(mdev, struct mt792x_dev, mt76);357dev->fw_features = features;358dev->hif_ops = &mt7925_pcie_ops;359dev->irq_map = &irq_map;360mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);361tasklet_init(&mdev->irq_tasklet, mt792x_irq_tasklet, (unsigned long)dev);362363dev->phy.dev = dev;364dev->phy.mt76 = &dev->mt76.phy;365dev->mt76.phy.priv = &dev->phy;366dev->bus_ops = dev->mt76.bus;367bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),368GFP_KERNEL);369if (!bus_ops) {370ret = -ENOMEM;371goto err_free_dev;372}373374bus_ops->rr = mt7925_rr;375bus_ops->wr = mt7925_wr;376bus_ops->rmw = mt7925_rmw;377dev->mt76.bus = bus_ops;378379if (!mt7925_disable_aspm && mt76_pci_aspm_supported(pdev))380dev->aspm_supported = true;381382ret = __mt792x_mcu_fw_pmctrl(dev);383if (ret)384goto err_free_dev;385386ret = __mt792xe_mcu_drv_pmctrl(dev);387if (ret)388goto err_free_dev;389390mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |391(mt76_rr(dev, MT_HW_REV) & 0xff);392393dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);394395mt76_rmw_field(dev, MT_HW_EMI_CTL, MT_HW_EMI_CTL_SLPPROT_EN, 1);396397ret = mt792x_wfsys_reset(dev);398if (ret)399goto err_free_dev;400401mt76_wr(dev, irq_map.host_irq_enable, 0);402403mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);404405ret = devm_request_irq(mdev->dev, pdev->irq, mt792x_irq_handler,406IRQF_SHARED, KBUILD_MODNAME, dev);407if (ret)408goto err_free_dev;409410ret = mt7925_dma_init(dev);411if (ret)412goto err_free_irq;413414ret = mt7925_register_device(dev);415if (ret)416goto err_free_irq;417418return 0;419420err_free_irq:421devm_free_irq(&pdev->dev, pdev->irq, dev);422err_free_dev:423mt76_free_device(&dev->mt76);424err_free_pci_vec:425pci_free_irq_vectors(pdev);426427return ret;428}429430static void mt7925_pci_remove(struct pci_dev *pdev)431{432struct mt76_dev *mdev = pci_get_drvdata(pdev);433struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);434435mt7925e_unregister_device(dev);436set_bit(MT76_REMOVED, &mdev->phy.state);437devm_free_irq(&pdev->dev, pdev->irq, dev);438mt76_free_device(&dev->mt76);439pci_free_irq_vectors(pdev);440}441442#if !defined(__FreeBSD__) || defined(CONFIG_PM_SLEEP)443static int mt7925_pci_suspend(struct device *device)444{445struct pci_dev *pdev = to_pci_dev(device);446struct mt76_dev *mdev = pci_get_drvdata(pdev);447struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);448struct mt76_connac_pm *pm = &dev->pm;449int i, err, ret;450451pm->suspended = true;452dev->hif_resumed = false;453flush_work(&dev->reset_work);454cancel_delayed_work_sync(&pm->ps_work);455cancel_work_sync(&pm->wake_work);456457mt7925_roc_abort_sync(dev);458459err = mt792x_mcu_drv_pmctrl(dev);460if (err < 0)461goto restore_suspend;462463wait_event_timeout(dev->wait,464!dev->regd_in_progress, 5 * HZ);465466/* always enable deep sleep during suspend to reduce467* power consumption468*/469mt7925_mcu_set_deep_sleep(dev, true);470471mt76_connac_mcu_set_hif_suspend(mdev, true, false);472ret = wait_event_timeout(dev->wait,473dev->hif_idle, 3 * HZ);474if (!ret) {475err = -ETIMEDOUT;476goto restore_suspend;477}478479napi_disable(&mdev->tx_napi);480mt76_worker_disable(&mdev->tx_worker);481482mt76_for_each_q_rx(mdev, i) {483napi_disable(&mdev->napi[i]);484}485486/* wait until dma is idle */487mt76_poll(dev, MT_WFDMA0_GLO_CFG,488MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |489MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000);490491/* put dma disabled */492mt76_clear(dev, MT_WFDMA0_GLO_CFG,493MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);494495/* disable interrupt */496mt76_wr(dev, dev->irq_map->host_irq_enable, 0);497498mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);499500synchronize_irq(pdev->irq);501tasklet_kill(&mdev->irq_tasklet);502503err = mt792x_mcu_fw_pmctrl(dev);504if (err)505goto restore_napi;506507return 0;508509restore_napi:510mt76_for_each_q_rx(mdev, i) {511napi_enable(&mdev->napi[i]);512}513napi_enable(&mdev->tx_napi);514515if (!pm->ds_enable)516mt7925_mcu_set_deep_sleep(dev, false);517518mt76_connac_mcu_set_hif_suspend(mdev, false, false);519ret = wait_event_timeout(dev->wait,520dev->hif_resumed, 3 * HZ);521if (!ret)522err = -ETIMEDOUT;523restore_suspend:524pm->suspended = false;525526if (err < 0)527mt792x_reset(&dev->mt76);528529return err;530}531532static int mt7925_pci_resume(struct device *device)533{534struct pci_dev *pdev = to_pci_dev(device);535struct mt76_dev *mdev = pci_get_drvdata(pdev);536struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);537struct mt76_connac_pm *pm = &dev->pm;538int i, err, ret;539540dev->hif_idle = false;541err = mt792x_mcu_drv_pmctrl(dev);542if (err < 0)543goto failed;544545mt792x_wpdma_reinit_cond(dev);546547/* enable interrupt */548mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);549mt76_connac_irq_enable(&dev->mt76,550dev->irq_map->tx.all_complete_mask |551MT_INT_RX_DONE_ALL | MT_INT_MCU_CMD);552mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);553554/* put dma enabled */555mt76_set(dev, MT_WFDMA0_GLO_CFG,556MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);557558mt76_worker_enable(&mdev->tx_worker);559560mt76_for_each_q_rx(mdev, i) {561napi_enable(&mdev->napi[i]);562}563napi_enable(&mdev->tx_napi);564565local_bh_disable();566mt76_for_each_q_rx(mdev, i) {567napi_schedule(&mdev->napi[i]);568}569napi_schedule(&mdev->tx_napi);570local_bh_enable();571572mt76_connac_mcu_set_hif_suspend(mdev, false, false);573ret = wait_event_timeout(dev->wait,574dev->hif_resumed, 3 * HZ);575if (!ret) {576err = -ETIMEDOUT;577goto failed;578}579580/* restore previous ds setting */581if (!pm->ds_enable)582mt7925_mcu_set_deep_sleep(dev, false);583584mt7925_regd_update(dev);585failed:586pm->suspended = false;587588if (err < 0)589mt792x_reset(&dev->mt76);590591return err;592}593#endif594595static void mt7925_pci_shutdown(struct pci_dev *pdev)596{597mt7925_pci_remove(pdev);598}599600static DEFINE_SIMPLE_DEV_PM_OPS(mt7925_pm_ops, mt7925_pci_suspend, mt7925_pci_resume);601602static struct pci_driver mt7925_pci_driver = {603.name = KBUILD_MODNAME,604.id_table = mt7925_pci_device_table,605.probe = mt7925_pci_probe,606.remove = mt7925_pci_remove,607.shutdown = mt7925_pci_shutdown,608.driver.pm = pm_sleep_ptr(&mt7925_pm_ops),609};610611module_pci_driver(mt7925_pci_driver);612613MODULE_DEVICE_TABLE(pci, mt7925_pci_device_table);614MODULE_FIRMWARE(MT7925_FIRMWARE_WM);615MODULE_FIRMWARE(MT7925_ROM_PATCH);616MODULE_AUTHOR("Deren Wu <[email protected]>");617MODULE_AUTHOR("Lorenzo Bianconi <[email protected]>");618MODULE_DESCRIPTION("MediaTek MT7925E (PCIe) wireless driver");619MODULE_LICENSE("Dual BSD/GPL");620#if defined(__FreeBSD__)621MODULE_VERSION(mt7925_pci, 1);622MODULE_DEPEND(mt7925_pci, linuxkpi, 1, 1, 1);623MODULE_DEPEND(mt7925_pci, linuxkpi_wlan, 1, 1, 1);624MODULE_DEPEND(mt7925_pci, mt76_core, 1, 1, 1);625#endif626627628